mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-28 08:39:56 +00:00
Merge branch 'master' of https://git.openjdk.java.net/jdk into JDK-6328248
This commit is contained in:
commit
4d33aff715
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@ NashornProfile.txt
|
||||
**/JTreport/**
|
||||
**/JTwork/**
|
||||
/src/utils/LogCompilation/target/
|
||||
/src/utils/LogCompilation/logc.jar
|
||||
/.project/
|
||||
/.settings/
|
||||
/compile_commands.json
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 2026, 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
|
||||
@ -68,17 +68,19 @@ java.compiler.interim_EXTRA_FILES := \
|
||||
TARGETS += $(BUILDTOOLS_OUTPUTDIR)/gensrc/java.compiler.interim/javax/tools/ToolProvider.java
|
||||
|
||||
################################################################################
|
||||
# Use the up-to-date PreviewFeature.java and NoPreview.java from the current
|
||||
# sources, instead of the versions from the boot JDK, as javac may be referring
|
||||
# to constants from the up-to-date versions.
|
||||
# Create a hybrid PreviewFeature.java that combines constants
|
||||
# from the current sources, as those can be used in javac APIs, and from the
|
||||
# bootstrap JDK, as those can be used from bootstrap JDK classfiles.
|
||||
|
||||
$(eval $(call SetupCopyFiles, COPY_PREVIEW_FEATURES, \
|
||||
FILES := $(TOPDIR)/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java \
|
||||
$(TOPDIR)/src/java.base/share/classes/jdk/internal/javac/NoPreview.java, \
|
||||
DEST := $(BUILDTOOLS_OUTPUTDIR)/gensrc/java.base.interim/jdk/internal/javac/, \
|
||||
))
|
||||
$(BUILDTOOLS_OUTPUTDIR)/gensrc/java.base.interim/jdk/internal/javac/PreviewFeature.java: \
|
||||
$(TOPDIR)/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java
|
||||
$(call LogInfo, Generating $@)
|
||||
$(JAVA) $(TOPDIR)/make/langtools/tools/previewfeature/SetupPreviewFeature.java \
|
||||
$(TOPDIR)/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java \
|
||||
$@
|
||||
|
||||
TARGETS += $(COPY_PREVIEW_FEATURES)
|
||||
|
||||
TARGETS += $(BUILDTOOLS_OUTPUTDIR)/gensrc/java.base.interim/jdk/internal/javac/PreviewFeature.java
|
||||
|
||||
################################################################################
|
||||
# Setup the rules to build interim langtools, which is compiled by the boot
|
||||
@ -123,7 +125,8 @@ define SetupInterimModule
|
||||
$1_DEPS_INTERIM := $$(addsuffix .interim, $$(filter \
|
||||
$$(INTERIM_LANGTOOLS_BASE_MODULES), $$(call FindTransitiveDepsForModule, $1)))
|
||||
|
||||
$$(BUILD_$1.interim): $$(foreach d, $$($1_DEPS_INTERIM), $$(BUILD_$$d)) $(COPY_PREVIEW_FEATURES)
|
||||
$$(BUILD_$1.interim): $$(foreach d, $$($1_DEPS_INTERIM), $$(BUILD_$$d)) \
|
||||
$(BUILDTOOLS_OUTPUTDIR)/gensrc/java.base.interim/jdk/internal/javac/PreviewFeature.java
|
||||
|
||||
TARGETS += $$(BUILD_$1.interim)
|
||||
endef
|
||||
|
||||
@ -70,12 +70,15 @@ CLASSLIST_FILE_VM_OPTS = \
|
||||
|
||||
# Save the stderr output of the command and print it along with stdout in case
|
||||
# something goes wrong.
|
||||
# The classlists must be generated with -Xint to avoid non-determinism
|
||||
# introduced by JIT compiled code
|
||||
$(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXECUTABLE_SUFFIX) $(CLASSLIST_JAR)
|
||||
$(call MakeDir, $(LINK_OPT_DIR))
|
||||
$(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $@))
|
||||
$(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $(JLI_TRACE_FILE)))
|
||||
$(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@.raw \
|
||||
$(CLASSLIST_FILE_VM_OPTS) \
|
||||
-Xint \
|
||||
-Xlog:aot=off \
|
||||
-Xlog:cds=off \
|
||||
-cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
|
||||
@ -90,6 +93,7 @@ $(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXECUTABLE_SUFFIX) $(CLASSLIST
|
||||
-XX:SharedClassListFile=$@.interim -XX:SharedArchiveFile=$@.jsa \
|
||||
-Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
|
||||
$(CLASSLIST_FILE_VM_OPTS) \
|
||||
-Xint \
|
||||
--module-path $(SUPPORT_OUTPUTDIR)/classlist.jar \
|
||||
-Xlog:aot=off \
|
||||
-Xlog:cds=off \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2012, 2026, 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
|
||||
@ -66,7 +66,8 @@ CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS))
|
||||
ifeq ($(CALLED_SPEC_TARGETS), )
|
||||
SKIP_SPEC := true
|
||||
endif
|
||||
ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq)
|
||||
MFLAGS_SINGLE := $(filter-out --%, $(MFLAGS))
|
||||
ifeq ($(findstring p, $(MFLAGS_SINGLE))$(findstring q, $(MFLAGS_SINGLE)), pq)
|
||||
SKIP_SPEC := true
|
||||
endif
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2026, 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
|
||||
@ -369,6 +369,10 @@ AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS],
|
||||
IS_GNU_DATE=yes
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
# Likely at the AIX provided version of the date utility here, which is not compatible
|
||||
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
|
||||
AC_MSG_ERROR([gnu date from AIX toolbox is required])
|
||||
fi
|
||||
IS_GNU_DATE=no
|
||||
fi
|
||||
AC_SUBST(IS_GNU_DATE)
|
||||
|
||||
@ -214,6 +214,7 @@ AC_DEFUN([FLAGS_SETUP_WARNINGS],
|
||||
WARNINGS_ENABLE_ADDITIONAL_CXX=""
|
||||
WARNINGS_ENABLE_ADDITIONAL_JVM=""
|
||||
DISABLED_WARNINGS="4800 5105"
|
||||
CFLAGS_CONVERSION_WARNINGS=
|
||||
;;
|
||||
|
||||
gcc)
|
||||
@ -239,6 +240,7 @@ AC_DEFUN([FLAGS_SETUP_WARNINGS],
|
||||
if test "x$OPENJDK_TARGET_CPU_ARCH" = "xppc"; then
|
||||
DISABLED_WARNINGS="$DISABLED_WARNINGS psabi"
|
||||
fi
|
||||
CFLAGS_CONVERSION_WARNINGS="-Wconversion -Wno-float-conversion"
|
||||
;;
|
||||
|
||||
clang)
|
||||
@ -258,6 +260,7 @@ AC_DEFUN([FLAGS_SETUP_WARNINGS],
|
||||
# These warnings will never be turned on, since they generate too many
|
||||
# false positives.
|
||||
DISABLED_WARNINGS="unknown-warning-option unused-parameter"
|
||||
CFLAGS_CONVERSION_WARNINGS="-Wimplicit-int-conversion"
|
||||
;;
|
||||
esac
|
||||
WARNINGS_ENABLE_ALL="$WARNINGS_ENABLE_ALL_NORMAL $WARNINGS_ENABLE_ADDITIONAL"
|
||||
@ -270,6 +273,7 @@ AC_DEFUN([FLAGS_SETUP_WARNINGS],
|
||||
AC_SUBST(DISABLED_WARNINGS)
|
||||
AC_SUBST(DISABLED_WARNINGS_C)
|
||||
AC_SUBST(DISABLED_WARNINGS_CXX)
|
||||
AC_SUBST(CFLAGS_CONVERSION_WARNINGS)
|
||||
])
|
||||
|
||||
AC_DEFUN([FLAGS_SETUP_QUALITY_CHECKS],
|
||||
@ -574,6 +578,11 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
||||
TOOLCHAIN_CFLAGS_JDK_CONLY="-fno-strict-aliasing" # technically NOT for CXX
|
||||
fi
|
||||
|
||||
if test "x$ENABLE_LINKTIME_GC" = xtrue; then
|
||||
TOOLCHAIN_CFLAGS_JDK="$TOOLCHAIN_CFLAGS_JDK -ffunction-sections -fdata-sections"
|
||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -ffunction-sections -fdata-sections"
|
||||
fi
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -ffunction-sections -ftls-model -fno-math-errno"
|
||||
TOOLCHAIN_CFLAGS_JDK="-ffunction-sections -fsigned-char"
|
||||
|
||||
@ -80,6 +80,10 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
||||
if test "x$CXX_IS_USER_SUPPLIED" = xfalse && test "x$CC_IS_USER_SUPPLIED" = xfalse; then
|
||||
UTIL_REQUIRE_TOOLCHAIN_PROGS(LLD, lld)
|
||||
fi
|
||||
|
||||
if test "x$ENABLE_LINKTIME_GC" = xtrue; then
|
||||
BASIC_LDFLAGS_JDK_ONLY="$BASIC_LDFLAGS_JDK_ONLY -Wl,--gc-sections"
|
||||
fi
|
||||
fi
|
||||
if test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
BASIC_LDFLAGS="-Wl,-b64 -Wl,-brtl -Wl,-bnorwexec -Wl,-blibpath:/usr/lib:lib -Wl,-bnoexpall \
|
||||
|
||||
@ -102,9 +102,20 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS],
|
||||
CHECKING_MSG: [if we should build headless-only (no GUI)])
|
||||
AC_SUBST(ENABLE_HEADLESS_ONLY)
|
||||
|
||||
# Avoid headless-only on macOS and Windows, it is not supported there
|
||||
if test "x$ENABLE_HEADLESS_ONLY" = xtrue; then
|
||||
if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
AC_MSG_ERROR([headless-only is not supported on macOS and Windows])
|
||||
fi
|
||||
fi
|
||||
|
||||
# should we linktime gc unused code sections in the JDK build ?
|
||||
if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = xs390x; then
|
||||
LINKTIME_GC_DEFAULT=true
|
||||
if test "x$OPENJDK_TARGET_OS" = "xlinux"; then
|
||||
if test "x$OPENJDK_TARGET_CPU" = "xs390x" || test "x$OPENJDK_TARGET_CPU" = "xppc64le"; then
|
||||
LINKTIME_GC_DEFAULT=true
|
||||
else
|
||||
LINKTIME_GC_DEFAULT=false
|
||||
fi
|
||||
else
|
||||
LINKTIME_GC_DEFAULT=false
|
||||
fi
|
||||
|
||||
@ -267,8 +267,8 @@ AC_DEFUN_ONCE([LIB_SETUP_ZLIB],
|
||||
LIBZ_LIBS=""
|
||||
if test "x$USE_EXTERNAL_LIBZ" = "xfalse"; then
|
||||
LIBZ_CFLAGS="$LIBZ_CFLAGS -I$TOPDIR/src/java.base/share/native/libzip/zlib"
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
LIBZ_CFLAGS="$LIBZ_CFLAGS -DHAVE_UNISTD_H"
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx -o "x$OPENJDK_TARGET_OS" = xaix -o "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
LIBZ_CFLAGS="$LIBZ_CFLAGS -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1"
|
||||
fi
|
||||
else
|
||||
LIBZ_LIBS="-lz"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2026, 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
|
||||
@ -311,6 +311,12 @@ AC_DEFUN([PLATFORM_EXTRACT_TARGET_AND_BUILD],
|
||||
else
|
||||
OPENJDK_BUILD_OS_ENV="$VAR_OS"
|
||||
fi
|
||||
# Special handling for MSYS2 that reports a Cygwin triplet as the default host triplet.
|
||||
case `uname` in
|
||||
MSYS*)
|
||||
OPENJDK_BUILD_OS_ENV=windows.msys2
|
||||
;;
|
||||
esac
|
||||
OPENJDK_BUILD_CPU="$VAR_CPU"
|
||||
OPENJDK_BUILD_CPU_ARCH="$VAR_CPU_ARCH"
|
||||
OPENJDK_BUILD_CPU_BITS="$VAR_CPU_BITS"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2026, 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
|
||||
@ -529,6 +529,7 @@ CFLAGS_WARNINGS_ARE_ERRORS := @CFLAGS_WARNINGS_ARE_ERRORS@
|
||||
DISABLED_WARNINGS := @DISABLED_WARNINGS@
|
||||
DISABLED_WARNINGS_C := @DISABLED_WARNINGS_C@
|
||||
DISABLED_WARNINGS_CXX := @DISABLED_WARNINGS_CXX@
|
||||
CFLAGS_CONVERSION_WARNINGS := @CFLAGS_CONVERSION_WARNINGS@
|
||||
|
||||
# A global flag (true or false) determining if native warnings are considered errors.
|
||||
WARNINGS_AS_ERRORS := @WARNINGS_AS_ERRORS@
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2026, 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
|
||||
@ -141,6 +141,66 @@ endef
|
||||
# Make sure logging is setup for everyone that includes MakeBase.gmk.
|
||||
$(eval $(call SetupLogging))
|
||||
|
||||
################################################################################
|
||||
# Make does not have support for VARARGS, you can send variable amount
|
||||
# of arguments, but you can for example not append a list at the end.
|
||||
# It is therefore not easy to send the elements of a list of unknown
|
||||
# length as argument to a function. This can somewhat be worked around
|
||||
# by sending a list as an argument, and then interpreting each element
|
||||
# of the list as an argument to the function. However, Make is
|
||||
# limited, and using this method you can not easily send spaces.
|
||||
#
|
||||
# We need to quote strings for two reasons when sending them as
|
||||
# "variable append packs":
|
||||
#
|
||||
# 1) variable appends can include spaces, and those must be preserved
|
||||
# 2) variable appends can include assignment strings ":=", and those
|
||||
# must be quoted to a form so that we can recognise the "append pack".
|
||||
# We recognise an "append pack" by its lack of strict assignment ":="
|
||||
|
||||
Q := $(HASH)
|
||||
SpaceQ := $(Q)s
|
||||
AppendQ := $(Q)+
|
||||
AssignQ := $(Q)a
|
||||
QQ := $(Q)$(Q)
|
||||
|
||||
# $(call Quote,echo "#trala:=") -> echo#s"##trala#a"
|
||||
Quote = $(subst :=,$(AssignQ),$(subst $(SPACE),$(SpaceQ),$(subst $(Q),$(QQ),$1)))
|
||||
|
||||
# $(call Unquote,echo#s"##trala#a") -> echo "#trala:="
|
||||
Unquote = $(subst $(QQ),$(Q),$(subst $(SpaceQ),$(SPACE),$(subst $(AssignQ),:=,$1)))
|
||||
|
||||
# $(call QuoteAppend,name,some value) -> name#+some#svalue
|
||||
# $(call QuoteAppend,bad+=name,some value) -> error
|
||||
QuoteAppend = $(if $(findstring +=,$1),$(error you can not have += in a variable name: "$1"),$(call Quote,$1)$(AppendQ)$(call Quote,$2))
|
||||
|
||||
# $(call UnquoteAppendIndex,name#+some#svalue,1) -> name
|
||||
# $(call UnquoteAppendIndex,name#+some#svalue,2) -> some value
|
||||
UnquoteAppendIndex = $(call Unquote,$(word $2,$(subst $(AppendQ),$(SPACE),$1)))
|
||||
|
||||
# $(call FilterFiles,dir,%.cpp) -> file1.cpp file2.cpp (without path)
|
||||
FilterFiles = $(filter $2,$(notdir $(call FindFiles,$1)))
|
||||
|
||||
# $(call Unpack module_,file1.cpp_CXXFLAGS#+-Wconversion file2.cpp_CXXFLAGS#+-Wconversion) -> module_file1.cpp_CXXFLAGS += -Wconversion
|
||||
# module_file2.cpp_CXXFLAGS += -Wconversion
|
||||
Unpack = $(foreach pair,$2,$1$(call UnquoteAppendIndex,$(pair),1) += $(call UnquoteAppendIndex,$(pair),2)$(NEWLINE))
|
||||
|
||||
# This macro takes four arguments:
|
||||
# $1: directory where to find files (striped), example: $(TOPDIR)/src/hotspot/share/gc/g1
|
||||
# $2: filter to match what to keep (striped), example: g1Concurrent%.cpp
|
||||
# $3: what flags to override (striped), example: _CXXFLAGS
|
||||
# $4: what value to append to the flag (striped), example: $(CFLAGS_CONVERSION_WARNINGS)
|
||||
#
|
||||
# The result will be a quoted string that can be unpacked to a list of
|
||||
# variable appendings (see macro Unpack above). You do not need to take
|
||||
# care of unpacking, it is done in NamedParamsMacroTemplate.
|
||||
#
|
||||
# This feature should only be used for warnings that we want to
|
||||
# incrementally add to the rest of the code base.
|
||||
#
|
||||
# $(call ExtendFlags,dir,%.cpp,_CXXFLAGS,-Wconversion) -> file1.cpp_CXXFLAGS#+-Wconversion file2.cpp_CXXFLAGS#+-Wconversion
|
||||
ExtendFlags = $(foreach file,$(call FilterFiles,$(strip $1),$(strip $2)),$(call QuoteAppend,$(file)$(strip $3),$(strip $4)))
|
||||
|
||||
################################################################################
|
||||
|
||||
MAX_PARAMS := 96
|
||||
@ -166,7 +226,10 @@ define NamedParamsMacroTemplate
|
||||
Too many named arguments to macro, please update MAX_PARAMS in MakeBase.gmk))
|
||||
# Iterate over 2 3 4... and evaluate the named parameters with $1_ as prefix
|
||||
$(foreach i, $(PARAM_SEQUENCE), $(if $(strip $($i)), \
|
||||
$(strip $1)_$(strip $(call EscapeHash, $(call DoubleDollar, $($i))))$(NEWLINE)))
|
||||
$(if $(findstring :=,$($i)), \
|
||||
$(strip $1)_$(strip $(call EscapeHash, $(call DoubleDollar, $($i))))$(NEWLINE), \
|
||||
$(call Unpack,$(strip $1)_,$($i)))))
|
||||
|
||||
# Debug print all named parameter names and values
|
||||
$(if $(findstring $(LOG_LEVEL), trace), \
|
||||
$(info $0 $(strip $1) $(foreach i, $(PARAM_SEQUENCE), \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2026, 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
|
||||
@ -35,8 +35,14 @@ include ProcessMarkdown.gmk
|
||||
include $(TOPDIR)/make/ToolsJdk.gmk
|
||||
|
||||
LAUNCHER_SRC := $(TOPDIR)/src/java.base/share/native/launcher
|
||||
|
||||
ifeq ($(call isTargetOs, aix), true)
|
||||
ADD_PLATFORM_INCLUDE_DIR := -I$(TOPDIR)/src/java.base/aix/native/include
|
||||
endif
|
||||
|
||||
LAUNCHER_CFLAGS += -I$(TOPDIR)/src/java.base/share/native/launcher \
|
||||
-I$(TOPDIR)/src/java.base/share/native/libjli \
|
||||
$(ADD_PLATFORM_INCLUDE_DIR) \
|
||||
-I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli \
|
||||
-I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libjli \
|
||||
#
|
||||
|
||||
@ -63,6 +63,10 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBGTEST, \
|
||||
unused-result zero-as-null-pointer-constant, \
|
||||
DISABLED_WARNINGS_clang := format-nonliteral undef unused-result \
|
||||
zero-as-null-pointer-constant, \
|
||||
$(comment Disable deprecated-declarations warnings to workaround) \
|
||||
$(comment clang18+glibc12 bug https://github.com/llvm/llvm-project/issues/76515) \
|
||||
$(comment until the clang bug has been fixed) \
|
||||
DISABLED_WARNINGS_clang_gtest-all.cc := deprecated-declarations, \
|
||||
DISABLED_WARNINGS_microsoft := 4530, \
|
||||
DEFAULT_CFLAGS := false, \
|
||||
CFLAGS := $(JVM_CFLAGS) \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 2026, 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
|
||||
@ -105,7 +105,7 @@ DISABLED_WARNINGS_gcc := array-bounds comment delete-non-virtual-dtor \
|
||||
DISABLED_WARNINGS_clang := delete-non-abstract-non-virtual-dtor \
|
||||
invalid-offsetof missing-braces \
|
||||
sometimes-uninitialized unknown-pragmas unused-but-set-variable \
|
||||
unused-function unused-local-typedef unused-private-field unused-variable
|
||||
unused-local-typedef unused-private-field unused-variable
|
||||
|
||||
ifneq ($(DEBUG_LEVEL), release)
|
||||
# Assert macro gives warning
|
||||
@ -190,6 +190,8 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJVM, \
|
||||
abstract_vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
||||
arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
||||
whitebox.cpp_CXXFLAGS := $(CFLAGS_SHIP_DEBUGINFO), \
|
||||
$(call ExtendFlags, $(TOPDIR)/src/hotspot/share/gc/g1, \
|
||||
g1Numa.cpp, _CXXFLAGS, $(CFLAGS_CONVERSION_WARNINGS)), \
|
||||
DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc), \
|
||||
DISABLED_WARNINGS_gcc_ad_$(HOTSPOT_TARGET_CPU_ARCH).cpp := nonnull, \
|
||||
DISABLED_WARNINGS_gcc_bytecodeInterpreter.cpp := unused-label, \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 2026, 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,10 +43,15 @@ JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \
|
||||
$(JVM_VARIANT_OUTPUTDIR)/gensrc
|
||||
#
|
||||
|
||||
ifeq ($(call isTargetOs, aix), true)
|
||||
ADD_PLATFORM_INCLUDE_DIR := -I$(TOPDIR)/src/java.base/aix/native/include
|
||||
endif
|
||||
|
||||
JVM_CFLAGS_INCLUDES += \
|
||||
$(patsubst %,-I%,$(JVM_SRC_DIRS)) \
|
||||
-I$(TOPDIR)/src/hotspot/share/include \
|
||||
-I$(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \
|
||||
$(ADD_PLATFORM_INCLUDE_DIR) \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I$(TOPDIR)/src/java.base/share/native/libjimage \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, 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
|
||||
@ -34,36 +34,6 @@ import java.util.*;
|
||||
|
||||
public class FieldGen {
|
||||
|
||||
static FieldParams Curve25519 = new FieldParams(
|
||||
"IntegerPolynomial25519", 26, 10, 1, 255,
|
||||
Arrays.asList(
|
||||
new Term(0, -19)
|
||||
),
|
||||
Curve25519CrSequence(), simpleSmallCrSequence(10)
|
||||
);
|
||||
|
||||
private static List<CarryReduce> Curve25519CrSequence() {
|
||||
List<CarryReduce> result = new ArrayList<CarryReduce>();
|
||||
|
||||
// reduce(7,2)
|
||||
result.add(new Reduce(17));
|
||||
result.add(new Reduce(18));
|
||||
|
||||
// carry(8,2)
|
||||
result.add(new Carry(8));
|
||||
result.add(new Carry(9));
|
||||
|
||||
// reduce(0,7)
|
||||
for (int i = 10; i < 17; i++) {
|
||||
result.add(new Reduce(i));
|
||||
}
|
||||
|
||||
// carry(0,9)
|
||||
result.addAll(fullCarry(10));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static FieldParams Curve448 = new FieldParams(
|
||||
"IntegerPolynomial448", 28, 16, 1, 448,
|
||||
Arrays.asList(
|
||||
@ -224,8 +194,7 @@ public class FieldGen {
|
||||
}
|
||||
|
||||
static final FieldParams[] ALL_FIELDS = {
|
||||
Curve25519, Curve448,
|
||||
P256, P384, P521, O256, O384, O521, O25519, O448
|
||||
Curve448, P256, P384, P521, O256, O384, O521, O25519, O448
|
||||
};
|
||||
|
||||
public static class Term {
|
||||
|
||||
93
make/langtools/tools/previewfeature/SetupPreviewFeature.java
Normal file
93
make/langtools/tools/previewfeature/SetupPreviewFeature.java
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 previewfeature;
|
||||
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.Trees;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
/* Construct a hybrid PreviewFeature.Feature enum that includes constants both
|
||||
* from the current JDK sources (so that they can be used in the javac API sources),
|
||||
* and from the bootstrap JDK (so that they can be used in the bootstrap classfiles).
|
||||
*
|
||||
* This hybrid enum is only used for the interim javac.
|
||||
*/
|
||||
public class SetupPreviewFeature {
|
||||
public static void main(String... args) throws Exception {
|
||||
Class<?> runtimeFeature = Class.forName("jdk.internal.javac.PreviewFeature$Feature");
|
||||
Set<String> constantsToAdd = new HashSet<>();
|
||||
for (Field runtimeField : runtimeFeature.getDeclaredFields()) {
|
||||
if (runtimeField.isEnumConstant()) {
|
||||
constantsToAdd.add(runtimeField.getName());
|
||||
}
|
||||
}
|
||||
var dummy = new StringWriter();
|
||||
var compiler = ToolProvider.getSystemJavaCompiler();
|
||||
var source = Path.of(args[0]);
|
||||
try (var fm = compiler.getStandardFileManager(null, null, null)) {
|
||||
JavacTask task =
|
||||
(JavacTask) compiler.getTask(dummy, null, null, null, null, fm.getJavaFileObjects(source));
|
||||
task.analyze();
|
||||
var sourceFeature = task.getElements()
|
||||
.getTypeElement("jdk.internal.javac.PreviewFeature.Feature");
|
||||
int insertPosition = -1;
|
||||
for (var el : sourceFeature.getEnclosedElements()) {
|
||||
if (el.getKind() == ElementKind.ENUM_CONSTANT) {
|
||||
constantsToAdd.remove(el.getSimpleName().toString());
|
||||
if (insertPosition == (-1)) {
|
||||
var trees = Trees.instance(task);
|
||||
var elPath = trees.getPath(el);
|
||||
insertPosition = (int) trees.getSourcePositions()
|
||||
.getStartPosition(elPath.getCompilationUnit(),
|
||||
elPath.getLeaf());
|
||||
}
|
||||
}
|
||||
}
|
||||
var target = Path.of(args[1]);
|
||||
Files.createDirectories(target.getParent());
|
||||
if (constantsToAdd.isEmpty()) {
|
||||
Files.copy(source, target);
|
||||
} else {
|
||||
String sourceCode = Files.readString(source);
|
||||
try (var out = Files.newBufferedWriter(target)) {
|
||||
out.write(sourceCode, 0, insertPosition);
|
||||
out.write(constantsToAdd.stream()
|
||||
.collect(Collectors.joining(", ",
|
||||
"/*compatibility constants:*/ ",
|
||||
",\n")));
|
||||
out.write(sourceCode, insertPosition, sourceCode.length() - insertPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 2026, 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
|
||||
@ -172,6 +172,10 @@ ifeq ($(USE_EXTERNAL_LIBZ), true)
|
||||
LEGAL_EXCLUDES += zlib.md
|
||||
endif
|
||||
|
||||
ifneq ($(TOOLCHAIN_TYPE), gcc)
|
||||
LEGAL_EXCLUDES += gcc.md
|
||||
endif
|
||||
|
||||
$(eval $(call SetupCopyLegalFiles, COPY_LEGAL, \
|
||||
EXCLUDES := $(LEGAL_EXCLUDES), \
|
||||
))
|
||||
|
||||
@ -95,7 +95,8 @@ ifeq ($(call isTargetOsType, unix), true)
|
||||
CFLAGS := $(VERSION_CFLAGS), \
|
||||
EXTRA_HEADER_DIRS := libjava, \
|
||||
EXTRA_OBJECT_FILES := \
|
||||
$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc$(OBJ_SUFFIX), \
|
||||
$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc$(OBJ_SUFFIX) \
|
||||
$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc_errorcodes$(OBJ_SUFFIX), \
|
||||
LD_SET_ORIGIN := false, \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \
|
||||
))
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2026, 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
|
||||
@ -99,14 +99,16 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
$(TOPDIR)/src/$(MODULE)/windows/native/libawt/windows/awt.rc
|
||||
endif
|
||||
|
||||
# This is the object file to provide the dladdr API, which is not
|
||||
# part of AIX. It occurs several times in the jdk code base.
|
||||
# Do not include it. When statically linking the java
|
||||
# launcher with all JDK and VM static libraries, we use the
|
||||
# --whole-archive linker option. The duplicate objects in different
|
||||
# static libraries cause linking errors due to duplicate symbols.
|
||||
ifeq ($(call isTargetOs, aix), true)
|
||||
# This is the object file to provide the dladdr API, which is not
|
||||
# part of AIX. It occurs several times in the jdk code base.
|
||||
# Do not include it. When statically linking the java
|
||||
# launcher with all JDK and VM static libraries, we use the
|
||||
# --whole-archive linker option. The duplicate objects in different
|
||||
# static libraries cause linking errors due to duplicate symbols.
|
||||
LIBAWT_STATIC_EXCLUDE_OBJS := porting_aix.o
|
||||
|
||||
LIBAWT_CFLAGS += -I$(TOPDIR)/src/java.base/aix/native/include
|
||||
endif
|
||||
|
||||
# -fgcse-after-reload improves performance of MaskFill in Java2D by 20% for
|
||||
@ -423,6 +425,9 @@ endif
|
||||
ifeq ($(call isTargetOs, linux)+$(ENABLE_HEADLESS_ONLY), true+true)
|
||||
LIBJAWT_CFLAGS += -DHEADLESS
|
||||
endif
|
||||
ifeq ($(call isTargetOs, aix)+$(ENABLE_HEADLESS_ONLY), true+true)
|
||||
LIBJAWT_CFLAGS += -DHEADLESS
|
||||
endif
|
||||
|
||||
ifeq ($(call isTargetOs, windows)+$(call isTargetCpu, x86), true+true)
|
||||
LIBJAWT_LIBS_windows := kernel32.lib
|
||||
|
||||
@ -338,11 +338,8 @@ else
|
||||
# noexcept-type required for GCC 7 builds. Not required for GCC 8+.
|
||||
# expansion-to-defined required for GCC 9 builds. Not required for GCC 10+.
|
||||
# maybe-uninitialized required for GCC 8 builds. Not required for GCC 9+.
|
||||
# calloc-transposed-args required for GCC 14 builds. (fixed upstream in
|
||||
# Harfbuzz 032c931e1c0cfb20f18e5acb8ba005775242bd92)
|
||||
HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := class-memaccess noexcept-type \
|
||||
expansion-to-defined dangling-reference maybe-uninitialized \
|
||||
calloc-transposed-args
|
||||
expansion-to-defined dangling-reference maybe-uninitialized
|
||||
HARFBUZZ_DISABLED_WARNINGS_clang := missing-field-initializers \
|
||||
range-loop-analysis unused-variable
|
||||
HARFBUZZ_DISABLED_WARNINGS_microsoft := 4267 4244
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2020, 2026, 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
|
||||
@ -29,7 +29,7 @@ DISABLED_WARNINGS_java += dangling-doc-comments
|
||||
|
||||
COPY += .gif .png .txt .spec .script .prerm .preinst \
|
||||
.postrm .postinst .list .sh .desktop .copyright .control .plist .template \
|
||||
.icns .scpt .wxs .wxl .wxi .wxf .ico .bmp .tiff .service .xsl
|
||||
.icns .scpt .wxs .wxl .wxi .wxf .ico .bmp .tiff .service .xsl .js
|
||||
|
||||
CLEAN += .properties
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2015, 2026, 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
|
||||
@ -63,7 +63,8 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
BUILD_JDK_JTREG_EXCLUDE += libDirectIO.c libInheritedChannel.c \
|
||||
libExplicitAttach.c libImplicitAttach.c \
|
||||
exelauncher.c libFDLeaker.c exeFDLeakTester.c \
|
||||
libChangeSignalDisposition.c exePrintSignalDisposition.c
|
||||
libChangeSignalDisposition.c exePrintSignalDisposition.c \
|
||||
libConcNativeFork.c libPipesCloseOnExec.c
|
||||
|
||||
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerTest := $(LIBCXX)
|
||||
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib
|
||||
@ -77,6 +78,9 @@ else
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerUnnamed := -pthread
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerModule := -pthread
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLoaderLookupInvoker := -pthread
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libConcNativeFork := -pthread
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libPipesCloseOnExec := -pthread
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLoaderLookupInvoker := -pthread
|
||||
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libExplicitAttach := -pthread
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libImplicitAttach := -pthread
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2014, 2024, Red Hat, Inc. All rights reserved.
|
||||
// Copyright 2025 Arm Limited and/or its affiliates.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -2233,15 +2233,9 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
|
||||
void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||
{
|
||||
st->print_cr("# MachUEPNode");
|
||||
if (UseCompressedClassPointers) {
|
||||
st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
|
||||
st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
|
||||
st->print_cr("\tcmpw rscratch1, r10");
|
||||
} else {
|
||||
st->print_cr("\tldr rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
|
||||
st->print_cr("\tldr r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
|
||||
st->print_cr("\tcmp rscratch1, r10");
|
||||
}
|
||||
st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
|
||||
st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
|
||||
st->print_cr("\tcmpw rscratch1, r10");
|
||||
st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
|
||||
}
|
||||
#endif
|
||||
@ -2467,11 +2461,8 @@ bool Matcher::is_generic_vector(MachOper* opnd) {
|
||||
return opnd->opcode() == VREG;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// Return whether or not this register is ever used as an argument.
|
||||
// This function is used on startup to build the trampoline stubs in
|
||||
// generateOptoStub. Registers not mentioned will be killed by the VM
|
||||
// call in the trampoline, and arguments in those registers not be
|
||||
// available to the callee.
|
||||
bool Matcher::can_be_java_arg(int reg)
|
||||
{
|
||||
return
|
||||
@ -2492,11 +2483,7 @@ bool Matcher::can_be_java_arg(int reg)
|
||||
reg == V6_num || reg == V6_H_num ||
|
||||
reg == V7_num || reg == V7_H_num;
|
||||
}
|
||||
|
||||
bool Matcher::is_spillable_arg(int reg)
|
||||
{
|
||||
return can_be_java_arg(reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint Matcher::int_pressure_limit()
|
||||
{
|
||||
@ -2531,10 +2518,6 @@ uint Matcher::float_pressure_limit()
|
||||
return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.size() : FLOATPRESSURE;
|
||||
}
|
||||
|
||||
bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RegMask& Matcher::divI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask::EMPTY;
|
||||
@ -3403,11 +3386,13 @@ encode %{
|
||||
} else if (rtype == relocInfo::metadata_type) {
|
||||
__ mov_metadata(dst_reg, (Metadata*)con);
|
||||
} else {
|
||||
assert(rtype == relocInfo::none, "unexpected reloc type");
|
||||
assert(rtype == relocInfo::none || rtype == relocInfo::external_word_type, "unexpected reloc type");
|
||||
// load fake address constants using a normal move
|
||||
if (! __ is_valid_AArch64_address(con) ||
|
||||
con < (address)(uintptr_t)os::vm_page_size()) {
|
||||
__ mov(dst_reg, con);
|
||||
} else {
|
||||
// no reloc so just use adrp and add
|
||||
uint64_t offset;
|
||||
__ adrp(dst_reg, con, offset);
|
||||
__ add(dst_reg, dst_reg, offset);
|
||||
@ -3812,11 +3797,6 @@ frame %{
|
||||
// Compiled code's Frame Pointer
|
||||
frame_pointer(R31);
|
||||
|
||||
// Interpreter stores its frame pointer in a register which is
|
||||
// stored to the stack by I2CAdaptors.
|
||||
// I2CAdaptors convert from interpreted java to compiled java.
|
||||
interpreter_frame_pointer(R29);
|
||||
|
||||
// Stack alignment requirement
|
||||
stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
|
||||
|
||||
@ -4535,6 +4515,18 @@ operand immP_1()
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// AOT Runtime Constants Address
|
||||
operand immAOTRuntimeConstantsAddress()
|
||||
%{
|
||||
// Check if the address is in the range of AOT Runtime Constants
|
||||
predicate(AOTRuntimeConstants::contains((address)(n->get_ptr())));
|
||||
match(ConP);
|
||||
|
||||
op_cost(0);
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Float and Double operands
|
||||
// Double Immediate
|
||||
operand immD()
|
||||
@ -6898,6 +6890,20 @@ instruct loadConP1(iRegPNoSp dst, immP_1 con)
|
||||
ins_pipe(ialu_imm);
|
||||
%}
|
||||
|
||||
instruct loadAOTRCAddress(iRegPNoSp dst, immAOTRuntimeConstantsAddress con)
|
||||
%{
|
||||
match(Set dst con);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "adr $dst, $con\t# AOT Runtime Constants Address" %}
|
||||
|
||||
ins_encode %{
|
||||
__ load_aotrc_address($dst$$Register, (address)$con$$constant);
|
||||
%}
|
||||
|
||||
ins_pipe(ialu_imm);
|
||||
%}
|
||||
|
||||
// Load Narrow Pointer Constant
|
||||
|
||||
instruct loadConN(iRegNNoSp dst, immN con)
|
||||
@ -8008,6 +8014,21 @@ instruct membar_release_lock() %{
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct membar_storeload() %{
|
||||
match(MemBarStoreLoad);
|
||||
ins_cost(VOLATILE_REF_COST*100);
|
||||
|
||||
format %{ "MEMBAR-store-load\n\t"
|
||||
"dmb ish" %}
|
||||
|
||||
ins_encode %{
|
||||
__ block_comment("membar_storeload");
|
||||
__ membar(Assembler::StoreLoad);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct unnecessary_membar_volatile() %{
|
||||
predicate(unnecessary_volatile(n));
|
||||
match(MemBarVolatile);
|
||||
@ -8037,6 +8058,20 @@ instruct membar_volatile() %{
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct membar_full() %{
|
||||
match(MemBarFull);
|
||||
ins_cost(VOLATILE_REF_COST*100);
|
||||
|
||||
format %{ "membar_full\n\t"
|
||||
"dmb ish" %}
|
||||
ins_encode %{
|
||||
__ block_comment("membar_full");
|
||||
__ membar(Assembler::AnyAny);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// Cast/Convert Instructions
|
||||
|
||||
|
||||
@ -3814,8 +3814,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void sve_cpy(FloatRegister Zd, SIMD_RegVariant T, PRegister Pg, int imm8,
|
||||
bool isMerge, bool isFloat) {
|
||||
void _sve_cpy(FloatRegister Zd, SIMD_RegVariant T, PRegister Pg, int imm8,
|
||||
bool isMerge, bool isFloat) {
|
||||
starti;
|
||||
assert(T != Q, "invalid size");
|
||||
int sh = 0;
|
||||
@ -3839,11 +3839,11 @@ private:
|
||||
public:
|
||||
// SVE copy signed integer immediate to vector elements (predicated)
|
||||
void sve_cpy(FloatRegister Zd, SIMD_RegVariant T, PRegister Pg, int imm8, bool isMerge) {
|
||||
sve_cpy(Zd, T, Pg, imm8, isMerge, /*isFloat*/false);
|
||||
_sve_cpy(Zd, T, Pg, imm8, isMerge, /*isFloat*/false);
|
||||
}
|
||||
// SVE copy floating-point immediate to vector elements (predicated)
|
||||
void sve_cpy(FloatRegister Zd, SIMD_RegVariant T, PRegister Pg, double d) {
|
||||
sve_cpy(Zd, T, Pg, checked_cast<uint8_t>(pack(d)), /*isMerge*/true, /*isFloat*/true);
|
||||
_sve_cpy(Zd, T, Pg, checked_cast<uint8_t>(pack(d)), /*isMerge*/true, /*isFloat*/true);
|
||||
}
|
||||
|
||||
// SVE conditionally select elements from two vectors
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#include "c1/c1_ValueStack.hpp"
|
||||
#include "ci/ciArrayKlass.hpp"
|
||||
#include "ci/ciInstance.hpp"
|
||||
#include "code/aotCodeCache.hpp"
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "gc/shared/gc_globals.hpp"
|
||||
@ -58,22 +59,6 @@ const Register SHIFT_count = r0; // where count for shift operations must be
|
||||
#define __ _masm->
|
||||
|
||||
|
||||
static void select_different_registers(Register preserve,
|
||||
Register extra,
|
||||
Register &tmp1,
|
||||
Register &tmp2) {
|
||||
if (tmp1 == preserve) {
|
||||
assert_different_registers(tmp1, tmp2, extra);
|
||||
tmp1 = extra;
|
||||
} else if (tmp2 == preserve) {
|
||||
assert_different_registers(tmp1, tmp2, extra);
|
||||
tmp2 = extra;
|
||||
}
|
||||
assert_different_registers(preserve, tmp1, tmp2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void select_different_registers(Register preserve,
|
||||
Register extra,
|
||||
Register &tmp1,
|
||||
@ -532,6 +517,15 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod
|
||||
|
||||
case T_LONG: {
|
||||
assert(patch_code == lir_patch_none, "no patching handled here");
|
||||
#if INCLUDE_CDS
|
||||
if (AOTCodeCache::is_on_for_dump()) {
|
||||
address b = c->as_pointer();
|
||||
if (AOTRuntimeConstants::contains(b)) {
|
||||
__ load_aotrc_address(dest->as_register_lo(), b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
__ mov(dest->as_register_lo(), (intptr_t)c->as_jlong());
|
||||
break;
|
||||
}
|
||||
@ -1259,12 +1253,9 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
|
||||
} else if (obj == klass_RInfo) {
|
||||
klass_RInfo = dst;
|
||||
}
|
||||
if (k->is_loaded() && !UseCompressedClassPointers) {
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo);
|
||||
} else {
|
||||
Rtmp1 = op->tmp3()->as_register();
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
|
||||
}
|
||||
|
||||
Rtmp1 = op->tmp3()->as_register();
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
|
||||
|
||||
assert_different_registers(obj, k_RInfo, klass_RInfo);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2026, 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.
|
||||
*
|
||||
@ -1287,9 +1287,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
|
||||
}
|
||||
LIR_Opr reg = rlock_result(x);
|
||||
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
|
||||
if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
|
||||
tmp3 = new_register(objectType);
|
||||
}
|
||||
tmp3 = new_register(objectType);
|
||||
__ checkcast(reg, obj.result(), x->klass(),
|
||||
new_register(objectType), new_register(objectType), tmp3,
|
||||
x->direct_compare(), info_for_exception, patching_info, stub,
|
||||
@ -1308,9 +1306,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
|
||||
}
|
||||
obj.load_item();
|
||||
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
|
||||
if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
|
||||
tmp3 = new_register(objectType);
|
||||
}
|
||||
tmp3 = new_register(objectType);
|
||||
__ instanceof(reg, obj.result(), x->klass(),
|
||||
new_register(objectType), new_register(objectType), tmp3,
|
||||
x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -105,12 +105,8 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
||||
} else {
|
||||
mov(t1, checked_cast<int32_t>(markWord::prototype().value()));
|
||||
str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
|
||||
if (UseCompressedClassPointers) { // Take care not to kill klass
|
||||
encode_klass_not_null(t1, klass);
|
||||
strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
} else {
|
||||
str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
encode_klass_not_null(t1, klass); // Take care not to kill klass
|
||||
strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
|
||||
if (len->is_valid()) {
|
||||
@ -121,7 +117,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
||||
// Clear gap/first 4 bytes following the length field.
|
||||
strw(zr, Address(obj, base_offset));
|
||||
}
|
||||
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
|
||||
} else if (!UseCompactObjectHeaders) {
|
||||
store_klass_gap(obj, zr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,6 @@ define_pd_global(bool, TieredCompilation, false);
|
||||
define_pd_global(intx, CompileThreshold, 1500 );
|
||||
|
||||
define_pd_global(intx, OnStackReplacePercentage, 933 );
|
||||
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
|
||||
define_pd_global(size_t, InitialCodeCacheSize, 160*K);
|
||||
define_pd_global(size_t, ReservedCodeCacheSize, 32*M );
|
||||
define_pd_global(size_t, NonProfiledCodeHeapSize, 13*M );
|
||||
@ -52,7 +51,6 @@ define_pd_global(bool, ProfileInterpreter, false);
|
||||
define_pd_global(size_t, CodeCacheExpansionSize, 32*K );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 1);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, true );
|
||||
define_pd_global(bool, CICompileOSR, true );
|
||||
#endif // !COMPILER2
|
||||
define_pd_global(bool, UseTypeProfile, false);
|
||||
|
||||
@ -30,7 +30,9 @@
|
||||
#include "opto/matcher.hpp"
|
||||
#include "opto/output.hpp"
|
||||
#include "opto/subnode.hpp"
|
||||
#include "runtime/objectMonitorTable.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/synchronizer.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
@ -221,37 +223,52 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1,
|
||||
if (!UseObjectMonitorTable) {
|
||||
assert(t1_monitor == t1_mark, "should be the same here");
|
||||
} else {
|
||||
const Register t1_hash = t1;
|
||||
Label monitor_found;
|
||||
|
||||
// Load cache address
|
||||
lea(t3_t, Address(rthread, JavaThread::om_cache_oops_offset()));
|
||||
// Save the mark, we might need it to extract the hash.
|
||||
mov(t3, t1_mark);
|
||||
|
||||
const int num_unrolled = 2;
|
||||
// Look for the monitor in the om_cache.
|
||||
|
||||
ByteSize cache_offset = JavaThread::om_cache_oops_offset();
|
||||
ByteSize monitor_offset = OMCache::oop_to_monitor_difference();
|
||||
const int num_unrolled = OMCache::CAPACITY;
|
||||
for (int i = 0; i < num_unrolled; i++) {
|
||||
ldr(t1, Address(t3_t));
|
||||
cmp(obj, t1);
|
||||
ldr(t1_monitor, Address(rthread, cache_offset + monitor_offset));
|
||||
ldr(t2, Address(rthread, cache_offset));
|
||||
cmp(obj, t2);
|
||||
br(Assembler::EQ, monitor_found);
|
||||
increment(t3_t, in_bytes(OMCache::oop_to_oop_difference()));
|
||||
cache_offset = cache_offset + OMCache::oop_to_oop_difference();
|
||||
}
|
||||
|
||||
Label loop;
|
||||
// Look for the monitor in the table.
|
||||
|
||||
// Search for obj in cache.
|
||||
bind(loop);
|
||||
// Get the hash code.
|
||||
ubfx(t1_hash, t3, markWord::hash_shift, markWord::hash_bits);
|
||||
|
||||
// Check for match.
|
||||
ldr(t1, Address(t3_t));
|
||||
cmp(obj, t1);
|
||||
br(Assembler::EQ, monitor_found);
|
||||
// Get the table and calculate the bucket's address
|
||||
lea(t3, ExternalAddress(ObjectMonitorTable::current_table_address()));
|
||||
ldr(t3, Address(t3));
|
||||
ldr(t2, Address(t3, ObjectMonitorTable::table_capacity_mask_offset()));
|
||||
ands(t1_hash, t1_hash, t2);
|
||||
ldr(t3, Address(t3, ObjectMonitorTable::table_buckets_offset()));
|
||||
|
||||
// Search until null encountered, guaranteed _null_sentinel at end.
|
||||
increment(t3_t, in_bytes(OMCache::oop_to_oop_difference()));
|
||||
cbnz(t1, loop);
|
||||
// Cache Miss, NE set from cmp above, cbnz does not set flags
|
||||
b(slow_path);
|
||||
// Read the monitor from the bucket.
|
||||
ldr(t1_monitor, Address(t3, t1_hash, Address::lsl(LogBytesPerWord)));
|
||||
|
||||
// Check if the monitor in the bucket is special (empty, tombstone or removed).
|
||||
cmp(t1_monitor, (unsigned char)ObjectMonitorTable::SpecialPointerValues::below_is_special);
|
||||
br(Assembler::LO, slow_path);
|
||||
|
||||
// Check if object matches.
|
||||
ldr(t3, Address(t1_monitor, ObjectMonitor::object_offset()));
|
||||
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs_asm->try_resolve_weak_handle_in_c2(this, t3, t2, slow_path);
|
||||
cmp(t3, obj);
|
||||
br(Assembler::NE, slow_path);
|
||||
|
||||
bind(monitor_found);
|
||||
ldr(t1_monitor, Address(t3_t, OMCache::oop_to_monitor_difference()));
|
||||
}
|
||||
|
||||
const Register t2_owner_addr = t2;
|
||||
@ -2858,3 +2875,24 @@ void C2_MacroAssembler::vector_expand_sve(FloatRegister dst, FloatRegister src,
|
||||
// dst = 00 87 00 65 00 43 00 21
|
||||
sve_tbl(dst, size, src, dst);
|
||||
}
|
||||
|
||||
// Optimized SVE cpy (imm, zeroing) instruction.
|
||||
//
|
||||
// `movi; cpy(imm, merging)` and `cpy(imm, zeroing)` have the same
|
||||
// functionality, but test results show that `movi; cpy(imm, merging)` has
|
||||
// higher throughput on some microarchitectures. This would depend on
|
||||
// microarchitecture and so may vary between implementations.
|
||||
void C2_MacroAssembler::sve_cpy(FloatRegister dst, SIMD_RegVariant T,
|
||||
PRegister pg, int imm8, bool isMerge) {
|
||||
if (VM_Version::prefer_sve_merging_mode_cpy() && !isMerge) {
|
||||
// Generates a NEON instruction `movi V<dst>.2d, #0`.
|
||||
// On AArch64, Z and V registers alias in the low 128 bits, so V<dst> is
|
||||
// the low 128 bits of Z<dst>. A write to V<dst> also clears all bits of
|
||||
// Z<dst> above 128, so this `movi` instruction effectively zeroes the
|
||||
// entire Z<dst> register. According to the Arm Software Optimization
|
||||
// Guide, `movi` is zero latency.
|
||||
movi(dst, T2D, 0);
|
||||
isMerge = true;
|
||||
}
|
||||
Assembler::sve_cpy(dst, T, pg, imm8, isMerge);
|
||||
}
|
||||
|
||||
@ -75,6 +75,8 @@
|
||||
unsigned vector_length_in_bytes);
|
||||
|
||||
public:
|
||||
using Assembler::sve_cpy;
|
||||
|
||||
// jdk.internal.util.ArraysSupport.vectorizedHashCode
|
||||
address arrays_hashcode(Register ary, Register cnt, Register result, FloatRegister vdata0,
|
||||
FloatRegister vdata1, FloatRegister vdata2, FloatRegister vdata3,
|
||||
@ -244,4 +246,7 @@
|
||||
void vector_expand_sve(FloatRegister dst, FloatRegister src, PRegister pg,
|
||||
FloatRegister tmp1, FloatRegister tmp2, BasicType bt,
|
||||
int vector_length_in_bytes);
|
||||
|
||||
void sve_cpy(FloatRegister dst, SIMD_RegVariant T, PRegister pg, int imm8,
|
||||
bool isMerge);
|
||||
#endif // CPU_AARCH64_C2_MACROASSEMBLER_AARCH64_HPP
|
||||
|
||||
@ -47,7 +47,6 @@ define_pd_global(intx, ConditionalMoveLimit, 3);
|
||||
define_pd_global(intx, FreqInlineSize, 325);
|
||||
define_pd_global(intx, MinJumpTableSize, 10);
|
||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||
@ -75,9 +74,6 @@ define_pd_global(size_t, NonNMethodCodeHeapSize, 5*M );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 6);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
|
||||
// Ergonomics related flags
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
||||
|
||||
define_pd_global(bool, TrapBasedRangeChecks, false); // Not needed.
|
||||
|
||||
#endif // CPU_AARCH64_C2_GLOBALS_AARCH64_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, Arm Limited. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -146,10 +146,10 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
bool should_save_return_value = !_needs_return_buffer;
|
||||
RegSpiller out_reg_spiller(_output_registers);
|
||||
int spill_offset = -1;
|
||||
int out_spill_offset = -1;
|
||||
|
||||
if (should_save_return_value) {
|
||||
spill_offset = 0;
|
||||
out_spill_offset = 0;
|
||||
// spill area can be shared with shadow space and out args,
|
||||
// since they are only used before the call,
|
||||
// and spill area is only used after.
|
||||
@ -174,6 +174,9 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
// FP-> | |
|
||||
// |---------------------| = frame_bottom_offset = frame_size
|
||||
// | (optional) |
|
||||
// | in_reg_spiller area |
|
||||
// |---------------------|
|
||||
// | (optional) |
|
||||
// | capture state buf |
|
||||
// |---------------------| = StubLocations::CAPTURED_STATE_BUFFER
|
||||
// | (optional) |
|
||||
@ -187,6 +190,19 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
GrowableArray<VMStorage> out_regs = ForeignGlobals::replace_place_holders(_input_registers, locs);
|
||||
ArgumentShuffle arg_shuffle(filtered_java_regs, out_regs, shuffle_reg);
|
||||
|
||||
// Need to spill for state capturing runtime call.
|
||||
// The area spilled into is distinct from the capture state buffer.
|
||||
RegSpiller in_reg_spiller(out_regs);
|
||||
int in_spill_offset = -1;
|
||||
if (_captured_state_mask != 0) {
|
||||
// The spill area cannot be shared with the out_spill since
|
||||
// spilling needs to happen before the call. Allocate a new
|
||||
// region in the stack for this spill space.
|
||||
in_spill_offset = allocated_frame_size;
|
||||
allocated_frame_size += in_reg_spiller.spill_size_bytes();
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
LogTarget(Trace, foreign, downcall) lt;
|
||||
if (lt.is_enabled()) {
|
||||
@ -228,6 +244,20 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
arg_shuffle.generate(_masm, shuffle_reg, 0, _abi._shadow_space_bytes);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
if (_captured_state_mask != 0) {
|
||||
assert(in_spill_offset != -1, "must be");
|
||||
__ block_comment("{ load initial thread local");
|
||||
in_reg_spiller.generate_spill(_masm, in_spill_offset);
|
||||
|
||||
// Copy the contents of the capture state buffer into thread local
|
||||
__ ldr(c_rarg0, Address(sp, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER)));
|
||||
__ movw(c_rarg1, _captured_state_mask);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, DowncallLinker::capture_state_pre), tmp1);
|
||||
|
||||
in_reg_spiller.generate_fill(_masm, in_spill_offset);
|
||||
__ block_comment("} load initial thread local");
|
||||
}
|
||||
|
||||
__ blr(as_Register(locs.get(StubLocations::TARGET_ADDRESS)));
|
||||
// this call is assumed not to have killed rthread
|
||||
|
||||
@ -254,15 +284,15 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ block_comment("{ save thread local");
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ ldr(c_rarg0, Address(sp, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER)));
|
||||
__ movw(c_rarg1, _captured_state_mask);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, DowncallLinker::capture_state), tmp1);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, DowncallLinker::capture_state_post), tmp1);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ block_comment("} save thread local");
|
||||
@ -321,7 +351,7 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
if (should_save_return_value) {
|
||||
// Need to save the native result registers around any runtime calls.
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ mov(c_rarg0, rthread);
|
||||
@ -330,7 +360,7 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ blr(tmp1);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ b(L_after_safepoint_poll);
|
||||
@ -342,13 +372,13 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ bind(L_reguard);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), tmp1);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ b(L_after_reguard);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, 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.
|
||||
*
|
||||
@ -245,8 +245,8 @@ inline bool frame::equal(frame other) const {
|
||||
|
||||
// Return unique id for this frame. The id must have a value where we can distinguish
|
||||
// identity and younger/older relationship. null represents an invalid (incomparable)
|
||||
// frame.
|
||||
inline intptr_t* frame::id(void) const { return unextended_sp(); }
|
||||
// frame. Should not be called for heap frames.
|
||||
inline intptr_t* frame::id(void) const { return real_fp(); }
|
||||
|
||||
// Return true if the frame is older (less recent activation) than the frame represented by id
|
||||
inline bool frame::is_older(intptr_t* id) const { assert(this->id() != nullptr && id != nullptr, "null frame id");
|
||||
@ -412,6 +412,9 @@ inline frame frame::sender(RegisterMap* map) const {
|
||||
StackWatermarkSet::on_iteration(map->thread(), result);
|
||||
}
|
||||
|
||||
// Calling frame::id() is currently not supported for heap frames.
|
||||
assert(result._on_heap || this->_on_heap || result.is_older(this->id()), "Must be");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "code/aotCodeCache.hpp"
|
||||
#include "gc/g1/g1BarrierSet.hpp"
|
||||
#include "gc/g1/g1BarrierSetAssembler.hpp"
|
||||
#include "gc/g1/g1BarrierSetRuntime.hpp"
|
||||
@ -243,9 +244,25 @@ static void generate_post_barrier(MacroAssembler* masm,
|
||||
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg, rscratch1);
|
||||
|
||||
// Does store cross heap regions?
|
||||
__ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
|
||||
__ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
|
||||
__ cbz(tmp1, done);
|
||||
#if INCLUDE_CDS
|
||||
// AOT code needs to load the barrier grain shift from the aot
|
||||
// runtime constants area in the code cache otherwise we can compile
|
||||
// it as an immediate operand
|
||||
if (AOTCodeCache::is_on_for_dump()) {
|
||||
address grain_shift_address = (address)AOTRuntimeConstants::grain_shift_address();
|
||||
__ eor(tmp1, store_addr, new_val);
|
||||
__ lea(tmp2, ExternalAddress(grain_shift_address));
|
||||
__ ldrb(tmp2, tmp2);
|
||||
__ lsrv(tmp1, tmp1, tmp2);
|
||||
__ cbz(tmp1, done);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
__ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
|
||||
__ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
|
||||
__ cbz(tmp1, done);
|
||||
}
|
||||
|
||||
// Crosses regions, storing null?
|
||||
if (new_val_may_be_null) {
|
||||
__ cbz(new_val, done);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, 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
|
||||
@ -441,6 +441,11 @@ OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Na
|
||||
return opto_reg;
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
|
||||
// Load the oop from the weak handle.
|
||||
__ ldr(obj, Address(obj));
|
||||
}
|
||||
|
||||
#undef __
|
||||
#define __ _masm->
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, 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
|
||||
@ -135,6 +135,7 @@ public:
|
||||
OptoReg::Name opto_reg);
|
||||
OptoReg::Name refine_register(const Node* node,
|
||||
OptoReg::Name opto_reg);
|
||||
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
#endif // COMPILER2
|
||||
};
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2022, Red Hat, Inc. All rights reserved.
|
||||
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -442,6 +443,30 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj,
|
||||
Register tmp, Label& slow_path) {
|
||||
assert_different_registers(obj, tmp);
|
||||
|
||||
Label done;
|
||||
|
||||
// Resolve weak handle using the standard implementation.
|
||||
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
|
||||
|
||||
// Check if the reference is null, and if it is, take the fast path.
|
||||
__ cbz(obj, done);
|
||||
|
||||
Address gc_state(rthread, ShenandoahThreadLocalData::gc_state_offset());
|
||||
__ lea(tmp, gc_state);
|
||||
__ ldrb(tmp, __ legitimize_address(gc_state, 1, tmp));
|
||||
|
||||
// Check if the heap is under weak-reference/roots processing, in
|
||||
// which case we need to take the slow path.
|
||||
__ tbnz(tmp, ShenandoahHeap::WEAK_ROOTS_BITPOS, slow_path);
|
||||
__ bind(done);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Special Shenandoah CAS implementation that handles false negatives due
|
||||
// to concurrent evacuation. The service is more complex than a
|
||||
// traditional CAS operation because the CAS operation is intended to
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
|
||||
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -79,6 +80,9 @@ public:
|
||||
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3);
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
#ifdef COMPILER2
|
||||
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
#endif
|
||||
void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
|
||||
bool acquire, bool release, bool is_cae, Register result);
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2026, 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
|
||||
@ -1326,6 +1326,23 @@ void ZStoreBarrierStubC2Aarch64::emit_code(MacroAssembler& masm) {
|
||||
register_stub(this);
|
||||
}
|
||||
|
||||
#undef __
|
||||
#define __ masm->
|
||||
|
||||
void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
|
||||
// Resolve weak handle using the standard implementation.
|
||||
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
|
||||
|
||||
// Check if the oop is bad, in which case we need to take the slow path.
|
||||
__ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatMarkBadBeforeMov);
|
||||
__ movzw(tmp, barrier_Relocation::unpatched);
|
||||
__ tst(obj, tmp);
|
||||
__ br(Assembler::NE, slow_path);
|
||||
|
||||
// Oop is okay, so we uncolor it.
|
||||
__ lsr(obj, obj, ZPointerLoadShift);
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
#endif // COMPILER2
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2026, 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
|
||||
@ -191,6 +191,7 @@ public:
|
||||
ZLoadBarrierStubC2* stub) const;
|
||||
void generate_c2_store_barrier_stub(MacroAssembler* masm,
|
||||
ZStoreBarrierStubC2* stub) const;
|
||||
void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
#endif // COMPILER2
|
||||
|
||||
void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
|
||||
|
||||
@ -95,7 +95,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
"Use simplest and shortest implementation for array equals") \
|
||||
product(bool, UseSIMDForBigIntegerShiftIntrinsics, true, \
|
||||
"Use SIMD instructions for left/right shift of BigInteger") \
|
||||
product(bool, UseSIMDForSHA3Intrinsic, true, \
|
||||
product(bool, UseSIMDForSHA3Intrinsic, false, \
|
||||
"Use SIMD SHA3 instructions for SHA3 intrinsic") \
|
||||
product(bool, AvoidUnalignedAccesses, false, \
|
||||
"Avoid generating unaligned memory accesses") \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -989,26 +989,15 @@ void InterpreterMacroAssembler::profile_final_call(Register mdp) {
|
||||
|
||||
|
||||
void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
||||
Register mdp,
|
||||
bool receiver_can_be_null) {
|
||||
Register mdp) {
|
||||
if (ProfileInterpreter) {
|
||||
Label profile_continue;
|
||||
|
||||
// If no method data exists, go to profile_continue.
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
Label skip_receiver_profile;
|
||||
if (receiver_can_be_null) {
|
||||
Label not_null;
|
||||
// We are making a call. Increment the count for null receiver.
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
b(skip_receiver_profile);
|
||||
bind(not_null);
|
||||
}
|
||||
|
||||
// Record the receiver type.
|
||||
profile_receiver_type(receiver, mdp, 0);
|
||||
bind(skip_receiver_profile);
|
||||
|
||||
// The method data pointer needs to be updated to reflect the new target.
|
||||
update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size()));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -285,8 +285,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void profile_not_taken_branch(Register mdp);
|
||||
void profile_call(Register mdp);
|
||||
void profile_final_call(Register mdp);
|
||||
void profile_virtual_call(Register receiver, Register mdp,
|
||||
bool receiver_can_be_null = false);
|
||||
void profile_virtual_call(Register receiver, Register mdp);
|
||||
void profile_ret(Register return_bci, Register mdp);
|
||||
void profile_null_seen(Register mdp);
|
||||
void profile_typecheck(Register mdp, Register klass);
|
||||
|
||||
@ -406,7 +406,6 @@ public:
|
||||
offset <<= shift;
|
||||
uint64_t target_page = ((uint64_t)insn_addr) + offset;
|
||||
target_page &= ((uint64_t)-1) << shift;
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
target = address(target_page);
|
||||
precond(inner != nullptr);
|
||||
inner(insn_addr, target);
|
||||
@ -520,13 +519,6 @@ int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
|
||||
return 2 * NativeInstruction::instruction_size;
|
||||
}
|
||||
|
||||
address MacroAssembler::target_addr_for_insn_or_null(address insn_addr) {
|
||||
if (NativeInstruction::is_ldrw_to_zr(insn_addr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return MacroAssembler::target_addr_for_insn(insn_addr);
|
||||
}
|
||||
|
||||
void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool in_nmethod, Register tmp) {
|
||||
ldr(tmp, Address(rthread, JavaThread::polling_word_offset()));
|
||||
if (at_return) {
|
||||
@ -770,7 +762,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
|
||||
assert(java_thread == rthread, "unexpected register");
|
||||
#ifdef ASSERT
|
||||
// TraceBytecodes does not use r12 but saves it over the call, so don't verify
|
||||
// if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");
|
||||
// if (!TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");
|
||||
#endif // ASSERT
|
||||
|
||||
assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
|
||||
@ -1010,14 +1002,10 @@ int MacroAssembler::ic_check(int end_alignment) {
|
||||
load_narrow_klass_compact(tmp1, receiver);
|
||||
ldrw(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
|
||||
cmpw(tmp1, tmp2);
|
||||
} else if (UseCompressedClassPointers) {
|
||||
} else {
|
||||
ldrw(tmp1, Address(receiver, oopDesc::klass_offset_in_bytes()));
|
||||
ldrw(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
|
||||
cmpw(tmp1, tmp2);
|
||||
} else {
|
||||
ldr(tmp1, Address(receiver, oopDesc::klass_offset_in_bytes()));
|
||||
ldr(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
|
||||
cmp(tmp1, tmp2);
|
||||
}
|
||||
|
||||
Label dont;
|
||||
@ -1960,9 +1948,7 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass,
|
||||
|
||||
const Register
|
||||
r_array_base = temp1,
|
||||
r_array_length = temp2,
|
||||
r_array_index = noreg, // unused
|
||||
r_bitmap = noreg; // unused
|
||||
r_array_length = temp2;
|
||||
|
||||
BLOCK_COMMENT("verify_secondary_supers_table {");
|
||||
|
||||
@ -3288,7 +3274,6 @@ int MacroAssembler::pop_p(unsigned int bitset, Register stack) {
|
||||
#ifdef ASSERT
|
||||
void MacroAssembler::verify_heapbase(const char* msg) {
|
||||
#if 0
|
||||
assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
|
||||
assert (Universe::heap() != nullptr, "java heap should be initialized");
|
||||
if (!UseCompressedOops || Universe::ptr_base() == nullptr) {
|
||||
// rheapbase is allocated as general register
|
||||
@ -3611,9 +3596,8 @@ extern "C" void findpc(intptr_t x);
|
||||
void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[])
|
||||
{
|
||||
// In order to get locks to work, we need to fake a in_VM state
|
||||
if (ShowMessageBoxOnError ) {
|
||||
if (ShowMessageBoxOnError) {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
JavaThreadState saved_state = thread->thread_state();
|
||||
thread->set_thread_state(_thread_in_vm);
|
||||
#ifndef PRODUCT
|
||||
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
|
||||
@ -5078,13 +5062,10 @@ void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
|
||||
void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(dst, src);
|
||||
decode_klass_not_null(dst);
|
||||
} else if (UseCompressedClassPointers) {
|
||||
ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
decode_klass_not_null(dst);
|
||||
} else {
|
||||
ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
decode_klass_not_null(dst);
|
||||
}
|
||||
|
||||
void MacroAssembler::restore_cpu_control_state_after_jni(Register tmp1, Register tmp2) {
|
||||
@ -5136,25 +5117,21 @@ void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, R
|
||||
|
||||
void MacroAssembler::cmp_klass(Register obj, Register klass, Register tmp) {
|
||||
assert_different_registers(obj, klass, tmp);
|
||||
if (UseCompressedClassPointers) {
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(tmp, obj);
|
||||
} else {
|
||||
ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
if (CompressedKlassPointers::base() == nullptr) {
|
||||
cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
|
||||
return;
|
||||
} else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
|
||||
&& CompressedKlassPointers::shift() == 0) {
|
||||
// Only the bottom 32 bits matter
|
||||
cmpw(klass, tmp);
|
||||
return;
|
||||
}
|
||||
decode_klass_not_null(tmp);
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(tmp, obj);
|
||||
} else {
|
||||
ldr(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
if (CompressedKlassPointers::base() == nullptr) {
|
||||
cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
|
||||
return;
|
||||
} else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
|
||||
&& CompressedKlassPointers::shift() == 0) {
|
||||
// Only the bottom 32 bits matter
|
||||
cmpw(klass, tmp);
|
||||
return;
|
||||
}
|
||||
decode_klass_not_null(tmp);
|
||||
cmp(klass, tmp);
|
||||
}
|
||||
|
||||
@ -5162,36 +5139,25 @@ void MacroAssembler::cmp_klasses_from_objects(Register obj1, Register obj2, Regi
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(tmp1, obj1);
|
||||
load_narrow_klass_compact(tmp2, obj2);
|
||||
cmpw(tmp1, tmp2);
|
||||
} else if (UseCompressedClassPointers) {
|
||||
} else {
|
||||
ldrw(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
|
||||
ldrw(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));
|
||||
cmpw(tmp1, tmp2);
|
||||
} else {
|
||||
ldr(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
|
||||
ldr(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));
|
||||
cmp(tmp1, tmp2);
|
||||
}
|
||||
cmpw(tmp1, tmp2);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_klass(Register dst, Register src) {
|
||||
// FIXME: Should this be a store release? concurrent gcs assumes
|
||||
// klass length is valid if klass field is not null.
|
||||
assert(!UseCompactObjectHeaders, "not with compact headers");
|
||||
if (UseCompressedClassPointers) {
|
||||
encode_klass_not_null(src);
|
||||
strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
|
||||
} else {
|
||||
str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
encode_klass_not_null(src);
|
||||
strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
|
||||
void MacroAssembler::store_klass_gap(Register dst, Register src) {
|
||||
assert(!UseCompactObjectHeaders, "not with compact headers");
|
||||
if (UseCompressedClassPointers) {
|
||||
// Store to klass gap in destination
|
||||
strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
|
||||
}
|
||||
// Store to klass gap in destination
|
||||
strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
|
||||
}
|
||||
|
||||
// Algorithm must match CompressedOops::encode.
|
||||
@ -5337,8 +5303,6 @@ MacroAssembler::KlassDecodeMode MacroAssembler::klass_decode_mode() {
|
||||
}
|
||||
|
||||
MacroAssembler::KlassDecodeMode MacroAssembler::klass_decode_mode(address base, int shift, const size_t range) {
|
||||
assert(UseCompressedClassPointers, "not using compressed class pointers");
|
||||
|
||||
// KlassDecodeMode shouldn't be set already.
|
||||
assert(_klass_decode_mode == KlassDecodeNone, "set once");
|
||||
|
||||
@ -5468,8 +5432,6 @@ void MacroAssembler::decode_klass_not_null_for_aot(Register dst, Register src) {
|
||||
}
|
||||
|
||||
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
|
||||
if (AOTCodeCache::is_on_for_dump()) {
|
||||
decode_klass_not_null_for_aot(dst, src);
|
||||
return;
|
||||
@ -5536,7 +5498,6 @@ void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
|
||||
}
|
||||
|
||||
void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert (oop_recorder() != nullptr, "this assembler needs an OopRecorder");
|
||||
int index = oop_recorder()->find_index(k);
|
||||
|
||||
@ -5738,7 +5699,6 @@ address MacroAssembler::read_polling_page(Register r, relocInfo::relocType rtype
|
||||
}
|
||||
|
||||
void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) {
|
||||
relocInfo::relocType rtype = dest.rspec().reloc()->type();
|
||||
uint64_t low_page = (uint64_t)CodeCache::low_bound() >> 12;
|
||||
uint64_t high_page = (uint64_t)(CodeCache::high_bound()-1) >> 12;
|
||||
uint64_t dest_page = (uint64_t)dest.target() >> 12;
|
||||
@ -5766,6 +5726,14 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_off
|
||||
}
|
||||
|
||||
void MacroAssembler::load_byte_map_base(Register reg) {
|
||||
#if INCLUDE_CDS
|
||||
if (AOTCodeCache::is_on_for_dump()) {
|
||||
address byte_map_base_adr = AOTRuntimeConstants::card_table_base_address();
|
||||
lea(reg, ExternalAddress(byte_map_base_adr));
|
||||
ldr(reg, Address(reg));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
|
||||
// Strictly speaking the card table base isn't an address at all, and it might
|
||||
@ -5773,6 +5741,20 @@ void MacroAssembler::load_byte_map_base(Register reg) {
|
||||
mov(reg, (uint64_t)ctbs->card_table_base_const());
|
||||
}
|
||||
|
||||
void MacroAssembler::load_aotrc_address(Register reg, address a) {
|
||||
#if INCLUDE_CDS
|
||||
assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
|
||||
if (AOTCodeCache::is_on_for_dump()) {
|
||||
// all aotrc field addresses should be registered in the AOTCodeCache address table
|
||||
lea(reg, ExternalAddress(a));
|
||||
} else {
|
||||
mov(reg, (uint64_t)a);
|
||||
}
|
||||
#else
|
||||
ShouldNotReachHere();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MacroAssembler::build_frame(int framesize) {
|
||||
assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
|
||||
assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
|
||||
@ -6114,7 +6096,6 @@ void MacroAssembler::string_equals(Register a1, Register a2,
|
||||
Label SAME, DONE, SHORT, NEXT_WORD;
|
||||
Register tmp1 = rscratch1;
|
||||
Register tmp2 = rscratch2;
|
||||
Register cnt2 = tmp2; // cnt2 only used in array length compare
|
||||
|
||||
assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2024, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -678,7 +678,6 @@ public:
|
||||
static bool uses_implicit_null_check(void* address);
|
||||
|
||||
static address target_addr_for_insn(address insn_addr);
|
||||
static address target_addr_for_insn_or_null(address insn_addr);
|
||||
|
||||
// Required platform-specific helpers for Label::patch_instructions.
|
||||
// They _shadow_ the declarations in AbstractAssembler, which are undefined.
|
||||
@ -1477,6 +1476,9 @@ public:
|
||||
// Load the base of the cardtable byte map into reg.
|
||||
void load_byte_map_base(Register reg);
|
||||
|
||||
// Load a constant address in the AOT Runtime Constants area
|
||||
void load_aotrc_address(Register reg, address a);
|
||||
|
||||
// Prolog generator routines to support switch between x86 code and
|
||||
// generated ARM code
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -192,7 +192,6 @@ int NativeMovRegMem::offset() const {
|
||||
|
||||
void NativeMovRegMem::set_offset(int x) {
|
||||
address pc = instruction_address();
|
||||
unsigned insn = *(unsigned*)pc;
|
||||
if (maybe_cpool_ref(pc)) {
|
||||
address addr = MacroAssembler::target_addr_for_insn(pc);
|
||||
*(int64_t*)addr = x;
|
||||
@ -204,7 +203,7 @@ void NativeMovRegMem::set_offset(int x) {
|
||||
|
||||
void NativeMovRegMem::verify() {
|
||||
#ifdef ASSERT
|
||||
address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address());
|
||||
MacroAssembler::target_addr_for_insn(instruction_address());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -213,7 +212,7 @@ void NativeMovRegMem::verify() {
|
||||
void NativeJump::verify() { ; }
|
||||
|
||||
address NativeJump::jump_destination() const {
|
||||
address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address());
|
||||
address dest = MacroAssembler::target_addr_for_insn(instruction_address());
|
||||
|
||||
// We use jump to self as the unresolved address which the inline
|
||||
// cache code (and relocs) know about
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2025, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -78,7 +78,6 @@ public:
|
||||
inline bool is_nop() const;
|
||||
bool is_jump();
|
||||
bool is_general_jump();
|
||||
inline bool is_jump_or_nop();
|
||||
inline bool is_cond_jump();
|
||||
bool is_safepoint_poll();
|
||||
bool is_movz();
|
||||
@ -420,10 +419,6 @@ inline bool NativeInstruction::is_jump() {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool NativeInstruction::is_jump_or_nop() {
|
||||
return is_nop() || is_jump();
|
||||
}
|
||||
|
||||
// Call trampoline stubs.
|
||||
class NativeCallTrampolineStub : public NativeInstruction {
|
||||
public:
|
||||
|
||||
@ -11876,16 +11876,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_sha512_implCompress = generate_sha512_implCompress(StubId::stubgen_sha512_implCompress_id);
|
||||
StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubId::stubgen_sha512_implCompressMB_id);
|
||||
}
|
||||
if (UseSHA3Intrinsics) {
|
||||
|
||||
if (UseSHA3Intrinsics && UseSIMDForSHA3Intrinsic) {
|
||||
StubRoutines::_double_keccak = generate_double_keccak();
|
||||
if (UseSIMDForSHA3Intrinsic) {
|
||||
StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubId::stubgen_sha3_implCompress_id);
|
||||
StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubId::stubgen_sha3_implCompressMB_id);
|
||||
} else {
|
||||
StubRoutines::_sha3_implCompress = generate_sha3_implCompress_gpr(StubId::stubgen_sha3_implCompress_id);
|
||||
StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress_gpr(StubId::stubgen_sha3_implCompressMB_id);
|
||||
}
|
||||
StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubId::stubgen_sha3_implCompress_id);
|
||||
StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubId::stubgen_sha3_implCompressMB_id);
|
||||
} else if (UseSHA3Intrinsics) {
|
||||
StubRoutines::_sha3_implCompress = generate_sha3_implCompress_gpr(StubId::stubgen_sha3_implCompress_id);
|
||||
StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress_gpr(StubId::stubgen_sha3_implCompressMB_id);
|
||||
}
|
||||
|
||||
if (UsePoly1305Intrinsics) {
|
||||
|
||||
@ -96,10 +96,6 @@ static inline Address aaddress(Register r) {
|
||||
return iaddress(r);
|
||||
}
|
||||
|
||||
static inline Address at_rsp() {
|
||||
return Address(esp, 0);
|
||||
}
|
||||
|
||||
// At top of Java expression stack which may be different than esp(). It
|
||||
// isn't for category 1 objects.
|
||||
static inline Address at_tos () {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright 2025 Arm Limited and/or its affiliates.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -365,16 +365,28 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA && VM_Version::supports_sha3()) {
|
||||
// Auto-enable UseSHA3Intrinsics on hardware with performance benefit.
|
||||
// Note that the evaluation of UseSHA3Intrinsics shows better performance
|
||||
if (UseSHA) {
|
||||
// No need to check VM_Version::supports_sha3(), since a fallback GPR intrinsic implementation is provided.
|
||||
if (FLAG_IS_DEFAULT(UseSHA3Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSHA3Intrinsics, true);
|
||||
}
|
||||
} else if (UseSHA3Intrinsics) {
|
||||
// Matches the documented and tested behavior: the -UseSHA option disables all SHA intrinsics.
|
||||
warning("UseSHA3Intrinsics requires that UseSHA is enabled.");
|
||||
FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA3Intrinsics && VM_Version::supports_sha3()) {
|
||||
// Auto-enable UseSIMDForSHA3Intrinsic on hardware with performance benefit.
|
||||
// Note that the evaluation of SHA3 extension Intrinsics shows better performance
|
||||
// on Apple and Qualcomm silicon but worse performance on Neoverse V1 and N2.
|
||||
if (_cpu == CPU_APPLE || _cpu == CPU_QUALCOMM) { // Apple or Qualcomm silicon
|
||||
if (FLAG_IS_DEFAULT(UseSHA3Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSHA3Intrinsics, true);
|
||||
if (FLAG_IS_DEFAULT(UseSIMDForSHA3Intrinsic)) {
|
||||
FLAG_SET_DEFAULT(UseSIMDForSHA3Intrinsic, true);
|
||||
}
|
||||
}
|
||||
} else if (UseSHA3Intrinsics && UseSIMDForSHA3Intrinsic) {
|
||||
}
|
||||
if (UseSHA3Intrinsics && UseSIMDForSHA3Intrinsic && !VM_Version::supports_sha3()) {
|
||||
warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
|
||||
}
|
||||
@ -446,7 +458,9 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(BlockZeroingLowLimit, 4 * VM_Version::zva_length());
|
||||
}
|
||||
} else if (UseBlockZeroing) {
|
||||
warning("DC ZVA is not available on this CPU");
|
||||
if (!FLAG_IS_DEFAULT(UseBlockZeroing)) {
|
||||
warning("DC ZVA is not available on this CPU");
|
||||
}
|
||||
FLAG_SET_DEFAULT(UseBlockZeroing, false);
|
||||
}
|
||||
|
||||
@ -664,16 +678,52 @@ void VM_Version::initialize() {
|
||||
void VM_Version::insert_features_names(uint64_t features, stringStream& ss) {
|
||||
int i = 0;
|
||||
ss.join([&]() {
|
||||
while (i < MAX_CPU_FEATURES) {
|
||||
if (supports_feature((VM_Version::Feature_Flag)i)) {
|
||||
return _features_names[i++];
|
||||
const char* str = nullptr;
|
||||
while ((i < MAX_CPU_FEATURES) && (str == nullptr)) {
|
||||
if (supports_feature(features, (VM_Version::Feature_Flag)i)) {
|
||||
str = _features_names[i];
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return (const char*)nullptr;
|
||||
return str;
|
||||
}, ", ");
|
||||
}
|
||||
|
||||
void VM_Version::get_cpu_features_name(void* features_buffer, stringStream& ss) {
|
||||
uint64_t features = *(uint64_t*)features_buffer;
|
||||
insert_features_names(features, ss);
|
||||
}
|
||||
|
||||
void VM_Version::get_missing_features_name(void* features_set1, void* features_set2, stringStream& ss) {
|
||||
uint64_t vm_features_set1 = *(uint64_t*)features_set1;
|
||||
uint64_t vm_features_set2 = *(uint64_t*)features_set2;
|
||||
int i = 0;
|
||||
ss.join([&]() {
|
||||
const char* str = nullptr;
|
||||
while ((i < MAX_CPU_FEATURES) && (str == nullptr)) {
|
||||
Feature_Flag flag = (Feature_Flag)i;
|
||||
if (supports_feature(vm_features_set1, flag) && !supports_feature(vm_features_set2, flag)) {
|
||||
str = _features_names[i];
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return str;
|
||||
}, ", ");
|
||||
}
|
||||
|
||||
int VM_Version::cpu_features_size() {
|
||||
return sizeof(_features);
|
||||
}
|
||||
|
||||
void VM_Version::store_cpu_features(void* buf) {
|
||||
*(uint64_t*)buf = _features;
|
||||
}
|
||||
|
||||
bool VM_Version::supports_features(void* features_buffer) {
|
||||
uint64_t features_to_test = *(uint64_t*)features_buffer;
|
||||
return (_features & features_to_test) == features_to_test;
|
||||
}
|
||||
|
||||
#if defined(LINUX)
|
||||
static bool check_info_file(const char* fpath,
|
||||
const char* virt1, VirtualizationType vt1,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -55,6 +55,9 @@ protected:
|
||||
static int _max_supported_sve_vector_length;
|
||||
static bool _rop_protection;
|
||||
static uintptr_t _pac_mask;
|
||||
// When _prefer_sve_merging_mode_cpy is true, `cpy (imm, zeroing)` is
|
||||
// implemented as `movi; cpy(imm, merging)`.
|
||||
static constexpr bool _prefer_sve_merging_mode_cpy = true;
|
||||
|
||||
static SpinWait _spin_wait;
|
||||
|
||||
@ -184,6 +187,9 @@ public:
|
||||
static bool supports_feature(Feature_Flag flag) {
|
||||
return (_features & BIT_MASK(flag)) != 0;
|
||||
}
|
||||
static bool supports_feature(uint64_t features, Feature_Flag flag) {
|
||||
return (features & BIT_MASK(flag)) != 0;
|
||||
}
|
||||
|
||||
static int cpu_family() { return _cpu; }
|
||||
static int cpu_model() { return _model; }
|
||||
@ -204,7 +210,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_zva_enabled() { return 0 <= _zva_length; }
|
||||
static bool is_zva_enabled() { return 0 < _zva_length; }
|
||||
static int zva_length() {
|
||||
assert(is_zva_enabled(), "ZVA not available");
|
||||
return _zva_length;
|
||||
@ -239,11 +245,27 @@ public:
|
||||
|
||||
static bool use_rop_protection() { return _rop_protection; }
|
||||
|
||||
static bool prefer_sve_merging_mode_cpy() { return _prefer_sve_merging_mode_cpy; }
|
||||
|
||||
// For common 64/128-bit unpredicated vector operations, we may prefer
|
||||
// emitting NEON instructions rather than the corresponding SVE instructions.
|
||||
static bool use_neon_for_vector(int vector_length_in_bytes) {
|
||||
return vector_length_in_bytes <= 16;
|
||||
}
|
||||
|
||||
static void get_cpu_features_name(void* features_buffer, stringStream& ss);
|
||||
|
||||
// Returns names of features present in features_set1 but not in features_set2
|
||||
static void get_missing_features_name(void* features_set1, void* features_set2, stringStream& ss);
|
||||
|
||||
// Returns number of bytes required to store cpu features representation
|
||||
static int cpu_features_size();
|
||||
|
||||
// Stores cpu features representation in the provided buffer. This representation is arch dependent.
|
||||
// Size of the buffer must be same as returned by cpu_features_size()
|
||||
static void store_cpu_features(void* buf);
|
||||
|
||||
static bool supports_features(void* features_to_test);
|
||||
};
|
||||
|
||||
#endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2008, 2026, 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
|
||||
@ -1088,10 +1088,8 @@ bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack,
|
||||
return clone_base_plus_offset_address(m, mstack, address_visited);
|
||||
}
|
||||
|
||||
// Return whether or not this register is ever used as an argument. This
|
||||
// function is used on startup to build the trampoline stubs in generateOptoStub.
|
||||
// Registers not mentioned will be killed by the VM call in the trampoline, and
|
||||
// arguments in those registers not be available to the callee.
|
||||
#ifdef ASSERT
|
||||
// Return whether or not this register is ever used as an argument.
|
||||
bool Matcher::can_be_java_arg( int reg ) {
|
||||
if (reg == R_R0_num ||
|
||||
reg == R_R1_num ||
|
||||
@ -1102,10 +1100,7 @@ bool Matcher::can_be_java_arg( int reg ) {
|
||||
reg <= R_S13_num) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Matcher::is_spillable_arg( int reg ) {
|
||||
return can_be_java_arg(reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint Matcher::int_pressure_limit()
|
||||
{
|
||||
@ -1117,10 +1112,6 @@ uint Matcher::float_pressure_limit()
|
||||
return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE;
|
||||
}
|
||||
|
||||
bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register for DIVI projection of divmodI
|
||||
const RegMask& Matcher::divI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
@ -4445,6 +4436,18 @@ instruct membar_release_lock() %{
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
instruct membar_storeload() %{
|
||||
match(MemBarStoreLoad);
|
||||
ins_cost(4*MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "MEMBAR-storeload" %}
|
||||
ins_encode %{
|
||||
__ membar(MacroAssembler::StoreLoad, noreg);
|
||||
%}
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
instruct membar_volatile() %{
|
||||
match(MemBarVolatile);
|
||||
ins_cost(4*MEMORY_REF_COST);
|
||||
@ -4468,6 +4471,18 @@ instruct unnecessary_membar_volatile() %{
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
instruct membar_full() %{
|
||||
match(MemBarFull);
|
||||
ins_cost(4*MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "MEMBAR-full" %}
|
||||
ins_encode %{
|
||||
__ membar(MacroAssembler::StoreLoad, noreg);
|
||||
%}
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
//----------Register Move Instructions-----------------------------------------
|
||||
|
||||
// Cast Index to Pointer for unsafe natives
|
||||
|
||||
@ -43,7 +43,6 @@ define_pd_global(bool, TieredCompilation, false);
|
||||
define_pd_global(intx, CompileThreshold, 1500 );
|
||||
|
||||
define_pd_global(intx, OnStackReplacePercentage, 933 );
|
||||
define_pd_global(size_t, NewSizeThreadIncrease, 4*K );
|
||||
define_pd_global(size_t, InitialCodeCacheSize, 160*K);
|
||||
define_pd_global(size_t, ReservedCodeCacheSize, 32*M );
|
||||
define_pd_global(size_t, NonProfiledCodeHeapSize, 13*M );
|
||||
@ -53,7 +52,6 @@ define_pd_global(bool, ProfileInterpreter, false);
|
||||
define_pd_global(size_t, CodeCacheExpansionSize, 32*K );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 1);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, true);
|
||||
define_pd_global(bool, CICompileOSR, true );
|
||||
#endif // COMPILER2
|
||||
define_pd_global(bool, UseTypeProfile, false);
|
||||
|
||||
@ -47,7 +47,6 @@ define_pd_global(intx, ConditionalMoveLimit, 4);
|
||||
// C2 gets to use all the float/double registers
|
||||
define_pd_global(intx, FreqInlineSize, 175);
|
||||
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
|
||||
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||
// The default setting 16/16 seems to work best.
|
||||
// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
|
||||
//define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize
|
||||
@ -94,7 +93,4 @@ define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
|
||||
define_pd_global(bool, TrapBasedRangeChecks, false); // Not needed
|
||||
|
||||
// Ergonomics related flags
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
||||
|
||||
#endif // CPU_ARM_C2_GLOBALS_ARM_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2026, 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
|
||||
@ -1210,7 +1210,7 @@ void InterpreterMacroAssembler::profile_final_call(Register mdp) {
|
||||
|
||||
|
||||
// Sets mdp, blows Rtemp.
|
||||
void InterpreterMacroAssembler::profile_virtual_call(Register mdp, Register receiver, bool receiver_can_be_null) {
|
||||
void InterpreterMacroAssembler::profile_virtual_call(Register mdp, Register receiver) {
|
||||
assert_different_registers(mdp, receiver, Rtemp);
|
||||
|
||||
if (ProfileInterpreter) {
|
||||
@ -1219,19 +1219,8 @@ void InterpreterMacroAssembler::profile_virtual_call(Register mdp, Register rece
|
||||
// If no method data exists, go to profile_continue.
|
||||
test_method_data_pointer(mdp, profile_continue);
|
||||
|
||||
Label skip_receiver_profile;
|
||||
if (receiver_can_be_null) {
|
||||
Label not_null;
|
||||
cbnz(receiver, not_null);
|
||||
// We are making a call. Increment the count for null receiver.
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()), Rtemp);
|
||||
b(skip_receiver_profile);
|
||||
bind(not_null);
|
||||
}
|
||||
|
||||
// Record the receiver type.
|
||||
record_klass_in_profile(receiver, mdp, Rtemp, true);
|
||||
bind(skip_receiver_profile);
|
||||
|
||||
// The method data pointer needs to be updated to reflect the new target.
|
||||
update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size()));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2026, 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
|
||||
@ -239,8 +239,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
|
||||
void profile_call(Register mdp); // Sets mdp, blows Rtemp.
|
||||
void profile_final_call(Register mdp); // Sets mdp, blows Rtemp.
|
||||
void profile_virtual_call(Register mdp, Register receiver, // Sets mdp, blows Rtemp.
|
||||
bool receiver_can_be_null = false);
|
||||
void profile_virtual_call(Register mdp, Register receiver); // Sets mdp, blows Rtemp.
|
||||
void profile_ret(Register mdp, Register return_bci); // Sets mdp, blows R0-R3/R0-R18, Rtemp, LR
|
||||
void profile_null_seen(Register mdp); // Sets mdp.
|
||||
void profile_typecheck(Register mdp, Register klass); // Sets mdp, blows Rtemp.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, 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
|
||||
@ -75,7 +75,6 @@
|
||||
|
||||
static bool narrow_klass_use_complex_address() {
|
||||
NOT_LP64(ShouldNotCallThis());
|
||||
assert(UseCompressedClassPointers, "only for compressed klass code");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -599,6 +599,9 @@ class Assembler : public AbstractAssembler {
|
||||
XVMAXSP_OPCODE = (60u << OPCODE_SHIFT | 192u << 3),
|
||||
XVMAXDP_OPCODE = (60u << OPCODE_SHIFT | 224u << 3),
|
||||
|
||||
XSMINJDP_OPCODE = (60u << OPCODE_SHIFT | 152u << 3),
|
||||
XSMAXJDP_OPCODE = (60u << OPCODE_SHIFT | 144u << 3),
|
||||
|
||||
// Deliver A Random Number (introduced with POWER9)
|
||||
DARN_OPCODE = (31u << OPCODE_SHIFT | 755u << 1),
|
||||
|
||||
@ -1577,10 +1580,6 @@ class Assembler : public AbstractAssembler {
|
||||
static bool is_nop(int x) {
|
||||
return x == 0x60000000;
|
||||
}
|
||||
// endgroup opcode for Power6
|
||||
static bool is_endgroup(int x) {
|
||||
return is_ori(x) && inv_ra_field(x) == 1 && inv_rs_field(x) == 1 && inv_d1_field(x) == 0;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
@ -1656,9 +1655,6 @@ class Assembler : public AbstractAssembler {
|
||||
inline void ori_opt( Register d, int ui16);
|
||||
inline void oris_opt(Register d, int ui16);
|
||||
|
||||
// endgroup opcode for Power6
|
||||
inline void endgroup();
|
||||
|
||||
// count instructions
|
||||
inline void cntlzw( Register a, Register s);
|
||||
inline void cntlzw_( Register a, Register s);
|
||||
@ -2455,6 +2451,9 @@ class Assembler : public AbstractAssembler {
|
||||
inline void xvrdpim( VectorSRegister d, VectorSRegister b);
|
||||
inline void xvrdpip( VectorSRegister d, VectorSRegister b);
|
||||
|
||||
inline void xsminjdp( VectorSRegister d, VectorSRegister a, VectorSRegister b); // Requires Power 9
|
||||
inline void xsmaxjdp( VectorSRegister d, VectorSRegister a, VectorSRegister b); // Requires Power 9
|
||||
|
||||
// The following functions do not match exactly the Java.math semantics.
|
||||
inline void xvminsp( VectorSRegister d, VectorSRegister a, VectorSRegister b);
|
||||
inline void xvmindp( VectorSRegister d, VectorSRegister a, VectorSRegister b);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -253,8 +253,6 @@ inline void Assembler::mr( Register d, Register s) { Assembler::orr(d, s,
|
||||
inline void Assembler::ori_opt( Register d, int ui16) { if (ui16!=0) Assembler::ori( d, d, ui16); }
|
||||
inline void Assembler::oris_opt(Register d, int ui16) { if (ui16!=0) Assembler::oris(d, d, ui16); }
|
||||
|
||||
inline void Assembler::endgroup() { Assembler::ori(R1, R1, 0); }
|
||||
|
||||
// count instructions
|
||||
inline void Assembler::cntlzw( Register a, Register s) { emit_int32(CNTLZW_OPCODE | rta(a) | rs(s) | rc(0)); }
|
||||
inline void Assembler::cntlzw_( Register a, Register s) { emit_int32(CNTLZW_OPCODE | rta(a) | rs(s) | rc(1)); }
|
||||
@ -908,6 +906,9 @@ inline void Assembler::xvrdpic( VectorSRegister d, VectorSRegister b)
|
||||
inline void Assembler::xvrdpim( VectorSRegister d, VectorSRegister b) { emit_int32( XVRDPIM_OPCODE | vsrt(d) | vsrb(b)); }
|
||||
inline void Assembler::xvrdpip( VectorSRegister d, VectorSRegister b) { emit_int32( XVRDPIP_OPCODE | vsrt(d) | vsrb(b)); }
|
||||
|
||||
inline void Assembler::xsminjdp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XSMINJDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
|
||||
inline void Assembler::xsmaxjdp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XSMAXJDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
|
||||
|
||||
inline void Assembler::xvminsp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMINSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
|
||||
inline void Assembler::xvmindp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMINDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
|
||||
inline void Assembler::xvmaxsp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMAXSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -144,7 +144,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
||||
|
||||
if (len->is_valid()) {
|
||||
stw(len, arrayOopDesc::length_offset_in_bytes(), obj);
|
||||
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
|
||||
} else if (!UseCompactObjectHeaders) {
|
||||
// Otherwise length is in the class gap.
|
||||
store_klass_gap(obj);
|
||||
}
|
||||
|
||||
@ -51,8 +51,6 @@ define_pd_global(size_t, NonNMethodCodeHeapSize, 5*M );
|
||||
define_pd_global(size_t, CodeCacheExpansionSize, 32*K);
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 1);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, true);
|
||||
define_pd_global(size_t, NewSizeThreadIncrease, 16*K);
|
||||
define_pd_global(size_t, InitialCodeCacheSize, 160*K);
|
||||
#endif // !COMPILER2
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2026 SAP SE. 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
|
||||
@ -600,19 +601,21 @@ void C2_MacroAssembler::count_positives(Register src, Register cnt, Register res
|
||||
orr(tmp0, tmp2, tmp0);
|
||||
|
||||
and_(tmp0, tmp0, tmp1);
|
||||
bne(CR0, Lslow); // Found negative byte.
|
||||
bne(CR0, Lslow); // Found negative byte.
|
||||
addi(result, result, 16);
|
||||
bdnz(Lfastloop);
|
||||
|
||||
bind(Lslow); // Fallback to slow version.
|
||||
subf(tmp0, src, result); // Bytes known positive.
|
||||
subf_(tmp0, tmp0, cnt); // Remaining Bytes.
|
||||
clrldi(tmp1, cnt, 32); // Clear garbage from upper 32 bits.
|
||||
subf_(tmp0, tmp0, tmp1); // Remaining Bytes.
|
||||
beq(CR0, Ldone);
|
||||
mtctr(tmp0);
|
||||
|
||||
bind(Lloop);
|
||||
lbz(tmp0, 0, result);
|
||||
andi_(tmp0, tmp0, 0x80);
|
||||
bne(CR0, Ldone); // Found negative byte.
|
||||
bne(CR0, Ldone); // Found negative byte.
|
||||
addi(result, result, 1);
|
||||
bdnz(Lloop);
|
||||
|
||||
|
||||
@ -47,7 +47,6 @@ define_pd_global(intx, ConditionalMoveLimit, 3);
|
||||
define_pd_global(intx, FreqInlineSize, 325);
|
||||
define_pd_global(intx, MinJumpTableSize, 10);
|
||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||
define_pd_global(intx, RegisterCostAreaRatio, 16000);
|
||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||
@ -91,7 +90,4 @@ define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
|
||||
define_pd_global(bool, TrapBasedRangeChecks, true);
|
||||
|
||||
// Ergonomics related flags
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
||||
|
||||
#endif // CPU_PPC_C2_GLOBALS_PPC_HPP
|
||||
|
||||
@ -119,9 +119,6 @@ address Disassembler::decode_instruction0(address here, outputStream * st, addre
|
||||
} else if (instruction == 0xbadbabe) {
|
||||
st->print(".data 0xbadbabe");
|
||||
next = here + Assembler::instr_len(here);
|
||||
} else if (Assembler::is_endgroup(instruction)) {
|
||||
st->print("endgroup");
|
||||
next = here + Assembler::instr_len(here);
|
||||
} else {
|
||||
next = here;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, 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
|
||||
@ -135,10 +135,10 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
bool should_save_return_value = !_needs_return_buffer;
|
||||
RegSpiller out_reg_spiller(_output_registers);
|
||||
int spill_offset = -1;
|
||||
int out_spill_offset = -1;
|
||||
|
||||
if (should_save_return_value) {
|
||||
spill_offset = frame::native_abi_reg_args_size;
|
||||
out_spill_offset = frame::native_abi_reg_args_size;
|
||||
// Spill area can be shared with additional out args (>8),
|
||||
// since it is only used after the call.
|
||||
int frame_size_including_spill_area = frame::native_abi_reg_args_size + out_reg_spiller.spill_size_bytes();
|
||||
@ -170,6 +170,18 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
ArgumentShuffle arg_shuffle(filtered_java_regs, out_regs, _abi._scratch1);
|
||||
|
||||
// Need to spill for state capturing runtime call.
|
||||
// The area spilled into is distinct from the capture state buffer.
|
||||
RegSpiller in_reg_spiller(out_regs);
|
||||
int in_spill_offset = -1;
|
||||
if (_captured_state_mask != 0) {
|
||||
// The spill area cannot be shared with the out_spill since
|
||||
// spilling needs to happen before the call. Allocate a new
|
||||
// region in the stack for this spill space.
|
||||
in_spill_offset = allocated_frame_size;
|
||||
allocated_frame_size += in_reg_spiller.spill_size_bytes();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
LogTarget(Trace, foreign, downcall) lt;
|
||||
if (lt.is_enabled()) {
|
||||
@ -211,6 +223,21 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
arg_shuffle.generate(_masm, as_VMStorage(callerSP), frame::jit_out_preserve_size, frame::native_abi_minframe_size);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
if (_captured_state_mask != 0) {
|
||||
assert(in_spill_offset != -1, "must be");
|
||||
__ block_comment("{ load initial thread local");
|
||||
in_reg_spiller.generate_spill(_masm, in_spill_offset);
|
||||
|
||||
// Copy the contents of the capture state buffer into thread local
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, DowncallLinker::capture_state_pre), R0);
|
||||
__ ld(R3_ARG1, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER), R1_SP);
|
||||
__ load_const_optimized(R4_ARG2, _captured_state_mask, R0);
|
||||
__ call_c(call_target_address);
|
||||
|
||||
in_reg_spiller.generate_fill(_masm, in_spill_offset);
|
||||
__ block_comment("} load initial thread local");
|
||||
}
|
||||
|
||||
__ call_c(call_target_address);
|
||||
|
||||
if (_needs_return_buffer) {
|
||||
@ -247,16 +274,16 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ block_comment("{ save thread local");
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, DowncallLinker::capture_state), R0);
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, DowncallLinker::capture_state_post), R0);
|
||||
__ ld(R3_ARG1, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER), R1_SP);
|
||||
__ load_const_optimized(R4_ARG2, _captured_state_mask, R0);
|
||||
__ call_c(call_target_address);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ block_comment("} save thread local");
|
||||
@ -310,7 +337,7 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
if (should_save_return_value) {
|
||||
// Need to save the native result registers around any runtime calls.
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, JavaThread::check_special_condition_for_native_trans), R0);
|
||||
@ -318,7 +345,7 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ call_c(call_target_address);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ b(L_after_safepoint_poll);
|
||||
@ -330,14 +357,14 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ bind(L_reguard);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, SharedRuntime::reguard_yellow_pages), R0);
|
||||
__ call_c(call_target_address);
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ b(L_after_reguard);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -137,10 +137,10 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address
|
||||
|
||||
// Return unique id for this frame. The id must have a value where we
|
||||
// can distinguish identity and younger/older relationship. null
|
||||
// represents an invalid (incomparable) frame.
|
||||
// represents an invalid (incomparable) frame. Should not be called for heap frames.
|
||||
inline intptr_t* frame::id(void) const {
|
||||
// Use _fp. _sp or _unextended_sp wouldn't be correct due to resizing.
|
||||
return _fp;
|
||||
return real_fp();
|
||||
}
|
||||
|
||||
// Return true if this frame is older (less recent activation) than
|
||||
@ -319,6 +319,9 @@ inline frame frame::sender(RegisterMap* map) const {
|
||||
StackWatermarkSet::on_iteration(map->thread(), result);
|
||||
}
|
||||
|
||||
// Calling frame::id() is currently not supported for heap frames.
|
||||
assert(result._on_heap || this->_on_heap || result.is_older(this->id()), "Must be");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026 SAP SE. 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
|
||||
@ -179,6 +179,11 @@ void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Re
|
||||
__ ld(dst, 0, dst); // Resolve (untagged) jobject.
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
|
||||
// Load the oop from the weak handle.
|
||||
__ ld(obj, 0, obj);
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register tmp) {
|
||||
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
assert_different_registers(tmp, R0);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026 SAP SE. 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
|
||||
@ -70,6 +70,12 @@ public:
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
|
||||
// Can be used in nmethods including native wrappers.
|
||||
// Attention: obj will only be valid until next safepoint (no SATB barrier).
|
||||
// TODO: maybe rename to try_peek_weak_handle on all platforms (try: operation may fail, peek: obj is not kept alive)
|
||||
// (other platforms currently use it for C2 only: try_resolve_weak_handle_in_c2)
|
||||
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
|
||||
virtual void barrier_stubs_init() {}
|
||||
|
||||
virtual NMethodPatchingType nmethod_patching_type() { return NMethodPatchingType::stw_instruction_and_data_patch; }
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2025, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -662,6 +663,31 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
|
||||
__ block_comment("} try_resolve_jobject_in_native (shenandoahgc)");
|
||||
}
|
||||
|
||||
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle(MacroAssembler *masm, Register obj,
|
||||
Register tmp, Label &slow_path) {
|
||||
__ block_comment("try_resolve_weak_handle (shenandoahgc) {");
|
||||
|
||||
assert_different_registers(obj, tmp);
|
||||
|
||||
Label done;
|
||||
|
||||
// Resolve weak handle using the standard implementation.
|
||||
BarrierSetAssembler::try_resolve_weak_handle(masm, obj, tmp, slow_path);
|
||||
|
||||
// Check if the reference is null, and if it is, take the fast path.
|
||||
__ cmpdi(CR0, obj, 0);
|
||||
__ beq(CR0, done);
|
||||
|
||||
// Check if the heap is under weak-reference/roots processing, in
|
||||
// which case we need to take the slow path.
|
||||
__ lbz(tmp, in_bytes(ShenandoahThreadLocalData::gc_state_offset()), R16_thread);
|
||||
__ andi_(tmp, tmp, ShenandoahHeap::WEAK_ROOTS);
|
||||
__ bne(CR0, slow_path);
|
||||
__ bind(done);
|
||||
|
||||
__ block_comment("} try_resolve_weak_handle (shenandoahgc)");
|
||||
}
|
||||
|
||||
// Special shenandoah CAS implementation that handles false negatives due
|
||||
// to concurrent evacuation. That is, the CAS operation is intended to succeed in
|
||||
// the following scenarios (success criteria):
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2022, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -121,6 +122,8 @@ public:
|
||||
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
|
||||
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
};
|
||||
|
||||
#endif // CPU_PPC_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_PPC_HPP
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026 SAP SE. 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
|
||||
@ -627,6 +627,19 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, R
|
||||
__ block_comment("} try_resolve_jobject_in_native (zgc)");
|
||||
}
|
||||
|
||||
void ZBarrierSetAssembler::try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
|
||||
// Resolve weak handle using the standard implementation.
|
||||
BarrierSetAssembler::try_resolve_weak_handle(masm, obj, tmp, slow_path);
|
||||
|
||||
// Check if the oop is bad, in which case we need to take the slow path.
|
||||
__ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatMarkBadMask);
|
||||
__ andi_(R0, obj, barrier_Relocation::unpatched);
|
||||
__ bne(CR0, slow_path);
|
||||
|
||||
// Oop is okay, so we uncolor it.
|
||||
__ srdi(obj, obj, ZPointerLoadShift);
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
#ifdef COMPILER1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2022 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026 SAP SE. 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
|
||||
@ -72,6 +72,8 @@ public:
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
|
||||
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
|
||||
virtual void check_oop(MacroAssembler *masm, Register obj, const char* msg);
|
||||
|
||||
virtual NMethodPatchingType nmethod_patching_type() { return NMethodPatchingType::conc_instruction_and_data_patch; }
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "runtime/icache.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
|
||||
// Use inline assembler to implement icache flush.
|
||||
int ICache::ppc64_flush_icache(address start, int lines, int magic) {
|
||||
@ -67,6 +68,9 @@ int ICache::ppc64_flush_icache(address start, int lines, int magic) {
|
||||
|
||||
void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {
|
||||
|
||||
guarantee(VM_Version::get_icache_line_size() >= ICache::line_size,
|
||||
"processors with smaller cache line size are no longer supported");
|
||||
|
||||
*flush_icache_stub = (ICache::flush_icache_stub_t)ICache::ppc64_flush_icache;
|
||||
|
||||
// First call to flush itself.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -35,9 +35,8 @@ class ICache : public AbstractICache {
|
||||
|
||||
public:
|
||||
enum {
|
||||
// Actually, cache line size is 64, but keeping it as it is to be
|
||||
// on the safe side on ALL PPC64 implementations.
|
||||
log2_line_size = 5,
|
||||
// Cache line size is 128 on all supported PPC64 implementations.
|
||||
log2_line_size = 7,
|
||||
line_size = 1 << log2_line_size
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -258,7 +258,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void profile_not_taken_branch(Register scratch1, Register scratch2);
|
||||
void profile_call(Register scratch1, Register scratch2);
|
||||
void profile_final_call(Register scratch1, Register scratch2);
|
||||
void profile_virtual_call(Register Rreceiver, Register Rscratch1, Register Rscratch2, bool receiver_can_be_null);
|
||||
void profile_virtual_call(Register Rreceiver, Register Rscratch1, Register Rscratch2);
|
||||
void profile_typecheck(Register Rklass, Register Rscratch1, Register Rscratch2);
|
||||
void profile_ret(TosState state, Register return_bci, Register scratch1, Register scratch2);
|
||||
void profile_switch_default(Register scratch1, Register scratch2);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -1340,28 +1340,15 @@ void InterpreterMacroAssembler::profile_final_call(Register scratch1, Register s
|
||||
// Count a virtual call in the bytecodes.
|
||||
void InterpreterMacroAssembler::profile_virtual_call(Register Rreceiver,
|
||||
Register Rscratch1,
|
||||
Register Rscratch2,
|
||||
bool receiver_can_be_null) {
|
||||
Register Rscratch2) {
|
||||
if (!ProfileInterpreter) { return; }
|
||||
Label profile_continue;
|
||||
|
||||
// If no method data exists, go to profile_continue.
|
||||
test_method_data_pointer(profile_continue);
|
||||
|
||||
Label skip_receiver_profile;
|
||||
if (receiver_can_be_null) {
|
||||
Label not_null;
|
||||
cmpdi(CR0, Rreceiver, 0);
|
||||
bne(CR0, not_null);
|
||||
// We are making a call. Increment the count for null receiver.
|
||||
increment_mdp_data_at(in_bytes(CounterData::count_offset()), Rscratch1, Rscratch2);
|
||||
b(skip_receiver_profile);
|
||||
bind(not_null);
|
||||
}
|
||||
|
||||
// Record the receiver type.
|
||||
record_klass_in_profile(Rreceiver, Rscratch1, Rscratch2);
|
||||
bind(skip_receiver_profile);
|
||||
|
||||
// The method data pointer needs to be updated to reflect the new target.
|
||||
update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -42,6 +42,7 @@
|
||||
#include "runtime/icache.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/objectMonitor.hpp"
|
||||
#include "runtime/objectMonitorTable.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
@ -482,7 +483,7 @@ void MacroAssembler::set_dest_of_bc_far_at(address instruction_addr, address des
|
||||
// variant 3, far cond branch to the next instruction, already patched to nops:
|
||||
//
|
||||
// nop
|
||||
// endgroup
|
||||
// nop
|
||||
// SKIP/DEST:
|
||||
//
|
||||
return;
|
||||
@ -499,7 +500,7 @@ void MacroAssembler::set_dest_of_bc_far_at(address instruction_addr, address des
|
||||
if (is_bc_far_variant2_at(instruction_addr) && dest == instruction_addr + 8) {
|
||||
// Far branch to next instruction: Optimize it by patching nops (produce variant 3).
|
||||
masm.nop();
|
||||
masm.endgroup();
|
||||
masm.nop();
|
||||
} else {
|
||||
if (is_bc_far_variant1_at(instruction_addr)) {
|
||||
// variant 1, the 1st instruction contains the destination address:
|
||||
@ -2756,39 +2757,54 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register
|
||||
addi(owner_addr, mark, in_bytes(ObjectMonitor::owner_offset()) - monitor_tag);
|
||||
mark = noreg;
|
||||
} else {
|
||||
const Register tmp3_bucket = tmp3;
|
||||
const Register tmp2_hash = tmp2;
|
||||
Label monitor_found;
|
||||
Register cache_addr = tmp2;
|
||||
|
||||
// Load cache address
|
||||
addi(cache_addr, R16_thread, in_bytes(JavaThread::om_cache_oops_offset()));
|
||||
// Save the mark, we might need it to extract the hash.
|
||||
mr(tmp2_hash, mark);
|
||||
|
||||
const int num_unrolled = 2;
|
||||
// Look for the monitor in the om_cache.
|
||||
|
||||
ByteSize cache_offset = JavaThread::om_cache_oops_offset();
|
||||
ByteSize monitor_offset = OMCache::oop_to_monitor_difference();
|
||||
const int num_unrolled = OMCache::CAPACITY;
|
||||
for (int i = 0; i < num_unrolled; i++) {
|
||||
ld(R0, 0, cache_addr);
|
||||
ld(R0, in_bytes(cache_offset), R16_thread);
|
||||
ld(monitor, in_bytes(cache_offset + monitor_offset), R16_thread);
|
||||
cmpd(CR0, R0, obj);
|
||||
beq(CR0, monitor_found);
|
||||
addi(cache_addr, cache_addr, in_bytes(OMCache::oop_to_oop_difference()));
|
||||
cache_offset = cache_offset + OMCache::oop_to_oop_difference();
|
||||
}
|
||||
|
||||
Label loop;
|
||||
// Look for the monitor in the table.
|
||||
|
||||
// Search for obj in cache.
|
||||
bind(loop);
|
||||
// Get the hash code.
|
||||
srdi(tmp2_hash, tmp2_hash, markWord::hash_shift);
|
||||
|
||||
// Check for match.
|
||||
ld(R0, 0, cache_addr);
|
||||
cmpd(CR0, R0, obj);
|
||||
beq(CR0, monitor_found);
|
||||
// Get the table and calculate the bucket's address
|
||||
int simm16_rest = load_const_optimized(tmp3, ObjectMonitorTable::current_table_address(), R0, true);
|
||||
ld_ptr(tmp3, simm16_rest, tmp3);
|
||||
ld(tmp1, in_bytes(ObjectMonitorTable::table_capacity_mask_offset()), tmp3);
|
||||
andr(tmp2_hash, tmp2_hash, tmp1);
|
||||
ld(tmp3_bucket, in_bytes(ObjectMonitorTable::table_buckets_offset()), tmp3);
|
||||
|
||||
// Search until null encountered, guaranteed _null_sentinel at end.
|
||||
addi(cache_addr, cache_addr, in_bytes(OMCache::oop_to_oop_difference()));
|
||||
cmpdi(CR1, R0, 0);
|
||||
bne(CR1, loop);
|
||||
// Cache Miss, CR0.NE set from cmp above
|
||||
b(slow_path);
|
||||
// Read the monitor from the bucket.
|
||||
sldi(tmp2_hash, tmp2_hash, LogBytesPerWord);
|
||||
ldx(monitor, tmp3_bucket, tmp2_hash);
|
||||
|
||||
// Check if the monitor in the bucket is special (empty, tombstone or removed).
|
||||
cmpldi(CR0, monitor, ObjectMonitorTable::SpecialPointerValues::below_is_special);
|
||||
blt(CR0, slow_path);
|
||||
|
||||
// Check if object matches.
|
||||
ld(tmp3, in_bytes(ObjectMonitor::object_offset()), monitor);
|
||||
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs_asm->try_resolve_weak_handle(this, tmp3, tmp2, slow_path);
|
||||
cmpd(CR0, tmp3, obj);
|
||||
bne(CR0, slow_path);
|
||||
|
||||
bind(monitor_found);
|
||||
ld(monitor, in_bytes(OMCache::oop_to_monitor_difference()), cache_addr);
|
||||
|
||||
// Compute owner address.
|
||||
addi(owner_addr, monitor, in_bytes(ObjectMonitor::owner_offset()));
|
||||
@ -3185,23 +3201,17 @@ Register MacroAssembler::encode_klass_not_null(Register dst, Register src) {
|
||||
|
||||
void MacroAssembler::store_klass(Register dst_oop, Register klass, Register ck) {
|
||||
assert(!UseCompactObjectHeaders, "not with compact headers");
|
||||
if (UseCompressedClassPointers) {
|
||||
Register compressedKlass = encode_klass_not_null(ck, klass);
|
||||
stw(compressedKlass, oopDesc::klass_offset_in_bytes(), dst_oop);
|
||||
} else {
|
||||
std(klass, oopDesc::klass_offset_in_bytes(), dst_oop);
|
||||
}
|
||||
Register compressedKlass = encode_klass_not_null(ck, klass);
|
||||
stw(compressedKlass, oopDesc::klass_offset_in_bytes(), dst_oop);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_klass_gap(Register dst_oop, Register val) {
|
||||
assert(!UseCompactObjectHeaders, "not with compact headers");
|
||||
if (UseCompressedClassPointers) {
|
||||
if (val == noreg) {
|
||||
val = R0;
|
||||
li(val, 0);
|
||||
}
|
||||
stw(val, oopDesc::klass_gap_offset_in_bytes(), dst_oop);
|
||||
if (val == noreg) {
|
||||
val = R0;
|
||||
li(val, 0);
|
||||
}
|
||||
stw(val, oopDesc::klass_gap_offset_in_bytes(), dst_oop);
|
||||
}
|
||||
|
||||
int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
||||
@ -3210,17 +3220,13 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
||||
// Not yet computed?
|
||||
if (computed_size == -1) {
|
||||
|
||||
if (!UseCompressedClassPointers) {
|
||||
computed_size = 0;
|
||||
} else {
|
||||
// Determine by scratch emit.
|
||||
ResourceMark rm;
|
||||
int code_size = 8 * BytesPerInstWord;
|
||||
CodeBuffer cb("decode_klass_not_null scratch buffer", code_size, 0);
|
||||
MacroAssembler* a = new MacroAssembler(&cb);
|
||||
a->decode_klass_not_null(R11_scratch1);
|
||||
computed_size = a->offset();
|
||||
}
|
||||
// Determine by scratch emit.
|
||||
ResourceMark rm;
|
||||
int code_size = 8 * BytesPerInstWord;
|
||||
CodeBuffer cb("decode_klass_not_null scratch buffer", code_size, 0);
|
||||
MacroAssembler* a = new MacroAssembler(&cb);
|
||||
a->decode_klass_not_null(R11_scratch1);
|
||||
computed_size = a->offset();
|
||||
}
|
||||
|
||||
return computed_size;
|
||||
@ -3243,18 +3249,14 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
|
||||
void MacroAssembler::load_klass_no_decode(Register dst, Register src) {
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(dst, src);
|
||||
} else if (UseCompressedClassPointers) {
|
||||
lwz(dst, oopDesc::klass_offset_in_bytes(), src);
|
||||
} else {
|
||||
ld(dst, oopDesc::klass_offset_in_bytes(), src);
|
||||
lwz(dst, oopDesc::klass_offset_in_bytes(), src);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
load_klass_no_decode(dst, src);
|
||||
if (UseCompressedClassPointers) { // also true for UseCompactObjectHeaders
|
||||
decode_klass_not_null(dst);
|
||||
}
|
||||
decode_klass_not_null(dst);
|
||||
}
|
||||
|
||||
// Loads the obj's Klass* into dst.
|
||||
@ -3270,18 +3272,13 @@ void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
|
||||
|
||||
void MacroAssembler::cmp_klass(ConditionRegister dst, Register obj, Register klass, Register tmp, Register tmp2) {
|
||||
assert_different_registers(obj, klass, tmp);
|
||||
if (UseCompressedClassPointers) {
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(tmp, obj);
|
||||
} else {
|
||||
lwz(tmp, oopDesc::klass_offset_in_bytes(), obj);
|
||||
}
|
||||
Register encoded_klass = encode_klass_not_null(tmp2, klass);
|
||||
cmpw(dst, tmp, encoded_klass);
|
||||
if (UseCompactObjectHeaders) {
|
||||
load_narrow_klass_compact(tmp, obj);
|
||||
} else {
|
||||
ld(tmp, oopDesc::klass_offset_in_bytes(), obj);
|
||||
cmpd(dst, tmp, klass);
|
||||
lwz(tmp, oopDesc::klass_offset_in_bytes(), obj);
|
||||
}
|
||||
Register encoded_klass = encode_klass_not_null(tmp2, klass);
|
||||
cmpw(dst, tmp, encoded_klass);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_klasses_from_objects(ConditionRegister dst, Register obj1, Register obj2, Register tmp1, Register tmp2) {
|
||||
@ -3289,14 +3286,10 @@ void MacroAssembler::cmp_klasses_from_objects(ConditionRegister dst, Register ob
|
||||
load_narrow_klass_compact(tmp1, obj1);
|
||||
load_narrow_klass_compact(tmp2, obj2);
|
||||
cmpw(dst, tmp1, tmp2);
|
||||
} else if (UseCompressedClassPointers) {
|
||||
} else {
|
||||
lwz(tmp1, oopDesc::klass_offset_in_bytes(), obj1);
|
||||
lwz(tmp2, oopDesc::klass_offset_in_bytes(), obj2);
|
||||
cmpw(dst, tmp1, tmp2);
|
||||
} else {
|
||||
ld(tmp1, oopDesc::klass_offset_in_bytes(), obj1);
|
||||
ld(tmp2, oopDesc::klass_offset_in_bytes(), obj2);
|
||||
cmpd(dst, tmp1, tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -70,14 +70,6 @@ class MacroAssembler: public Assembler {
|
||||
// Move register if destination register and target register are different
|
||||
inline void mr_if_needed(Register rd, Register rs, bool allow_invalid = false);
|
||||
inline void fmr_if_needed(FloatRegister rd, FloatRegister rs);
|
||||
// This is dedicated for emitting scheduled mach nodes. For better
|
||||
// readability of the ad file I put it here.
|
||||
// Endgroups are not needed if
|
||||
// - the scheduler is off
|
||||
// - the scheduler found that there is a natural group end, in that
|
||||
// case it reduced the size of the instruction used in the test
|
||||
// yielding 'needed'.
|
||||
inline void endgroup_if_needed(bool needed);
|
||||
|
||||
// Memory barriers.
|
||||
inline void membar(int bits);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -72,11 +72,6 @@ inline void MacroAssembler::mr_if_needed(Register rd, Register rs, bool allow_no
|
||||
inline void MacroAssembler::fmr_if_needed(FloatRegister rd, FloatRegister rs) {
|
||||
if (rs != rd) fmr(rd, rs);
|
||||
}
|
||||
inline void MacroAssembler::endgroup_if_needed(bool needed) {
|
||||
if (needed) {
|
||||
endgroup();
|
||||
}
|
||||
}
|
||||
|
||||
inline void MacroAssembler::membar(int bits) {
|
||||
// Comment: Usage of elemental_membar(bits) is not recommended for Power 8.
|
||||
@ -240,13 +235,13 @@ inline bool MacroAssembler::is_bc_far_variant3_at(address instruction_addr) {
|
||||
// Variant 3, far cond branch to the next instruction, already patched to nops:
|
||||
//
|
||||
// nop
|
||||
// endgroup
|
||||
// nop
|
||||
// SKIP/DEST:
|
||||
//
|
||||
const int instruction_1 = *(int*)(instruction_addr);
|
||||
const int instruction_2 = *(int*)(instruction_addr + 4);
|
||||
return is_nop(instruction_1) &&
|
||||
is_endgroup(instruction_2);
|
||||
is_nop(instruction_2);
|
||||
}
|
||||
|
||||
// set dst to -1, 0, +1 as follows: if CR0bi is "greater than", dst is set to 1,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2026 SAP SE. 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
|
||||
@ -86,7 +87,6 @@
|
||||
|
||||
static bool narrow_klass_use_complex_address() {
|
||||
NOT_LP64(ShouldNotCallThis());
|
||||
assert(UseCompressedClassPointers, "only for compressed klass code");
|
||||
// TODO: PPC port if (MatchDecodeNodes) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -49,11 +49,6 @@
|
||||
|
||||
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
|
||||
|
||||
// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
|
||||
inline static RegisterOrConstant constant(int value) {
|
||||
return RegisterOrConstant(value);
|
||||
}
|
||||
|
||||
void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg,
|
||||
Register temp_reg, Register temp2_reg) {
|
||||
if (VerifyMethodHandles) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
// Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -2234,6 +2234,12 @@ bool Matcher::match_rule_supported(int opcode) {
|
||||
case Op_FmaVD:
|
||||
return (SuperwordUseVSX && UseFMA);
|
||||
|
||||
case Op_MinF:
|
||||
case Op_MaxF:
|
||||
case Op_MinD:
|
||||
case Op_MaxD:
|
||||
return (PowerArchitecturePPC64 >= 9);
|
||||
|
||||
case Op_Digit:
|
||||
return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit);
|
||||
case Op_LowerCase:
|
||||
@ -2406,10 +2412,8 @@ bool Matcher::is_generic_vector(MachOper* opnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return whether or not this register is ever used as an argument. This
|
||||
// function is used on startup to build the trampoline stubs in generateOptoStub.
|
||||
// Registers not mentioned will be killed by the VM call in the trampoline, and
|
||||
// arguments in those registers not be available to the callee.
|
||||
#ifdef ASSERT
|
||||
// Return whether or not this register is ever used as an argument.
|
||||
bool Matcher::can_be_java_arg(int reg) {
|
||||
// We must include the virtual halves in order to get STDs and LDs
|
||||
// instead of STWs and LWs in the trampoline stubs.
|
||||
@ -2441,10 +2445,7 @@ bool Matcher::can_be_java_arg(int reg) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Matcher::is_spillable_arg(int reg) {
|
||||
return can_be_java_arg(reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint Matcher::int_pressure_limit()
|
||||
{
|
||||
@ -2456,10 +2457,6 @@ uint Matcher::float_pressure_limit()
|
||||
return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE;
|
||||
}
|
||||
|
||||
bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register for DIVI projection of divmodI.
|
||||
const RegMask& Matcher::divI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
@ -3709,13 +3706,6 @@ frame %{
|
||||
// Compiled code's Frame Pointer.
|
||||
frame_pointer(R1); // R1_SP
|
||||
|
||||
// Interpreter stores its frame pointer in a register which is
|
||||
// stored to the stack by I2CAdaptors. I2CAdaptors convert from
|
||||
// interpreted java to compiled java.
|
||||
//
|
||||
// R14_state holds pointer to caller's cInterpreter.
|
||||
interpreter_frame_pointer(R14); // R14_state
|
||||
|
||||
stack_alignment(frame::alignment_in_bytes);
|
||||
|
||||
// Number of outgoing stack slots killed above the
|
||||
@ -6333,36 +6323,8 @@ instruct loadConD_Ex(regD dst, immD src) %{
|
||||
// Prefetch instructions.
|
||||
// Must be safe to execute with invalid address (cannot fault).
|
||||
|
||||
// Special prefetch versions which use the dcbz instruction.
|
||||
instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
|
||||
match(PrefetchAllocation (AddP mem src));
|
||||
predicate(AllocatePrefetchStyle == 3);
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ dcbz($src$$Register, $mem$$base$$Register);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
|
||||
match(PrefetchAllocation mem);
|
||||
predicate(AllocatePrefetchStyle == 3);
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ dcbz($mem$$base$$Register);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
|
||||
match(PrefetchAllocation (AddP mem src));
|
||||
predicate(AllocatePrefetchStyle != 3);
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
|
||||
@ -6375,7 +6337,6 @@ instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
|
||||
|
||||
instruct prefetch_alloc_no_offset(indirectMemory mem) %{
|
||||
match(PrefetchAllocation mem);
|
||||
predicate(AllocatePrefetchStyle != 3);
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
|
||||
@ -7169,6 +7130,18 @@ instruct membar_release_lock() %{
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct membar_storeload() %{
|
||||
match(MemBarStoreLoad);
|
||||
ins_cost(4*MEMORY_REF_COST);
|
||||
|
||||
format %{ "MEMBAR-store-load" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ fence();
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct membar_volatile() %{
|
||||
match(MemBarVolatile);
|
||||
ins_cost(4*MEMORY_REF_COST);
|
||||
@ -7211,6 +7184,18 @@ instruct membar_volatile() %{
|
||||
// ins_pipe(pipe_class_default);
|
||||
//%}
|
||||
|
||||
instruct membar_full() %{
|
||||
match(MemBarFull);
|
||||
ins_cost(4*MEMORY_REF_COST);
|
||||
|
||||
format %{ "MEMBAR-full" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ fence();
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct membar_CPUOrder() %{
|
||||
match(MemBarCPUOrder);
|
||||
ins_cost(0);
|
||||
@ -10318,7 +10303,7 @@ instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
|
||||
|
||||
ins_variable_size_depending_on_alignment(true);
|
||||
|
||||
format %{ "cmovI $crx, $dst, $src" %}
|
||||
format %{ "CMOVI $crx, $dst, $src" %}
|
||||
size(8);
|
||||
ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
|
||||
ins_pipe(pipe_class_default);
|
||||
@ -10331,7 +10316,7 @@ instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
|
||||
|
||||
ins_variable_size_depending_on_alignment(true);
|
||||
|
||||
format %{ "cmovI $crx, $dst, $src" %}
|
||||
format %{ "CMOVI $crx, $dst, $src" %}
|
||||
size(8);
|
||||
ins_encode( enc_cmove_bso_reg(dst, crx, src) );
|
||||
ins_pipe(pipe_class_default);
|
||||
@ -10343,7 +10328,7 @@ instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
|
||||
effect(DEF dst, USE crx, USE src);
|
||||
predicate(false);
|
||||
|
||||
format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %}
|
||||
format %{ "CMOVI $dst, $crx, $src \t// postalloc expanded" %}
|
||||
postalloc_expand %{
|
||||
//
|
||||
// replaces
|
||||
@ -10493,7 +10478,7 @@ instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
|
||||
|
||||
ins_variable_size_depending_on_alignment(true);
|
||||
|
||||
format %{ "cmovL $crx, $dst, $src" %}
|
||||
format %{ "CMOVL $crx, $dst, $src" %}
|
||||
size(8);
|
||||
ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
|
||||
ins_pipe(pipe_class_default);
|
||||
@ -10506,7 +10491,7 @@ instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
|
||||
|
||||
ins_variable_size_depending_on_alignment(true);
|
||||
|
||||
format %{ "cmovL $crx, $dst, $src" %}
|
||||
format %{ "CMOVL $crx, $dst, $src" %}
|
||||
size(8);
|
||||
ins_encode( enc_cmove_bso_reg(dst, crx, src) );
|
||||
ins_pipe(pipe_class_default);
|
||||
@ -10518,7 +10503,7 @@ instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
|
||||
effect(DEF dst, USE crx, USE src);
|
||||
predicate(false);
|
||||
|
||||
format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %}
|
||||
format %{ "CMOVL $dst, $crx, $src \t// postalloc expanded" %}
|
||||
postalloc_expand %{
|
||||
//
|
||||
// replaces
|
||||
@ -10719,9 +10704,9 @@ instruct convF2HF_reg_reg(iRegIdst dst, regF src, regF tmp) %{
|
||||
effect(TEMP tmp);
|
||||
ins_cost(3 * DEFAULT_COST);
|
||||
size(12);
|
||||
format %{ "xscvdphp $tmp, $src\t# convert to half precision\n\t"
|
||||
"mffprd $dst, $tmp\t# move result from $tmp to $dst\n\t"
|
||||
"extsh $dst, $dst\t# make it a proper short"
|
||||
format %{ "XSCVDPHP $tmp, $src\t# convert to half precision\n\t"
|
||||
"MFFPRD $dst, $tmp\t# move result from $tmp to $dst\n\t"
|
||||
"EXTSH $dst, $dst\t# make it a proper short"
|
||||
%}
|
||||
ins_encode %{
|
||||
__ f2hf($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
|
||||
@ -10733,8 +10718,8 @@ instruct convHF2F_reg_reg(regF dst, iRegIsrc src) %{
|
||||
match(Set dst (ConvHF2F src));
|
||||
ins_cost(2 * DEFAULT_COST);
|
||||
size(8);
|
||||
format %{ "mtfprd $dst, $src\t# move source from $src to $dst\n\t"
|
||||
"xscvhpdp $dst, $dst\t# convert from half precision"
|
||||
format %{ "MTFPRD $dst, $src\t# move source from $src to $dst\n\t"
|
||||
"XSCVHPDP $dst, $dst\t# convert from half precision"
|
||||
%}
|
||||
ins_encode %{
|
||||
__ hf2f($dst$$FloatRegister, $src$$Register);
|
||||
@ -11132,7 +11117,7 @@ instruct cmov_bns_less(flagsReg crx) %{
|
||||
|
||||
ins_variable_size_depending_on_alignment(true);
|
||||
|
||||
format %{ "cmov $crx" %}
|
||||
format %{ "CMOV $crx" %}
|
||||
size(12);
|
||||
ins_encode %{
|
||||
Label done;
|
||||
@ -11160,7 +11145,7 @@ instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
|
||||
match(Set crx (CmpF src1 src2));
|
||||
ins_cost(DEFAULT_COST+BRANCH_COST);
|
||||
|
||||
format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %}
|
||||
format %{ "CMPF $crx, $src1, $src2 \t// postalloc expanded" %}
|
||||
postalloc_expand %{
|
||||
//
|
||||
// replaces
|
||||
@ -12313,6 +12298,58 @@ instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct minF(regF dst, regF src1, regF src2) %{
|
||||
match(Set dst (MinF src1 src2));
|
||||
predicate(PowerArchitecturePPC64 >= 9);
|
||||
ins_cost(DEFAULT_COST);
|
||||
|
||||
format %{ "XSMINJDP $dst, $src1, $src2\t// MinF" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct minD(regD dst, regD src1, regD src2) %{
|
||||
match(Set dst (MinD src1 src2));
|
||||
predicate(PowerArchitecturePPC64 >= 9);
|
||||
ins_cost(DEFAULT_COST);
|
||||
|
||||
format %{ "XSMINJDP $dst, $src1, $src2\t// MinD" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ xsminjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct maxF(regF dst, regF src1, regF src2) %{
|
||||
match(Set dst (MaxF src1 src2));
|
||||
predicate(PowerArchitecturePPC64 >= 9);
|
||||
ins_cost(DEFAULT_COST);
|
||||
|
||||
format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxF" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct maxD(regD dst, regD src1, regD src2) %{
|
||||
match(Set dst (MaxD src1 src2));
|
||||
predicate(PowerArchitecturePPC64 >= 9);
|
||||
ins_cost(DEFAULT_COST);
|
||||
|
||||
format %{ "XSMAXJDP $dst, $src1, $src2\t// MaxD" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ xsmaxjdp($dst$$FloatRegister->to_vsr(), $src1$$FloatRegister->to_vsr(), $src2$$FloatRegister->to_vsr());
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
//---------- Population Count Instructions ------------------------------------
|
||||
|
||||
instruct popCountI(iRegIdst dst, iRegIsrc src) %{
|
||||
@ -13835,7 +13872,7 @@ instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{
|
||||
instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
|
||||
match(Set cr0 (OverflowAddL op1 op2));
|
||||
|
||||
format %{ "add_ $op1, $op2\t# overflow check long" %}
|
||||
format %{ "ADD_ $op1, $op2\t# overflow check long" %}
|
||||
size(12);
|
||||
ins_encode %{
|
||||
__ li(R0, 0);
|
||||
@ -13848,7 +13885,7 @@ instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
|
||||
instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
|
||||
match(Set cr0 (OverflowSubL op1 op2));
|
||||
|
||||
format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %}
|
||||
format %{ "SUBFO_ R0, $op2, $op1\t# overflow check long" %}
|
||||
size(12);
|
||||
ins_encode %{
|
||||
__ li(R0, 0);
|
||||
@ -13861,7 +13898,7 @@ instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
|
||||
instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
|
||||
match(Set cr0 (OverflowSubL zero op2));
|
||||
|
||||
format %{ "nego_ R0, $op2\t# overflow check long" %}
|
||||
format %{ "NEGO_ R0, $op2\t# overflow check long" %}
|
||||
size(12);
|
||||
ins_encode %{
|
||||
__ li(R0, 0);
|
||||
@ -13874,7 +13911,7 @@ instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
|
||||
instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
|
||||
match(Set cr0 (OverflowMulL op1 op2));
|
||||
|
||||
format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %}
|
||||
format %{ "MULLDO_ R0, $op1, $op2\t# overflow check long" %}
|
||||
size(12);
|
||||
ins_encode %{
|
||||
__ li(R0, 0);
|
||||
@ -14251,7 +14288,7 @@ instruct ForwardExceptionjmp()
|
||||
match(ForwardException);
|
||||
ins_cost(CALL_COST);
|
||||
|
||||
format %{ "Jmp forward_exception_stub" %}
|
||||
format %{ "JMP forward_exception_stub" %}
|
||||
ins_encode %{
|
||||
__ set_inst_mark();
|
||||
__ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
|
||||
@ -14279,7 +14316,7 @@ instruct RethrowException() %{
|
||||
match(Rethrow);
|
||||
ins_cost(CALL_COST);
|
||||
|
||||
format %{ "Jmp rethrow_stub" %}
|
||||
format %{ "JMP rethrow_stub" %}
|
||||
ins_encode %{
|
||||
__ set_inst_mark();
|
||||
__ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
|
||||
@ -14321,20 +14358,6 @@ instruct tlsLoadP(threadRegP dst) %{
|
||||
|
||||
//---Some PPC specific nodes---------------------------------------------------
|
||||
|
||||
// Stop a group.
|
||||
instruct endGroup() %{
|
||||
ins_cost(0);
|
||||
|
||||
ins_is_nop(true);
|
||||
|
||||
format %{ "End Bundle (ori r1, r1, 0)" %}
|
||||
size(4);
|
||||
ins_encode %{
|
||||
__ endgroup();
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// Nop instructions
|
||||
|
||||
instruct fxNop() %{
|
||||
|
||||
@ -3489,7 +3489,7 @@ void TemplateTable::invokevirtual(int byte_no) {
|
||||
// Get receiver klass.
|
||||
__ load_klass_check_null_throw(Rrecv_klass, Rrecv, R11_scratch1);
|
||||
__ verify_klass_ptr(Rrecv_klass);
|
||||
__ profile_virtual_call(Rrecv_klass, R11_scratch1, R12_scratch2, false);
|
||||
__ profile_virtual_call(Rrecv_klass, R11_scratch1, R12_scratch2);
|
||||
|
||||
generate_vtable_call(Rrecv_klass, Rvtableindex_or_method, Rret_addr, R11_scratch1);
|
||||
}
|
||||
@ -3596,7 +3596,7 @@ void TemplateTable::invokeinterface_object_method(Register Rrecv_klass,
|
||||
// Non-final callc case.
|
||||
__ bind(LnotFinal);
|
||||
__ lhz(Rindex, in_bytes(ResolvedMethodEntry::table_index_offset()), Rcache);
|
||||
__ profile_virtual_call(Rrecv_klass, Rtemp1, Rscratch, false);
|
||||
__ profile_virtual_call(Rrecv_klass, Rtemp1, Rscratch);
|
||||
generate_vtable_call(Rrecv_klass, Rindex, Rret, Rscratch);
|
||||
}
|
||||
|
||||
@ -3664,7 +3664,7 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
__ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
|
||||
L_no_such_interface, /*return_method=*/false);
|
||||
|
||||
__ profile_virtual_call(Rrecv_klass, Rscratch1, Rscratch2, false);
|
||||
__ profile_virtual_call(Rrecv_klass, Rscratch1, Rscratch2);
|
||||
|
||||
// Find entry point to call.
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -475,19 +475,12 @@ void VM_Version::print_features() {
|
||||
|
||||
void VM_Version::determine_features() {
|
||||
#if defined(ABI_ELFv2)
|
||||
// 1 InstWord per call for the blr instruction.
|
||||
const int code_size = (num_features+1+2*1)*BytesPerInstWord;
|
||||
const int code_size = (num_features + 1 /*blr*/) * BytesPerInstWord;
|
||||
#else
|
||||
// 7 InstWords for each call (function descriptor + blr instruction).
|
||||
const int code_size = (num_features+1+2*7)*BytesPerInstWord;
|
||||
const int code_size = (num_features + 1 /*blr*/ + 6 /* fd */) * BytesPerInstWord;
|
||||
#endif
|
||||
int features = 0;
|
||||
|
||||
// create test area
|
||||
enum { BUFFER_SIZE = 2*4*K }; // Needs to be >=2* max cache line size (cache line size can't exceed min page size).
|
||||
char test_area[BUFFER_SIZE];
|
||||
char *mid_of_test_area = &test_area[BUFFER_SIZE>>1];
|
||||
|
||||
// Allocate space for the code.
|
||||
ResourceMark rm;
|
||||
CodeBuffer cb("detect_cpu_features", code_size, 0);
|
||||
@ -497,20 +490,13 @@ void VM_Version::determine_features() {
|
||||
_features = VM_Version::all_features_m;
|
||||
|
||||
// Emit code.
|
||||
void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->function_entry();
|
||||
void (*test)() = (void(*)())(void *)a->function_entry();
|
||||
uint32_t *code = (uint32_t *)a->pc();
|
||||
// Keep R3_ARG1 unmodified, it contains &field (see below).
|
||||
// Keep R4_ARG2 unmodified, it contains offset = 0 (see below).
|
||||
a->mfdscr(R0);
|
||||
a->darn(R7);
|
||||
a->brw(R5, R6);
|
||||
a->blr();
|
||||
|
||||
// Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
|
||||
void (*zero_cacheline_func_ptr)(char*) = (void(*)(char*))(void *)a->function_entry();
|
||||
a->dcbz(R3_ARG1); // R3_ARG1 = addr
|
||||
a->blr();
|
||||
|
||||
uint32_t *code_end = (uint32_t *)a->pc();
|
||||
a->flush();
|
||||
_features = VM_Version::unknown_m;
|
||||
@ -522,18 +508,9 @@ void VM_Version::determine_features() {
|
||||
Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
|
||||
}
|
||||
|
||||
// Measure cache line size.
|
||||
memset(test_area, 0xFF, BUFFER_SIZE); // Fill test area with 0xFF.
|
||||
(*zero_cacheline_func_ptr)(mid_of_test_area); // Call function which executes dcbz to the middle.
|
||||
int count = 0; // count zeroed bytes
|
||||
for (int i = 0; i < BUFFER_SIZE; i++) if (test_area[i] == 0) count++;
|
||||
guarantee(is_power_of_2(count), "cache line size needs to be a power of 2");
|
||||
_L1_data_cache_line_size = count;
|
||||
|
||||
// Execute code. Illegal instructions will be replaced by 0 in the signal handler.
|
||||
VM_Version::_is_determine_features_test_running = true;
|
||||
// We must align the first argument to 16 bytes because of the lqarx check.
|
||||
(*test)(align_up((address)mid_of_test_area, 16), 0);
|
||||
(*test)();
|
||||
VM_Version::_is_determine_features_test_running = false;
|
||||
|
||||
// determine which instructions are legal.
|
||||
@ -550,6 +527,10 @@ void VM_Version::determine_features() {
|
||||
}
|
||||
|
||||
_features = features;
|
||||
|
||||
_L1_data_cache_line_size = VM_Version::get_dcache_line_size();
|
||||
assert(_L1_data_cache_line_size >= DEFAULT_CACHE_LINE_SIZE,
|
||||
"processors with smaller cache line size are no longer supported");
|
||||
}
|
||||
|
||||
// Power 8: Configure Data Stream Control Register.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. 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
|
||||
@ -81,6 +81,9 @@ public:
|
||||
static uint64_t _dscr_val;
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
static int get_dcache_line_size();
|
||||
static int get_icache_line_size();
|
||||
};
|
||||
|
||||
#endif // CPU_PPC_VM_VERSION_PPC_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -196,12 +196,9 @@ void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Registe
|
||||
if (UseCompactObjectHeaders) {
|
||||
__ load_narrow_klass_compact(tmp, src);
|
||||
__ load_narrow_klass_compact(t0, dst);
|
||||
} else if (UseCompressedClassPointers) {
|
||||
} else {
|
||||
__ lwu(tmp, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
__ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
|
||||
} else {
|
||||
__ ld(tmp, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
__ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
__ bne(tmp, t0, *stub->entry(), /* is_far */ true);
|
||||
} else {
|
||||
@ -257,9 +254,7 @@ void LIR_Assembler::arraycopy_assert(Register src, Register dst, Register tmp, c
|
||||
// but not necessarily exactly of type default_type.
|
||||
Label known_ok, halt;
|
||||
__ mov_metadata(tmp, default_type->constant_encoding());
|
||||
if (UseCompressedClassPointers) {
|
||||
__ encode_klass_not_null(tmp);
|
||||
}
|
||||
__ encode_klass_not_null(tmp);
|
||||
|
||||
if (basic_type != T_OBJECT) {
|
||||
__ cmp_klass_compressed(dst, tmp, t0, halt, false);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -55,20 +55,6 @@ const Register SHIFT_count = x10; // where count for shift operations must be
|
||||
|
||||
#define __ _masm->
|
||||
|
||||
static void select_different_registers(Register preserve,
|
||||
Register extra,
|
||||
Register &tmp1,
|
||||
Register &tmp2) {
|
||||
if (tmp1 == preserve) {
|
||||
assert_different_registers(tmp1, tmp2, extra);
|
||||
tmp1 = extra;
|
||||
} else if (tmp2 == preserve) {
|
||||
assert_different_registers(tmp1, tmp2, extra);
|
||||
tmp2 = extra;
|
||||
}
|
||||
assert_different_registers(preserve, tmp1, tmp2);
|
||||
}
|
||||
|
||||
static void select_different_registers(Register preserve,
|
||||
Register extra,
|
||||
Register &tmp1,
|
||||
@ -1155,12 +1141,8 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
|
||||
} else if (obj == klass_RInfo) {
|
||||
klass_RInfo = dst;
|
||||
}
|
||||
if (k->is_loaded() && !UseCompressedClassPointers) {
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo);
|
||||
} else {
|
||||
Rtmp1 = op->tmp3()->as_register();
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
|
||||
}
|
||||
Rtmp1 = op->tmp3()->as_register();
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
|
||||
|
||||
assert_different_registers(obj, k_RInfo, klass_RInfo);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -1073,9 +1073,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
|
||||
}
|
||||
LIR_Opr reg = rlock_result(x);
|
||||
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
|
||||
if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
|
||||
tmp3 = new_register(objectType);
|
||||
}
|
||||
tmp3 = new_register(objectType);
|
||||
__ checkcast(reg, obj.result(), x->klass(),
|
||||
new_register(objectType), new_register(objectType), tmp3,
|
||||
x->direct_compare(), info_for_exception, patching_info, stub,
|
||||
@ -1094,9 +1092,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
|
||||
}
|
||||
obj.load_item();
|
||||
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
|
||||
if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
|
||||
tmp3 = new_register(objectType);
|
||||
}
|
||||
tmp3 = new_register(objectType);
|
||||
__ instanceof(reg, obj.result(), x->klass(),
|
||||
new_register(objectType), new_register(objectType), tmp3,
|
||||
x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -92,12 +92,8 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
||||
// This assumes that all prototype bits fitr in an int32_t
|
||||
mv(tmp1, checked_cast<int32_t>(markWord::prototype().value()));
|
||||
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
|
||||
if (UseCompressedClassPointers) { // Take care not to kill klass
|
||||
encode_klass_not_null(tmp1, klass, tmp2);
|
||||
sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
} else {
|
||||
sd(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
encode_klass_not_null(tmp1, klass, tmp2);
|
||||
sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
|
||||
if (len->is_valid()) {
|
||||
@ -108,7 +104,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
||||
// Clear gap/first 4 bytes following the length field.
|
||||
sw(zr, Address(obj, base_offset));
|
||||
}
|
||||
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
|
||||
} else if (!UseCompactObjectHeaders) {
|
||||
store_klass_gap(obj, zr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,6 @@ define_pd_global(bool, TieredCompilation, false);
|
||||
define_pd_global(intx, CompileThreshold, 1500 );
|
||||
|
||||
define_pd_global(intx, OnStackReplacePercentage, 933 );
|
||||
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
|
||||
define_pd_global(size_t, InitialCodeCacheSize, 160*K);
|
||||
define_pd_global(size_t, ReservedCodeCacheSize, 32*M );
|
||||
define_pd_global(size_t, NonProfiledCodeHeapSize, 13*M );
|
||||
@ -52,7 +51,6 @@ define_pd_global(bool, ProfileInterpreter, false);
|
||||
define_pd_global(size_t, CodeCacheExpansionSize, 32*K );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 1);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, true );
|
||||
define_pd_global(bool, CICompileOSR, true );
|
||||
#endif // !COMPILER2
|
||||
define_pd_global(bool, UseTypeProfile, false);
|
||||
|
||||
@ -30,7 +30,9 @@
|
||||
#include "opto/intrinsicnode.hpp"
|
||||
#include "opto/output.hpp"
|
||||
#include "opto/subnode.hpp"
|
||||
#include "runtime/objectMonitorTable.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/synchronizer.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#ifdef PRODUCT
|
||||
@ -123,35 +125,52 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box,
|
||||
if (!UseObjectMonitorTable) {
|
||||
assert(tmp1_monitor == tmp1_mark, "should be the same here");
|
||||
} else {
|
||||
const Register tmp2_hash = tmp2;
|
||||
const Register tmp3_bucket = tmp3;
|
||||
Label monitor_found;
|
||||
|
||||
// Load cache address
|
||||
la(tmp3_t, Address(xthread, JavaThread::om_cache_oops_offset()));
|
||||
// Save the mark, we might need it to extract the hash.
|
||||
mv(tmp2_hash, tmp1_mark);
|
||||
|
||||
const int num_unrolled = 2;
|
||||
// Look for the monitor in the om_cache.
|
||||
|
||||
ByteSize cache_offset = JavaThread::om_cache_oops_offset();
|
||||
ByteSize monitor_offset = OMCache::oop_to_monitor_difference();
|
||||
const int num_unrolled = OMCache::CAPACITY;
|
||||
for (int i = 0; i < num_unrolled; i++) {
|
||||
ld(tmp1, Address(tmp3_t));
|
||||
beq(obj, tmp1, monitor_found);
|
||||
add(tmp3_t, tmp3_t, in_bytes(OMCache::oop_to_oop_difference()));
|
||||
ld(tmp1_monitor, Address(xthread, cache_offset + monitor_offset));
|
||||
ld(tmp4, Address(xthread, cache_offset));
|
||||
beq(obj, tmp4, monitor_found);
|
||||
cache_offset = cache_offset + OMCache::oop_to_oop_difference();
|
||||
}
|
||||
|
||||
Label loop;
|
||||
// Look for the monitor in the table.
|
||||
|
||||
// Search for obj in cache.
|
||||
bind(loop);
|
||||
// Get the hash code.
|
||||
srli(tmp2_hash, tmp2_hash, markWord::hash_shift);
|
||||
|
||||
// Check for match.
|
||||
ld(tmp1, Address(tmp3_t));
|
||||
beq(obj, tmp1, monitor_found);
|
||||
// Get the table and calculate the bucket's address.
|
||||
la(tmp3_t, ExternalAddress(ObjectMonitorTable::current_table_address()));
|
||||
ld(tmp3_t, Address(tmp3_t));
|
||||
ld(tmp1, Address(tmp3_t, ObjectMonitorTable::table_capacity_mask_offset()));
|
||||
andr(tmp2_hash, tmp2_hash, tmp1);
|
||||
ld(tmp3_t, Address(tmp3_t, ObjectMonitorTable::table_buckets_offset()));
|
||||
|
||||
// Search until null encountered, guaranteed _null_sentinel at end.
|
||||
add(tmp3_t, tmp3_t, in_bytes(OMCache::oop_to_oop_difference()));
|
||||
bnez(tmp1, loop);
|
||||
// Cache Miss. Take the slowpath.
|
||||
j(slow_path);
|
||||
// Read the monitor from the bucket.
|
||||
shadd(tmp3_bucket, tmp2_hash, tmp3_t, tmp4, LogBytesPerWord);
|
||||
ld(tmp1_monitor, Address(tmp3_bucket));
|
||||
|
||||
// Check if the monitor in the bucket is special (empty, tombstone or removed).
|
||||
mv(tmp2, ObjectMonitorTable::SpecialPointerValues::below_is_special);
|
||||
bltu(tmp1_monitor, tmp2, slow_path);
|
||||
|
||||
// Check if object matches.
|
||||
ld(tmp3, Address(tmp1_monitor, ObjectMonitor::object_offset()));
|
||||
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs_asm->try_resolve_weak_handle_in_c2(this, tmp3, tmp2, slow_path);
|
||||
bne(tmp3, obj, slow_path);
|
||||
|
||||
bind(monitor_found);
|
||||
ld(tmp1_monitor, Address(tmp3_t, OMCache::oop_to_monitor_difference()));
|
||||
}
|
||||
|
||||
const Register tmp2_owner_addr = tmp2;
|
||||
@ -1156,8 +1175,7 @@ void C2_MacroAssembler::string_compare_long_same_encoding(Register result, Regis
|
||||
Label TAIL_CHECK, TAIL, NEXT_WORD, DIFFERENCE;
|
||||
|
||||
const int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 :
|
||||
(UseCompressedClassPointers ? 8 : 4))) == 0, "Must be");
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 : 8)) == 0, "Must be");
|
||||
|
||||
const int minCharsInWord = isLL ? wordSize : wordSize / 2;
|
||||
|
||||
@ -1250,8 +1268,7 @@ void C2_MacroAssembler::string_compare_long_different_encoding(Register result,
|
||||
Label TAIL, NEXT_WORD, DIFFERENCE;
|
||||
|
||||
const int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 :
|
||||
(UseCompressedClassPointers ? 8 : 4))) == 0, "Must be");
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 : 8)) == 0, "Must be");
|
||||
|
||||
Register strL = isLU ? str1 : str2;
|
||||
Register strU = isLU ? str2 : str1;
|
||||
@ -1466,8 +1483,7 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2,
|
||||
int length_offset = arrayOopDesc::length_offset_in_bytes();
|
||||
int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);
|
||||
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 :
|
||||
(UseCompressedClassPointers ? 8 : 4))) == 0, "Must be");
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 : 8)) == 0, "Must be");
|
||||
|
||||
Register cnt1 = tmp3;
|
||||
Register cnt2 = tmp1; // cnt2 only used in array length compare
|
||||
@ -1592,8 +1608,7 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
|
||||
int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
|
||||
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 :
|
||||
(UseCompressedClassPointers ? 8 : 4))) == 0, "Must be");
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 : 8)) == 0, "Must be");
|
||||
|
||||
BLOCK_COMMENT("string_equals {");
|
||||
|
||||
@ -2680,8 +2695,7 @@ void C2_MacroAssembler::arrays_equals_v(Register a1, Register a2, Register resul
|
||||
int length_offset = arrayOopDesc::length_offset_in_bytes();
|
||||
int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);
|
||||
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 :
|
||||
(UseCompressedClassPointers ? 8 : 4))) == 0, "Must be");
|
||||
assert((base_offset % (UseCompactObjectHeaders ? 4 : 8)) == 0, "Must be");
|
||||
|
||||
BLOCK_COMMENT("arrays_equals_v {");
|
||||
|
||||
|
||||
@ -47,7 +47,6 @@ define_pd_global(intx, ConditionalMoveLimit, 3);
|
||||
define_pd_global(intx, FreqInlineSize, 325);
|
||||
define_pd_global(intx, MinJumpTableSize, 10);
|
||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||
@ -75,9 +74,6 @@ define_pd_global(size_t, NonNMethodCodeHeapSize, 5*M );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 6);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
|
||||
// Ergonomics related flags
|
||||
define_pd_global(bool, NeverActAsServerClassMachine, false);
|
||||
|
||||
define_pd_global(bool, TrapBasedRangeChecks, false); // Not needed.
|
||||
|
||||
#endif // CPU_RISCV_C2_GLOBALS_RISCV_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -140,10 +140,10 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
bool should_save_return_value = !_needs_return_buffer;
|
||||
RegSpiller out_reg_spiller(_output_registers);
|
||||
int spill_offset = -1;
|
||||
int out_spill_offset = -1;
|
||||
|
||||
if (should_save_return_value) {
|
||||
spill_offset = 0;
|
||||
out_spill_offset = 0;
|
||||
// spill area can be shared with shadow space and out args,
|
||||
// since they are only used before the call,
|
||||
// and spill area is only used after.
|
||||
@ -168,6 +168,9 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
// FP-> | |
|
||||
// |---------------------| = frame_bottom_offset = frame_size
|
||||
// | (optional) |
|
||||
// | in_reg_spiller area |
|
||||
// |---------------------|
|
||||
// | (optional) |
|
||||
// | capture state buf |
|
||||
// |---------------------| = StubLocations::CAPTURED_STATE_BUFFER
|
||||
// | (optional) |
|
||||
@ -181,6 +184,18 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
GrowableArray<VMStorage> out_regs = ForeignGlobals::replace_place_holders(_input_registers, locs);
|
||||
ArgumentShuffle arg_shuffle(filtered_java_regs, out_regs, shuffle_reg);
|
||||
|
||||
// Need to spill for state capturing runtime call.
|
||||
// The area spilled into is distinct from the capture state buffer.
|
||||
RegSpiller in_reg_spiller(out_regs);
|
||||
int in_spill_offset = -1;
|
||||
if (_captured_state_mask != 0) {
|
||||
// The spill area cannot be shared with the out_spill since
|
||||
// spilling needs to happen before the call. Allocate a new
|
||||
// region in the stack for this spill space.
|
||||
in_spill_offset = allocated_frame_size;
|
||||
allocated_frame_size += in_reg_spiller.spill_size_bytes();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
LogTarget(Trace, foreign, downcall) lt;
|
||||
if (lt.is_enabled()) {
|
||||
@ -226,6 +241,20 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
arg_shuffle.generate(_masm, shuffle_reg, 0, _abi._shadow_space_bytes);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
if (_captured_state_mask != 0) {
|
||||
assert(in_spill_offset != -1, "must be");
|
||||
__ block_comment("{ load initial thread local");
|
||||
in_reg_spiller.generate_spill(_masm, in_spill_offset);
|
||||
|
||||
// Copy the contents of the capture state buffer into thread local
|
||||
__ ld(c_rarg0, Address(sp, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER)));
|
||||
__ mv(c_rarg1, _captured_state_mask);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, DowncallLinker::capture_state_pre));
|
||||
|
||||
in_reg_spiller.generate_fill(_masm, in_spill_offset);
|
||||
__ block_comment("} load initial thread local");
|
||||
}
|
||||
|
||||
__ jalr(as_Register(locs.get(StubLocations::TARGET_ADDRESS)));
|
||||
// this call is assumed not to have killed xthread
|
||||
|
||||
@ -254,15 +283,15 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ block_comment("{ save thread local");
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ ld(c_rarg0, Address(sp, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER)));
|
||||
__ mv(c_rarg1, _captured_state_mask);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, DowncallLinker::capture_state));
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, DowncallLinker::capture_state_post));
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ block_comment("} save thread local");
|
||||
@ -319,7 +348,7 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
if (should_save_return_value) {
|
||||
// Need to save the native result registers around any runtime calls.
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ mv(c_rarg0, xthread);
|
||||
@ -327,7 +356,7 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans));
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
__ j(L_after_safepoint_poll);
|
||||
__ block_comment("} L_safepoint_poll_slow_path");
|
||||
@ -339,13 +368,13 @@ void DowncallLinker::StubGenerator::generate() {
|
||||
|
||||
if (should_save_return_value) {
|
||||
// Need to save the native result registers around any runtime calls.
|
||||
out_reg_spiller.generate_spill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_spill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
|
||||
|
||||
if (should_save_return_value) {
|
||||
out_reg_spiller.generate_fill(_masm, spill_offset);
|
||||
out_reg_spiller.generate_fill(_masm, out_spill_offset);
|
||||
}
|
||||
|
||||
__ j(L_after_reguard);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -236,8 +236,8 @@ inline bool frame::equal(frame other) const {
|
||||
|
||||
// Return unique id for this frame. The id must have a value where we can distinguish
|
||||
// identity and younger/older relationship. null represents an invalid (incomparable)
|
||||
// frame.
|
||||
inline intptr_t* frame::id(void) const { return unextended_sp(); }
|
||||
// frame. Should not be called for heap frames.
|
||||
inline intptr_t* frame::id(void) const { return real_fp(); }
|
||||
|
||||
// Return true if the frame is older (less recent activation) than the frame represented by id
|
||||
inline bool frame::is_older(intptr_t* id) const { assert(this->id() != nullptr && id != nullptr, "null frame id");
|
||||
@ -398,6 +398,9 @@ frame frame::sender(RegisterMap* map) const {
|
||||
StackWatermarkSet::on_iteration(map->thread(), result);
|
||||
}
|
||||
|
||||
// Calling frame::id() is currently not supported for heap frames.
|
||||
assert(result._on_heap || this->_on_heap || result.is_older(this->id()), "Must be");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -369,6 +369,11 @@ OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Na
|
||||
return opto_reg;
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
|
||||
// Load the oop from the weak handle.
|
||||
__ ld(obj, Address(obj));
|
||||
}
|
||||
|
||||
#undef __
|
||||
#define __ _masm->
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -110,6 +110,8 @@ public:
|
||||
#ifdef COMPILER2
|
||||
OptoReg::Name refine_register(const Node* node,
|
||||
OptoReg::Name opto_reg);
|
||||
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj,
|
||||
Register tmp, Label& slow_path);
|
||||
#endif // COMPILER2
|
||||
};
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -461,6 +462,30 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler *masm, Register obj,
|
||||
Register tmp, Label& slow_path) {
|
||||
assert_different_registers(obj, tmp);
|
||||
|
||||
Label done;
|
||||
|
||||
// Resolve weak handle using the standard implementation.
|
||||
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
|
||||
|
||||
// Check if the reference is null, and if it is, take the fast path.
|
||||
__ beqz(obj, done);
|
||||
|
||||
Address gc_state(xthread, ShenandoahThreadLocalData::gc_state_offset());
|
||||
__ lbu(tmp, gc_state);
|
||||
|
||||
// Check if the heap is under weak-reference/roots processing, in
|
||||
// which case we need to take the slow path.
|
||||
__ test_bit(tmp, tmp, ShenandoahHeap::WEAK_ROOTS_BITPOS);
|
||||
__ bnez(tmp, slow_path);
|
||||
__ bind(done);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Special Shenandoah CAS implementation that handles false negatives due
|
||||
// to concurrent evacuation. The service is more complex than a
|
||||
// traditional CAS operation because the CAS operation is intended to
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -84,7 +85,9 @@ public:
|
||||
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
|
||||
#ifdef COMPILER2
|
||||
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
|
||||
#endif
|
||||
void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
|
||||
Assembler::Aqrl acquire, Assembler::Aqrl release, bool is_cae, Register result);
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user