mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-15 13:49:42 +02:00
Merge commit '41520998aa
'
This commit is contained in:
commit
f373b4b75d
564 changed files with 14071 additions and 8341 deletions
|
@ -1491,12 +1491,12 @@ following targets are known to work:</p>
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><code>BASE_OS</code> must be one of "OEL6" for Oracle Enterprise
|
||||
Linux 6 or "Fedora" (if not specified "OEL6" will be the default). If
|
||||
the base OS is "Fedora" the corresponding Fedora release can be
|
||||
specified with the help of the <code>BASE_OS_VERSION</code> option (with
|
||||
"27" as default version). If the build is successful, the new devkits
|
||||
can be found in the <code>build/devkit/result</code> subdirectory:</p>
|
||||
<p><code>BASE_OS</code> must be one of <code>OL</code> for Oracle
|
||||
Enterprise Linux or <code>Fedora</code>. If the base OS is
|
||||
<code>Fedora</code> the corresponding Fedora release can be specified
|
||||
with the help of the <code>BASE_OS_VERSION</code> option. If the build
|
||||
is successful, the new devkits can be found in the
|
||||
<code>build/devkit/result</code> subdirectory:</p>
|
||||
<pre><code>cd make/devkit
|
||||
make TARGETS="ppc64le-linux-gnu aarch64-linux-gnu" BASE_OS=Fedora BASE_OS_VERSION=21
|
||||
ls -1 ../../build/devkit/result/
|
||||
|
|
|
@ -1285,12 +1285,10 @@ at least the following targets are known to work:
|
|||
| ppc64le-linux-gnu |
|
||||
| s390x-linux-gnu |
|
||||
|
||||
`BASE_OS` must be one of "OEL6" for Oracle Enterprise Linux 6 or "Fedora" (if
|
||||
not specified "OEL6" will be the default). If the base OS is "Fedora" the
|
||||
corresponding Fedora release can be specified with the help of the
|
||||
`BASE_OS_VERSION` option (with "27" as default version). If the build is
|
||||
successful, the new devkits can be found in the `build/devkit/result`
|
||||
subdirectory:
|
||||
`BASE_OS` must be one of `OL` for Oracle Enterprise Linux or `Fedora`. If the
|
||||
base OS is `Fedora` the corresponding Fedora release can be specified with the
|
||||
help of the `BASE_OS_VERSION` option. If the build is successful, the new
|
||||
devkits can be found in the `build/devkit/result` subdirectory:
|
||||
|
||||
```
|
||||
cd make/devkit
|
||||
|
|
|
@ -85,7 +85,7 @@ CreateHkTargets = \
|
|||
################################################################################
|
||||
# Include module specific build settings
|
||||
|
||||
THIS_SNIPPET := modules/$(MODULE)/Java.gmk
|
||||
THIS_SNIPPET := $(call GetModuleSnippetName, Java)
|
||||
|
||||
ifneq ($(wildcard $(THIS_SNIPPET)), )
|
||||
include MakeSnippetStart.gmk
|
||||
|
@ -115,6 +115,7 @@ $(eval $(call SetupJavaCompilation, $(MODULE), \
|
|||
EXCLUDE_FILES := $(EXCLUDE_FILES), \
|
||||
EXCLUDE_PATTERNS := -files, \
|
||||
KEEP_ALL_TRANSLATIONS := $(KEEP_ALL_TRANSLATIONS), \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE), \
|
||||
JAVAC_FLAGS := \
|
||||
$(DOCLINT) \
|
||||
$(JAVAC_FLAGS) \
|
||||
|
|
|
@ -184,7 +184,7 @@ endif
|
|||
################################################################################
|
||||
# Include module specific build settings
|
||||
|
||||
THIS_SNIPPET := modules/$(MODULE)/Jmod.gmk
|
||||
THIS_SNIPPET := $(call GetModuleSnippetName, Jmod)
|
||||
|
||||
ifneq ($(wildcard $(THIS_SNIPPET)), )
|
||||
include MakeSnippetStart.gmk
|
||||
|
|
|
@ -270,6 +270,7 @@ endif
|
|||
# Since debug symbols are not included in the jmod files, they need to be copied
|
||||
# in manually after generating the images.
|
||||
|
||||
# These variables are read by SetupCopyDebuginfo
|
||||
ALL_JDK_MODULES := $(JDK_MODULES)
|
||||
ALL_JRE_MODULES := $(sort $(JRE_MODULES), $(foreach m, $(JRE_MODULES), \
|
||||
$(call FindTransitiveDepsForModule, $m)))
|
||||
|
|
|
@ -1407,7 +1407,7 @@ CLEAN_SUPPORT_DIRS += demos
|
|||
CLEAN_SUPPORT_DIR_TARGETS := $(addprefix clean-, $(CLEAN_SUPPORT_DIRS))
|
||||
CLEAN_TESTS += hotspot-jtreg-native jdk-jtreg-native lib
|
||||
CLEAN_TEST_TARGETS += $(addprefix clean-test-, $(CLEAN_TESTS))
|
||||
CLEAN_PHASES := gensrc java native include
|
||||
CLEAN_PHASES += gensrc java native include
|
||||
CLEAN_PHASE_TARGETS := $(addprefix clean-, $(CLEAN_PHASES))
|
||||
CLEAN_MODULE_TARGETS := $(addprefix clean-, $(ALL_MODULES))
|
||||
# Construct targets of the form clean-$module-$phase
|
||||
|
|
|
@ -149,7 +149,7 @@ endef
|
|||
|
||||
################################################################################
|
||||
|
||||
PHASE_MAKEDIRS := $(TOPDIR)/make
|
||||
PHASE_MAKEDIRS += $(TOPDIR)/make
|
||||
|
||||
# Helper macro for DeclareRecipesForPhase
|
||||
# Declare a recipe for calling the module and phase specific makefile.
|
||||
|
|
|
@ -34,18 +34,23 @@ include MakeFileStart.gmk
|
|||
################################################################################
|
||||
|
||||
include CopyFiles.gmk
|
||||
include Modules.gmk
|
||||
|
||||
MODULE_SRC := $(TOPDIR)/src/$(MODULE)
|
||||
|
||||
# Define the snippet for MakeSnippetStart/End
|
||||
THIS_SNIPPET := modules/$(MODULE)/$(MAKEFILE_PREFIX).gmk
|
||||
################################################################################
|
||||
# Include module specific build settings
|
||||
|
||||
include MakeSnippetStart.gmk
|
||||
THIS_SNIPPET := $(call GetModuleSnippetName, $(MAKEFILE_PREFIX))
|
||||
|
||||
# Include the file being wrapped.
|
||||
include $(THIS_SNIPPET)
|
||||
ifneq ($(wildcard $(THIS_SNIPPET)), )
|
||||
include MakeSnippetStart.gmk
|
||||
|
||||
include MakeSnippetEnd.gmk
|
||||
# Include the file being wrapped.
|
||||
include $(THIS_SNIPPET)
|
||||
|
||||
include MakeSnippetEnd.gmk
|
||||
endif
|
||||
|
||||
ifeq ($(MAKEFILE_PREFIX), Lib)
|
||||
# We need to keep track of what libraries are generated/needed by this
|
||||
|
|
|
@ -1243,7 +1243,7 @@ UseSpecialTestHandler = \
|
|||
# Now process each test to run and setup a proper make rule
|
||||
$(foreach test, $(TESTS_TO_RUN), \
|
||||
$(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
|
||||
$(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \
|
||||
$(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
|
||||
$(eval ALL_TEST_IDS += $(TEST_ID)) \
|
||||
$(if $(call UseCustomTestHandler, $(test)), \
|
||||
$(eval $(call SetupRunCustomTest, $(TEST_ID), \
|
||||
|
@ -1323,9 +1323,9 @@ run-test-report: post-run-test
|
|||
TEST TOTAL PASS FAIL ERROR SKIP " "
|
||||
$(foreach test, $(TESTS_TO_RUN), \
|
||||
$(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
|
||||
$(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \
|
||||
$(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
|
||||
$(ECHO) >> $(TEST_LAST_IDS) $(TEST_ID) $(NEWLINE) \
|
||||
$(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c '\n' '[_*1000]')) \
|
||||
$(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c '\n' '_')) \
|
||||
$(if $(filter __________________________________________________%, $(NAME_PATTERN)), \
|
||||
$(eval TEST_NAME := ) \
|
||||
$(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s\n" " " "$(test)" $(NEWLINE) \
|
||||
|
|
|
@ -36,7 +36,7 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_LANGTOOLS, \
|
|||
COMPILER := bootjdk, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \
|
||||
SRC := $(TOPDIR)/make/langtools/tools, \
|
||||
INCLUDES := compileproperties propertiesparser, \
|
||||
INCLUDES := compileproperties flagsgenerator propertiesparser, \
|
||||
COPY := .properties, \
|
||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes, \
|
||||
))
|
||||
|
|
|
@ -395,11 +395,9 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
|
|||
|
||||
# When compiling code to be executed by the Boot JDK, force compatibility with the
|
||||
# oldest supported bootjdk.
|
||||
OLDEST_BOOT_JDK=`$ECHO $DEFAULT_ACCEPTABLE_BOOT_VERSIONS \
|
||||
OLDEST_BOOT_JDK_VERSION=`$ECHO $DEFAULT_ACCEPTABLE_BOOT_VERSIONS \
|
||||
| $TR " " "\n" | $SORT -n | $HEAD -n1`
|
||||
# -Xlint:-options is added to avoid "warning: [options] system modules path not set in conjunction with -source"
|
||||
BOOT_JDK_SOURCETARGET="-source $OLDEST_BOOT_JDK -target $OLDEST_BOOT_JDK -Xlint:-options"
|
||||
AC_SUBST(BOOT_JDK_SOURCETARGET)
|
||||
AC_SUBST(OLDEST_BOOT_JDK_VERSION)
|
||||
|
||||
# Check if the boot jdk is 32 or 64 bit
|
||||
if $JAVA -version 2>&1 | $GREP -q "64-Bit"; then
|
||||
|
|
|
@ -513,6 +513,10 @@ AC_DEFUN([JVM_FEATURES_VERIFY],
|
|||
[
|
||||
variant=$1
|
||||
|
||||
if JVM_FEATURES_IS_ACTIVE(jfr) && ! JVM_FEATURES_IS_ACTIVE(services); then
|
||||
AC_MSG_ERROR([Specified JVM feature 'jfr' requires feature 'services' for variant '$variant'])
|
||||
fi
|
||||
|
||||
if JVM_FEATURES_IS_ACTIVE(jvmci) && ! (JVM_FEATURES_IS_ACTIVE(compiler1) || \
|
||||
JVM_FEATURES_IS_ACTIVE(compiler2)); then
|
||||
AC_MSG_ERROR([Specified JVM feature 'jvmci' requires feature 'compiler2' or 'compiler1' for variant '$variant'])
|
||||
|
|
|
@ -393,9 +393,8 @@ EXTERNAL_BUILDJDK := @EXTERNAL_BUILDJDK@
|
|||
# Whether the boot jdk jar supports --date=TIMESTAMP
|
||||
BOOT_JDK_JAR_SUPPORTS_DATE := @BOOT_JDK_JAR_SUPPORTS_DATE@
|
||||
|
||||
# When compiling Java source to be run by the boot jdk
|
||||
# use these extra flags, eg -source 6 -target 6
|
||||
BOOT_JDK_SOURCETARGET := @BOOT_JDK_SOURCETARGET@
|
||||
# The oldest supported boot jdk version
|
||||
OLDEST_BOOT_JDK_VERSION := @OLDEST_BOOT_JDK_VERSION@
|
||||
|
||||
# Information about the build system
|
||||
NUM_CORES := @NUM_CORES@
|
||||
|
|
|
@ -38,10 +38,15 @@ include JarArchive.gmk
|
|||
###
|
||||
|
||||
# Create classes that can run on the bootjdk
|
||||
TARGET_RELEASE_BOOTJDK := $(BOOT_JDK_SOURCETARGET)
|
||||
# -Xlint:-options is added to avoid the warning
|
||||
# "system modules path not set in conjunction with -source"
|
||||
TARGET_RELEASE_BOOTJDK := -source $(OLDEST_BOOT_JDK_VERSION) \
|
||||
-target $(OLDEST_BOOT_JDK_VERSION) -Xlint:-options
|
||||
|
||||
# Create classes that can be used in (or be a part of) the new jdk we're building
|
||||
TARGET_RELEASE_NEWJDK := -source $(JDK_SOURCE_TARGET_VERSION) -target $(JDK_SOURCE_TARGET_VERSION)
|
||||
# Create classes that can be used in (or be a part of) the new jdk we're
|
||||
# building
|
||||
TARGET_RELEASE_NEWJDK := -source $(JDK_SOURCE_TARGET_VERSION) \
|
||||
-target $(JDK_SOURCE_TARGET_VERSION)
|
||||
|
||||
# Create classes that can be used in JDK 8, for legacy support
|
||||
TARGET_RELEASE_JDK8 := --release 8
|
||||
|
@ -178,6 +183,10 @@ define SetupJavaCompilationBody
|
|||
|
||||
$1_SAFE_NAME := $$(strip $$(subst /,_, $1))
|
||||
|
||||
ifeq ($$($1_LOG_ACTION), )
|
||||
$1_LOG_ACTION := Compiling
|
||||
endif
|
||||
|
||||
ifeq ($$($1_SMALL_JAVA), )
|
||||
# If unspecified, default to true
|
||||
$1_SMALL_JAVA := true
|
||||
|
@ -472,7 +481,7 @@ define SetupJavaCompilationBody
|
|||
# list of files.
|
||||
$$($1_FILELIST): $$($1_SRCS) $$($1_VARDEPS_FILE)
|
||||
$$(call MakeDir, $$(@D))
|
||||
$$(call LogWarn, Compiling up to $$(words $$($1_SRCS)) files for $1)
|
||||
$$(call LogWarn, $$($1_LOG_ACTION) up to $$(words $$($1_SRCS)) files for $1)
|
||||
$$(eval $$(call ListPathsSafely, $1_SRCS, $$($1_FILELIST)))
|
||||
|
||||
# Create a $$($1_MODFILELIST) file with significant modified dependencies
|
||||
|
|
|
@ -33,7 +33,7 @@ include $(TOPDIR)/make/conf/module-loader-map.conf
|
|||
|
||||
# Append platform-specific and upgradeable modules
|
||||
PLATFORM_MODULES += $(PLATFORM_MODULES_$(OPENJDK_TARGET_OS)) \
|
||||
$(UPGRADEABLE_PLATFORM_MODULES)
|
||||
$(UPGRADEABLE_PLATFORM_MODULES) $(CUSTOM_UPGRADEABLE_PLATFORM_MODULES)
|
||||
|
||||
################################################################################
|
||||
# Setup module sets for docs
|
||||
|
@ -216,7 +216,7 @@ endif
|
|||
# Find dependencies ("requires") for a given module.
|
||||
# Param 1: Module to find dependencies for.
|
||||
FindDepsForModule = \
|
||||
$(DEPS_$(strip $1))
|
||||
$(filter-out $(IMPORT_MODULES), $(DEPS_$(strip $1)))
|
||||
|
||||
# Find dependencies ("requires") transitively in 3 levels for a given module.
|
||||
# Param 1: Module to find dependencies for.
|
||||
|
@ -254,7 +254,8 @@ FindTransitiveIndirectDepsForModules = \
|
|||
# Upgradeable modules are those that are either defined as upgradeable or that
|
||||
# require an upradeable module.
|
||||
FindAllUpgradeableModules = \
|
||||
$(sort $(filter-out $(MODULES_FILTER), $(UPGRADEABLE_PLATFORM_MODULES)))
|
||||
$(sort $(filter-out $(MODULES_FILTER), \
|
||||
$(UPGRADEABLE_PLATFORM_MODULES) $(CUSTOM_UPGRADEABLE_PLATFORM_MODULES)))
|
||||
|
||||
################################################################################
|
||||
|
||||
|
@ -316,6 +317,19 @@ define ReadImportMetaData
|
|||
$$(eval $$(call ReadSingleImportMetaData, $$m)))
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# Get a full snippet path for the current module and a given base name.
|
||||
#
|
||||
# Param 1 - The base name of the snippet file to include
|
||||
GetModuleSnippetName = \
|
||||
$(if $(CUSTOM_MODULE_MAKE_ROOT), \
|
||||
$(if $(wildcard $(CUSTOM_MODULE_MAKE_ROOT)/$(MODULE)/$(strip $1).gmk), \
|
||||
$(CUSTOM_MODULE_MAKE_ROOT)/$(MODULE)/$(strip $1).gmk, \
|
||||
$(wildcard modules/$(MODULE)/$(strip $1).gmk) \
|
||||
), \
|
||||
$(wildcard modules/$(MODULE)/$(strip $1).gmk) \
|
||||
)
|
||||
|
||||
################################################################################
|
||||
|
||||
endif # include guard
|
||||
|
|
161
make/langtools/tools/flagsgenerator/FlagsGenerator.java
Normal file
161
make/langtools/tools/flagsgenerator/FlagsGenerator.java
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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 flagsgenerator;
|
||||
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.source.util.Trees;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
public class FlagsGenerator {
|
||||
public static void main(String... args) throws IOException {
|
||||
var compiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
try (var fm = compiler.getStandardFileManager(null, null, null)) {
|
||||
JavacTask task = (JavacTask) compiler.getTask(null, null, d -> {}, null, null, fm.getJavaFileObjects(args[0]));
|
||||
Trees trees = Trees.instance(task);
|
||||
CompilationUnitTree cut = task.parse().iterator().next();
|
||||
|
||||
task.analyze();
|
||||
|
||||
TypeElement clazz = (TypeElement) trees.getElement(new TreePath(new TreePath(cut), cut.getTypeDecls().get(0)));
|
||||
Map<Integer, List<String>> flag2Names = new TreeMap<>();
|
||||
Map<FlagTarget, Map<Integer, List<String>>> target2FlagBit2Fields = new EnumMap<>(FlagTarget.class);
|
||||
Map<String, String> customToString = new HashMap<>();
|
||||
Set<String> noToString = new HashSet<>();
|
||||
|
||||
for (VariableElement field : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
|
||||
String flagName = field.getSimpleName().toString();
|
||||
for (AnnotationMirror am : field.getAnnotationMirrors()) {
|
||||
switch (am.getAnnotationType().toString()) {
|
||||
case "com.sun.tools.javac.code.Flags.Use" -> {
|
||||
long flagValue = ((Number) field.getConstantValue()).longValue();
|
||||
int flagBit = 63 - Long.numberOfLeadingZeros(flagValue);
|
||||
|
||||
flag2Names.computeIfAbsent(flagBit, _ -> new ArrayList<>())
|
||||
.add(flagName);
|
||||
|
||||
List<?> originalTargets = (List<?>) valueOfValueAttribute(am);
|
||||
originalTargets.stream()
|
||||
.map(value -> FlagTarget.valueOf(value.toString()))
|
||||
.forEach(target -> target2FlagBit2Fields.computeIfAbsent(target, _ -> new HashMap<>())
|
||||
.computeIfAbsent(flagBit, _ -> new ArrayList<>())
|
||||
.add(flagName));
|
||||
}
|
||||
case "com.sun.tools.javac.code.Flags.CustomToStringValue" -> {
|
||||
customToString.put(flagName, (String) valueOfValueAttribute(am));
|
||||
}
|
||||
case "com.sun.tools.javac.code.Flags.NoToStringValue" -> {
|
||||
noToString.add(flagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//verify there are no flag overlaps:
|
||||
for (Entry<FlagTarget, Map<Integer, List<String>>> targetAndFlag : target2FlagBit2Fields.entrySet()) {
|
||||
for (Entry<Integer, List<String>> flagAndFields : targetAndFlag.getValue().entrySet()) {
|
||||
if (flagAndFields.getValue().size() > 1) {
|
||||
throw new AssertionError("duplicate flag for target: " + targetAndFlag.getKey() +
|
||||
", flag: " + flagAndFields.getKey() +
|
||||
", flags fields: " + flagAndFields.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(args[1])))) {
|
||||
out.println("""
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
public enum FlagsEnum {
|
||||
""");
|
||||
for (Entry<Integer, List<String>> e : flag2Names.entrySet()) {
|
||||
String constantName = e.getValue().stream().collect(Collectors.joining("_OR_"));
|
||||
String toString = e.getValue()
|
||||
.stream()
|
||||
.filter(n -> !noToString.contains(n))
|
||||
.map(n -> customToString.getOrDefault(n, n.toLowerCase(Locale.US)))
|
||||
.collect(Collectors.joining(" or "));
|
||||
out.println(" " + constantName + "(1L<<" + e.getKey() + ", \"" + toString + "\"),");
|
||||
}
|
||||
out.println("""
|
||||
;
|
||||
|
||||
private final long value;
|
||||
private final String toString;
|
||||
private FlagsEnum(long value, String toString) {
|
||||
this.value = value;
|
||||
this.toString = toString;
|
||||
}
|
||||
public long value() {
|
||||
return value;
|
||||
}
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
}
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Object valueOfValueAttribute(AnnotationMirror am) {
|
||||
return am.getElementValues()
|
||||
.values()
|
||||
.iterator()
|
||||
.next()
|
||||
.getValue();
|
||||
}
|
||||
|
||||
private enum FlagTarget {
|
||||
BLOCK,
|
||||
CLASS,
|
||||
METHOD,
|
||||
MODULE,
|
||||
PACKAGE,
|
||||
TYPE_VAR,
|
||||
VARIABLE;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2025, 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
|
||||
|
@ -76,7 +76,7 @@ public interface MessageType {
|
|||
ANNOTATION("annotation", "Compound", "com.sun.tools.javac.code.Attribute"),
|
||||
BOOLEAN("boolean", "boolean", null),
|
||||
COLLECTION("collection", "Collection", "java.util"),
|
||||
FLAG("flag", "Flag", "com.sun.tools.javac.code.Flags"),
|
||||
FLAG("flag", "FlagsEnum", "com.sun.tools.javac.code"),
|
||||
FRAGMENT("fragment", "Fragment", null),
|
||||
DIAGNOSTIC("diagnostic", "JCDiagnostic", "com.sun.tools.javac.util"),
|
||||
MODIFIER("modifier", "Modifier", "javax.lang.model.element"),
|
||||
|
|
|
@ -177,7 +177,8 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
|||
endif
|
||||
|
||||
LIBSPLASHSCREEN_CFLAGS += -DSPLASHSCREEN -DPNG_NO_MMX_CODE \
|
||||
-DPNG_ARM_NEON_OPT=0 -DPNG_ARM_NEON_IMPLEMENTATION=0
|
||||
-DPNG_ARM_NEON_OPT=0 -DPNG_ARM_NEON_IMPLEMENTATION=0 \
|
||||
-DPNG_LOONGARCH_LSX_OPT=0
|
||||
|
||||
ifeq ($(call isTargetOs, linux)+$(call isTargetCpuArch, ppc), true+true)
|
||||
LIBSPLASHSCREEN_CFLAGS += -DPNG_POWERPC_VSX_OPT=0
|
||||
|
|
|
@ -41,17 +41,17 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
|
|||
|
||||
TARGETS += $(COMPILE_PROPERTIES)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Compile properties files into enum-like classes using the propertiesparser tool
|
||||
#
|
||||
|
||||
# To avoid reevaluating the compilation setup for the tools each time this file
|
||||
# is included, the following trick is used to be able to declare a dependency on
|
||||
# the built tools.
|
||||
BUILD_TOOLS_LANGTOOLS := $(call SetupJavaCompilationCompileTarget, \
|
||||
BUILD_TOOLS_LANGTOOLS, $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Compile properties files into enum-like classes using the propertiesparser tool
|
||||
#
|
||||
|
||||
TOOL_PARSEPROPERTIES_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
|
||||
propertiesparser.PropertiesParser
|
||||
|
||||
|
@ -76,3 +76,26 @@ $(eval $(call SetupExecute, PARSEPROPERTIES, \
|
|||
TARGETS += $(PARSEPROPERTIES)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Generate FlagsEnum from Flags constants
|
||||
#
|
||||
|
||||
TOOL_FLAGSGENERATOR_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
|
||||
flagsgenerator.FlagsGenerator
|
||||
|
||||
FLAGS_SRC := \
|
||||
$(MODULE_SRC)/share/classes/com/sun/tools/javac/code/Flags.java
|
||||
|
||||
FLAGS_OUT := \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/com/sun/tools/javac/code/FlagsEnum.java
|
||||
|
||||
$(eval $(call SetupExecute, FLAGSGENERATOR, \
|
||||
WARN := Generating FlagsEnum, \
|
||||
DEPS := $(FLAGS_SRC) $(BUILD_TOOLS_LANGTOOLS), \
|
||||
OUTPUT_FILE := $(FLAGS_OUT), \
|
||||
COMMAND := $(TOOL_FLAGSGENERATOR_CMD) $(FLAGS_SRC) $(FLAGS_OUT), \
|
||||
))
|
||||
|
||||
TARGETS += $(FLAGSGENERATOR)
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -33,4 +33,6 @@ DISABLED_WARNINGS_java += dangling-doc-comments this-escape
|
|||
|
||||
JAVAC_FLAGS += -parameters -XDstringConcat=inline
|
||||
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK)
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -121,15 +121,15 @@ ifeq ($(call isTargetOs, windows), true)
|
|||
TARGETS += $(BUILD_LIBJPACKAGE)
|
||||
|
||||
##############################################################################
|
||||
## Build libwixhelper
|
||||
## Build libmsica
|
||||
##############################################################################
|
||||
|
||||
# Build Wix custom action helper
|
||||
# Build MSI custom action library
|
||||
# Output library in resources dir, and symbols in the object dir
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBWIXHELPER, \
|
||||
NAME := wixhelper, \
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBMSICA, \
|
||||
NAME := msica, \
|
||||
OUTPUT_DIR := $(JPACKAGE_OUTPUT_DIR), \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libwixhelper, \
|
||||
SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmsica, \
|
||||
ONLY_EXPORTED := true, \
|
||||
OPTIMIZATION := LOW, \
|
||||
EXTRA_SRC := common, \
|
||||
|
@ -139,7 +139,7 @@ ifeq ($(call isTargetOs, windows), true)
|
|||
LIBS_windows := msi.lib ole32.lib shell32.lib shlwapi.lib user32.lib, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBWIXHELPER)
|
||||
TARGETS += $(BUILD_LIBMSICA)
|
||||
|
||||
##############################################################################
|
||||
## Build msiwrapper
|
||||
|
|
|
@ -62,7 +62,8 @@ BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libGetXSpace := java.base:libjava
|
|||
ifeq ($(call isTargetOs, windows), true)
|
||||
BUILD_JDK_JTREG_EXCLUDE += libDirectIO.c libInheritedChannel.c \
|
||||
libExplicitAttach.c libImplicitAttach.c \
|
||||
exelauncher.c libFDLeaker.c exeFDLeakTester.c
|
||||
exelauncher.c libFDLeaker.c exeFDLeakTester.c \
|
||||
libChangeSignalDisposition.c exePrintSignalDisposition.c
|
||||
|
||||
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerTest := $(LIBCXX)
|
||||
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib
|
||||
|
|
|
@ -16282,41 +16282,8 @@ instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
|
|||
// ============================================================================
|
||||
// inlined locking and unlocking
|
||||
|
||||
instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
|
||||
%{
|
||||
predicate(LockingMode != LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
|
||||
|
||||
ins_cost(5 * INSN_COST);
|
||||
format %{ "fastlock $object,$box\t! kills $tmp,$tmp2,$tmp3" %}
|
||||
|
||||
ins_encode %{
|
||||
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
|
||||
%{
|
||||
predicate(LockingMode != LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastUnlock object box));
|
||||
effect(TEMP tmp, TEMP tmp2);
|
||||
|
||||
ins_cost(5 * INSN_COST);
|
||||
format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %}
|
||||
|
||||
ins_encode %{
|
||||
__ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
|
||||
%{
|
||||
predicate(LockingMode == LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
|
||||
|
||||
|
@ -16332,7 +16299,6 @@ instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp
|
|||
|
||||
instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
|
||||
%{
|
||||
predicate(LockingMode == LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastUnlock object box));
|
||||
effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
|
||||
|
||||
|
|
|
@ -410,11 +410,7 @@ int LIR_Assembler::emit_unwind_handler() {
|
|||
if (method()->is_synchronized()) {
|
||||
monitor_address(0, FrameMap::r0_opr);
|
||||
stub = new MonitorExitStub(FrameMap::r0_opr, true, 0);
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ b(*stub->entry());
|
||||
} else {
|
||||
__ unlock_object(r5, r4, r0, r6, *stub->entry());
|
||||
}
|
||||
__ unlock_object(r5, r4, r0, r6, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
|
@ -2484,13 +2480,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
|||
Register hdr = op->hdr_opr()->as_register();
|
||||
Register lock = op->lock_opr()->as_register();
|
||||
Register temp = op->scratch_opr()->as_register();
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check_here(op->info());
|
||||
__ null_check(obj, -1);
|
||||
}
|
||||
__ b(*op->stub()->entry());
|
||||
} else if (op->code() == lir_lock) {
|
||||
if (op->code() == lir_lock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
// add debug info for NullPointerException only if one is possible
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry());
|
||||
|
@ -2823,7 +2813,7 @@ void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, C
|
|||
return;
|
||||
}
|
||||
|
||||
__ lea(dest->as_register_lo(), as_Address(addr->as_address_ptr()));
|
||||
__ lea(dest->as_pointer_register(), as_Address(addr->as_address_ptr()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -981,7 +981,7 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
|
|||
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
|
||||
const LIR_Opr result_reg = result_register_for(x->type());
|
||||
|
||||
LIR_Opr addr = new_pointer_register();
|
||||
LIR_Opr addr = new_register(T_ADDRESS);
|
||||
__ leal(LIR_OprFact::address(a), addr);
|
||||
|
||||
crc.load_item_force(cc->at(0));
|
||||
|
@ -1058,7 +1058,7 @@ void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
|
|||
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
|
||||
const LIR_Opr result_reg = result_register_for(x->type());
|
||||
|
||||
LIR_Opr addr = new_pointer_register();
|
||||
LIR_Opr addr = new_register(T_ADDRESS);
|
||||
__ leal(LIR_OprFact::address(a), addr);
|
||||
|
||||
crc.load_item_force(cc->at(0));
|
||||
|
|
|
@ -60,8 +60,6 @@ void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
|
|||
}
|
||||
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord -1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2);
|
||||
int null_check_offset = -1;
|
||||
|
||||
|
@ -72,95 +70,20 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
|||
|
||||
null_check_offset = offset();
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(disp_hdr, obj, hdr, temp, rscratch2, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
lightweight_lock(disp_hdr, obj, hdr, temp, rscratch2, slow_case);
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(hdr, obj);
|
||||
ldrb(hdr, Address(hdr, Klass::misc_flags_offset()));
|
||||
tst(hdr, KlassFlags::_misc_is_value_based_class);
|
||||
br(Assembler::NE, slow_case);
|
||||
}
|
||||
|
||||
Label done;
|
||||
// Load object header
|
||||
ldr(hdr, Address(obj, hdr_offset));
|
||||
// and mark it as unlocked
|
||||
orr(hdr, hdr, markWord::unlocked_value);
|
||||
// save unlocked object header into the displaced header location on the stack
|
||||
str(hdr, Address(disp_hdr, 0));
|
||||
// test if object header is still the same (i.e. unlocked), and if so, store the
|
||||
// displaced header address in the object header - if it is not the same, get the
|
||||
// object header instead
|
||||
lea(rscratch2, Address(obj, hdr_offset));
|
||||
cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/nullptr);
|
||||
// if the object header was the same, we're done
|
||||
// if the object header was not the same, it is now in the hdr register
|
||||
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
|
||||
//
|
||||
// 1) (hdr & aligned_mask) == 0
|
||||
// 2) sp <= hdr
|
||||
// 3) hdr <= sp + page_size
|
||||
//
|
||||
// these 3 tests can be done by evaluating the following expression:
|
||||
//
|
||||
// (hdr - sp) & (aligned_mask - page_size)
|
||||
//
|
||||
// assuming both the stack pointer and page_size have their least
|
||||
// significant 2 bits cleared and page_size is a power of 2
|
||||
mov(rscratch1, sp);
|
||||
sub(hdr, hdr, rscratch1);
|
||||
ands(hdr, hdr, aligned_mask - (int)os::vm_page_size());
|
||||
// for recursive locking, the result is zero => save it in the displaced header
|
||||
// location (null in the displaced hdr location indicates recursive locking)
|
||||
str(hdr, Address(disp_hdr, 0));
|
||||
// otherwise we don't care about the result and handle locking via runtime call
|
||||
cbnz(hdr, slow_case);
|
||||
// done
|
||||
bind(done);
|
||||
inc_held_monitor_count(rscratch1);
|
||||
}
|
||||
return null_check_offset;
|
||||
}
|
||||
|
||||
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord -1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2);
|
||||
Label done;
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// load displaced header
|
||||
ldr(hdr, Address(disp_hdr, 0));
|
||||
// if the loaded hdr is null we had recursive locking
|
||||
// if we had recursive locking, we are done
|
||||
cbz(hdr, done);
|
||||
}
|
||||
|
||||
// load object
|
||||
ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
verify_oop(obj);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_unlock(obj, hdr, temp, rscratch2, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// test if object header is pointing to the displaced header, and if so, restore
|
||||
// the displaced header in the object - if the object header is not pointing to
|
||||
// the displaced header, get the object header instead
|
||||
// if the object header was not pointing to the displaced header,
|
||||
// we do unlocking via runtime call
|
||||
if (hdr_offset) {
|
||||
lea(rscratch1, Address(obj, hdr_offset));
|
||||
cmpxchgptr(disp_hdr, hdr, rscratch1, rscratch2, done, &slow_case);
|
||||
} else {
|
||||
cmpxchgptr(disp_hdr, hdr, obj, rscratch2, done, &slow_case);
|
||||
}
|
||||
// done
|
||||
bind(done);
|
||||
dec_held_monitor_count(rscratch1);
|
||||
}
|
||||
lightweight_unlock(obj, hdr, temp, rscratch2, slow_case);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -147,215 +147,8 @@ address C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register
|
|||
return pc();
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmpReg,
|
||||
Register tmp2Reg, Register tmp3Reg) {
|
||||
Register oop = objectReg;
|
||||
Register box = boxReg;
|
||||
Register disp_hdr = tmpReg;
|
||||
Register tmp = tmp2Reg;
|
||||
Label cont;
|
||||
Label object_has_monitor;
|
||||
Label count, no_count;
|
||||
|
||||
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
|
||||
assert_different_registers(oop, box, tmp, disp_hdr, rscratch2);
|
||||
|
||||
// Load markWord from object into displaced_header.
|
||||
ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, oop);
|
||||
ldrb(tmp, Address(tmp, Klass::misc_flags_offset()));
|
||||
tst(tmp, KlassFlags::_misc_is_value_based_class);
|
||||
br(Assembler::NE, cont);
|
||||
}
|
||||
|
||||
// Check for existing monitor
|
||||
tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
|
||||
b(cont);
|
||||
} else {
|
||||
assert(LockingMode == LM_LEGACY, "must be");
|
||||
// Set tmp to be (markWord of object | UNLOCK_VALUE).
|
||||
orr(tmp, disp_hdr, markWord::unlocked_value);
|
||||
|
||||
// Initialize the box. (Must happen before we update the object mark!)
|
||||
str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
// Compare object markWord with an unlocked value (tmp) and if
|
||||
// equal exchange the stack address of our box with object markWord.
|
||||
// On failure disp_hdr contains the possibly locked markWord.
|
||||
cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
|
||||
/*release*/ true, /*weak*/ false, disp_hdr);
|
||||
br(Assembler::EQ, cont);
|
||||
|
||||
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
|
||||
|
||||
// If the compare-and-exchange succeeded, then we found an unlocked
|
||||
// object, will have now locked it will continue at label cont
|
||||
|
||||
// Check if the owner is self by comparing the value in the
|
||||
// markWord of object (disp_hdr) with the stack pointer.
|
||||
mov(rscratch1, sp);
|
||||
sub(disp_hdr, disp_hdr, rscratch1);
|
||||
mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
|
||||
// If condition is true we are cont and hence we can store 0 as the
|
||||
// displaced header in the box, which indicates that it is a recursive lock.
|
||||
ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result
|
||||
str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
b(cont);
|
||||
}
|
||||
|
||||
// Handle existing monitor.
|
||||
bind(object_has_monitor);
|
||||
|
||||
// Try to CAS owner (no owner => current thread's _monitor_owner_id).
|
||||
ldr(rscratch2, Address(rthread, JavaThread::monitor_owner_id_offset()));
|
||||
add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset())-markWord::monitor_value));
|
||||
cmpxchg(tmp, zr, rscratch2, Assembler::xword, /*acquire*/ true,
|
||||
/*release*/ true, /*weak*/ false, tmp3Reg); // Sets flags for result
|
||||
|
||||
// Store a non-null value into the box to avoid looking like a re-entrant
|
||||
// lock. The fast-path monitor unlock code checks for
|
||||
// markWord::monitor_value so use markWord::unused_mark which has the
|
||||
// relevant bit set, and also matches ObjectSynchronizer::enter.
|
||||
mov(tmp, (address)markWord::unused_mark().value());
|
||||
str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
br(Assembler::EQ, cont); // CAS success means locking succeeded
|
||||
|
||||
cmp(tmp3Reg, rscratch2);
|
||||
br(Assembler::NE, cont); // Check for recursive locking
|
||||
|
||||
// Recursive lock case
|
||||
increment(Address(disp_hdr, in_bytes(ObjectMonitor::recursions_offset()) - markWord::monitor_value), 1);
|
||||
// flag == EQ still from the cmp above, checking if this is a reentrant lock
|
||||
|
||||
bind(cont);
|
||||
// flag == EQ indicates success
|
||||
// flag == NE indicates failure
|
||||
br(Assembler::NE, no_count);
|
||||
|
||||
bind(count);
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
inc_held_monitor_count(rscratch1);
|
||||
}
|
||||
|
||||
bind(no_count);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Register tmpReg,
|
||||
Register tmp2Reg) {
|
||||
Register oop = objectReg;
|
||||
Register box = boxReg;
|
||||
Register disp_hdr = tmpReg;
|
||||
Register owner_addr = tmpReg;
|
||||
Register tmp = tmp2Reg;
|
||||
Label cont;
|
||||
Label object_has_monitor;
|
||||
Label count, no_count;
|
||||
Label unlocked;
|
||||
|
||||
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_unlock_lightweight");
|
||||
assert_different_registers(oop, box, tmp, disp_hdr);
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
// Find the lock address and load the displaced header from the stack.
|
||||
ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
// If the displaced header is 0, we have a recursive unlock.
|
||||
cmp(disp_hdr, zr);
|
||||
br(Assembler::EQ, cont);
|
||||
}
|
||||
|
||||
// Handle existing monitor.
|
||||
ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
|
||||
tbnz(tmp, exact_log2(markWord::monitor_value), object_has_monitor);
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
|
||||
b(cont);
|
||||
} else {
|
||||
assert(LockingMode == LM_LEGACY, "must be");
|
||||
// Check if it is still a light weight lock, this is is true if we
|
||||
// see the stack address of the basicLock in the markWord of the
|
||||
// object.
|
||||
|
||||
cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false,
|
||||
/*release*/ true, /*weak*/ false, tmp);
|
||||
b(cont);
|
||||
}
|
||||
|
||||
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
|
||||
|
||||
// Handle existing monitor.
|
||||
bind(object_has_monitor);
|
||||
STATIC_ASSERT(markWord::monitor_value <= INT_MAX);
|
||||
add(tmp, tmp, -(int)markWord::monitor_value); // monitor
|
||||
|
||||
ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset()));
|
||||
|
||||
Label notRecursive;
|
||||
cbz(disp_hdr, notRecursive);
|
||||
|
||||
// Recursive lock
|
||||
sub(disp_hdr, disp_hdr, 1u);
|
||||
str(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset()));
|
||||
cmp(disp_hdr, disp_hdr); // Sets flags for result
|
||||
b(cont);
|
||||
|
||||
bind(notRecursive);
|
||||
|
||||
// Compute owner address.
|
||||
lea(owner_addr, Address(tmp, ObjectMonitor::owner_offset()));
|
||||
|
||||
// Set owner to null.
|
||||
// Release to satisfy the JMM
|
||||
stlr(zr, owner_addr);
|
||||
// We need a full fence after clearing owner to avoid stranding.
|
||||
// StoreLoad achieves this.
|
||||
membar(StoreLoad);
|
||||
|
||||
// Check if the entry_list is empty.
|
||||
ldr(rscratch1, Address(tmp, ObjectMonitor::entry_list_offset()));
|
||||
cmp(rscratch1, zr);
|
||||
br(Assembler::EQ, cont); // If so we are done.
|
||||
|
||||
// Check if there is a successor.
|
||||
ldr(rscratch1, Address(tmp, ObjectMonitor::succ_offset()));
|
||||
cmp(rscratch1, zr);
|
||||
br(Assembler::NE, unlocked); // If so we are done.
|
||||
|
||||
// Save the monitor pointer in the current thread, so we can try to
|
||||
// reacquire the lock in SharedRuntime::monitor_exit_helper().
|
||||
str(tmp, Address(rthread, JavaThread::unlocked_inflated_monitor_offset()));
|
||||
|
||||
cmp(zr, rthread); // Set Flag to NE => slow path
|
||||
b(cont);
|
||||
|
||||
bind(unlocked);
|
||||
cmp(zr, zr); // Set Flag to EQ => fast path
|
||||
|
||||
// Intentional fall-through
|
||||
|
||||
bind(cont);
|
||||
// flag == EQ indicates success
|
||||
// flag == NE indicates failure
|
||||
br(Assembler::NE, no_count);
|
||||
|
||||
bind(count);
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
dec_held_monitor_count(rscratch1);
|
||||
}
|
||||
|
||||
bind(no_count);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Register t1,
|
||||
Register t2, Register t3) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
assert_different_registers(obj, box, t1, t2, t3, rscratch2);
|
||||
|
||||
// Handle inflated monitor.
|
||||
|
@ -512,7 +305,6 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist
|
|||
|
||||
void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, Register t1,
|
||||
Register t2, Register t3) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
assert_different_registers(obj, box, t1, t2, t3);
|
||||
|
||||
// Handle inflated monitor.
|
||||
|
|
|
@ -51,9 +51,6 @@
|
|||
FloatRegister vmul3, FloatRegister vpow, FloatRegister vpowm,
|
||||
BasicType eltype);
|
||||
|
||||
// Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
|
||||
void fast_lock(Register object, Register box, Register tmp, Register tmp2, Register tmp3);
|
||||
void fast_unlock(Register object, Register box, Register tmp, Register tmp2);
|
||||
// Code used by cmpFastLockLightweight and cmpFastUnlockLightweight mach instructions in .ad file.
|
||||
void fast_lock_lightweight(Register object, Register box, Register t1, Register t2, Register t3);
|
||||
void fast_unlock_lightweight(Register object, Register box, Register t1, Register t2, Register t3);
|
||||
|
|
|
@ -691,104 +691,27 @@ void InterpreterMacroAssembler::leave_jfr_critical_section() {
|
|||
void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
{
|
||||
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
} else {
|
||||
Label count, done;
|
||||
|
||||
const Register swap_reg = r0;
|
||||
const Register tmp = c_rarg2;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp2 = c_rarg4;
|
||||
const Register tmp3 = c_rarg5;
|
||||
const Register tmp = c_rarg2;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp2 = c_rarg4;
|
||||
const Register tmp3 = c_rarg5;
|
||||
|
||||
const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
|
||||
const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
|
||||
const int mark_offset = lock_offset +
|
||||
BasicLock::displaced_header_offset_in_bytes();
|
||||
// Load object pointer into obj_reg %c_rarg3
|
||||
ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
Label slow_case;
|
||||
Label slow_case, done;
|
||||
lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
|
||||
b(done);
|
||||
|
||||
// Load object pointer into obj_reg %c_rarg3
|
||||
ldr(obj_reg, Address(lock_reg, obj_offset));
|
||||
bind(slow_case);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
|
||||
b(done);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Call the runtime routine for slow case
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, obj_reg);
|
||||
ldrb(tmp, Address(tmp, Klass::misc_flags_offset()));
|
||||
tst(tmp, KlassFlags::_misc_is_value_based_class);
|
||||
br(Assembler::NE, slow_case);
|
||||
}
|
||||
|
||||
// Load (object->mark() | 1) into swap_reg
|
||||
ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
orr(swap_reg, rscratch1, 1);
|
||||
|
||||
// Save (object->mark() | 1) into BasicLock's displaced header
|
||||
str(swap_reg, Address(lock_reg, mark_offset));
|
||||
|
||||
assert(lock_offset == 0,
|
||||
"displached header must be first word in BasicObjectLock");
|
||||
|
||||
Label fail;
|
||||
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, rscratch1, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Fast check for recursive lock.
|
||||
//
|
||||
// Can apply the optimization only if this is a stack lock
|
||||
// allocated in this thread. For efficiency, we can focus on
|
||||
// recently allocated stack locks (instead of reading the stack
|
||||
// base and checking whether 'mark' points inside the current
|
||||
// thread stack):
|
||||
// 1) (mark & 7) == 0, and
|
||||
// 2) sp <= mark < mark + os::pagesize()
|
||||
//
|
||||
// Warning: sp + os::pagesize can overflow the stack base. We must
|
||||
// neither apply the optimization for an inflated lock allocated
|
||||
// just above the thread stack (this is why condition 1 matters)
|
||||
// nor apply the optimization if the stack lock is inside the stack
|
||||
// of another thread. The latter is avoided even in case of overflow
|
||||
// because we have guard pages at the end of all stacks. Hence, if
|
||||
// we go over the stack base and hit the stack of another thread,
|
||||
// this should not be in a writeable area that could contain a
|
||||
// stack lock allocated by that thread. As a consequence, a stack
|
||||
// lock less than page size away from sp is guaranteed to be
|
||||
// owned by the current thread.
|
||||
//
|
||||
// These 3 tests can be done by evaluating the following
|
||||
// expression: ((mark - sp) & (7 - os::vm_page_size())),
|
||||
// assuming both stack pointer and pagesize have their
|
||||
// least significant 3 bits clear.
|
||||
// NOTE: the mark is in swap_reg %r0 as the result of cmpxchg
|
||||
// NOTE2: aarch64 does not like to subtract sp from rn so take a
|
||||
// copy
|
||||
mov(rscratch1, sp);
|
||||
sub(swap_reg, swap_reg, rscratch1);
|
||||
ands(swap_reg, swap_reg, (uint64_t)(7 - (int)os::vm_page_size()));
|
||||
|
||||
// Save the test result, for recursive case, the result is zero
|
||||
str(swap_reg, Address(lock_reg, mark_offset));
|
||||
br(Assembler::NE, slow_case);
|
||||
|
||||
bind(count);
|
||||
inc_held_monitor_count(rscratch1);
|
||||
b(done);
|
||||
}
|
||||
bind(slow_case);
|
||||
|
||||
// Call the runtime routine for slow case
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
bind(done);
|
||||
}
|
||||
|
||||
|
||||
|
@ -807,57 +730,29 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
|
|||
{
|
||||
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
} else {
|
||||
Label count, done;
|
||||
const Register swap_reg = r0;
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock
|
||||
|
||||
const Register swap_reg = r0;
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock
|
||||
save_bcp(); // Save in case of exception
|
||||
|
||||
save_bcp(); // Save in case of exception
|
||||
// Load oop into obj_reg(%c_rarg3)
|
||||
ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// Convert from BasicObjectLock structure to object and BasicLock
|
||||
// structure Store the BasicLock address into %r0
|
||||
lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
|
||||
}
|
||||
// Free entry
|
||||
str(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
// Load oop into obj_reg(%c_rarg3)
|
||||
ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
Label slow_case, done;
|
||||
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
|
||||
b(done);
|
||||
|
||||
// Free entry
|
||||
str(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
Label slow_case;
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
|
||||
b(done);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load the old header from BasicLock structure
|
||||
ldr(header_reg, Address(swap_reg,
|
||||
BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
// Test for recursion
|
||||
cbz(header_reg, count);
|
||||
|
||||
// Atomic swap back the old header
|
||||
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, count, &slow_case);
|
||||
|
||||
bind(count);
|
||||
dec_held_monitor_count(rscratch1);
|
||||
b(done);
|
||||
}
|
||||
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case.
|
||||
str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
bind(done);
|
||||
restore_bcp();
|
||||
}
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case.
|
||||
str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
bind(done);
|
||||
restore_bcp();
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
|
||||
|
|
|
@ -7101,7 +7101,6 @@ void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
|||
// - t1, t2, t3: temporary registers, will be destroyed
|
||||
// - slow: branched to if locking fails, absolute offset may larger than 32KB (imm14 encoding).
|
||||
void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Register t1, Register t2, Register t3, Label& slow) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
|
||||
assert_different_registers(basic_lock, obj, t1, t2, t3, rscratch1);
|
||||
|
||||
Label push;
|
||||
|
@ -7161,7 +7160,6 @@ void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Registe
|
|||
// - t1, t2, t3: temporary registers
|
||||
// - slow: branched to if unlocking fails, absolute offset may larger than 32KB (imm14 encoding).
|
||||
void MacroAssembler::lightweight_unlock(Register obj, Register t1, Register t2, Register t3, Label& slow) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
|
||||
// cmpxchg clobbers rscratch1.
|
||||
assert_different_registers(obj, t1, t2, t3, rscratch1);
|
||||
|
||||
|
|
|
@ -1721,7 +1721,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// We use the same pc/oopMap repeatedly when we call out.
|
||||
|
||||
Label native_return;
|
||||
if (LockingMode != LM_LEGACY && method->is_object_wait0()) {
|
||||
if (method->is_object_wait0()) {
|
||||
// For convenience we use the pc we want to resume to in case of preemption on Object.wait.
|
||||
__ set_last_Java_frame(sp, noreg, native_return, rscratch1);
|
||||
} else {
|
||||
|
@ -1776,44 +1776,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// Load the oop from the handle
|
||||
__ ldr(obj_reg, Address(oop_handle_reg, 0));
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ b(slow_path_lock);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load (object->mark() | 1) into swap_reg %r0
|
||||
__ ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
__ orr(swap_reg, rscratch1, 1);
|
||||
|
||||
// Save (object->mark() | 1) into BasicLock's displaced header
|
||||
__ str(swap_reg, Address(lock_reg, mark_word_offset));
|
||||
|
||||
// src -> dest iff dest == r0 else r0 <- dest
|
||||
__ cmpxchg_obj_header(r0, lock_reg, obj_reg, rscratch1, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Hmm should this move to the slow path code area???
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 3) == 0, and
|
||||
// 2) sp <= mark < mark + os::pagesize()
|
||||
// These 3 tests can be done by evaluating the following
|
||||
// expression: ((mark - sp) & (3 - os::vm_page_size())),
|
||||
// assuming both stack pointer and pagesize have their
|
||||
// least significant 2 bits clear.
|
||||
// NOTE: the oopMark is in swap_reg %r0 as the result of cmpxchg
|
||||
|
||||
__ sub(swap_reg, sp, swap_reg);
|
||||
__ neg(swap_reg, swap_reg);
|
||||
__ ands(swap_reg, swap_reg, 3 - (int)os::vm_page_size());
|
||||
|
||||
// Save the test result, for recursive case, the result is zero
|
||||
__ str(swap_reg, Address(lock_reg, mark_word_offset));
|
||||
__ br(Assembler::NE, slow_path_lock);
|
||||
|
||||
__ bind(count);
|
||||
__ inc_held_monitor_count(rscratch1);
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
__ lightweight_lock(lock_reg, obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
|
||||
}
|
||||
__ lightweight_lock(lock_reg, obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
|
||||
|
||||
// Slow path will re-enter here
|
||||
__ bind(lock_done);
|
||||
|
@ -1888,7 +1851,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
__ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
|
||||
__ stlrw(rscratch1, rscratch2);
|
||||
|
||||
if (LockingMode != LM_LEGACY && method->is_object_wait0()) {
|
||||
if (method->is_object_wait0()) {
|
||||
// Check preemption for Object.wait()
|
||||
__ ldr(rscratch1, Address(rthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ cbz(rscratch1, native_return);
|
||||
|
@ -1917,48 +1880,18 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// Get locked oop from the handle we passed to jni
|
||||
__ ldr(obj_reg, Address(oop_handle_reg, 0));
|
||||
|
||||
Label done, not_recursive;
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
// Simple recursive lock?
|
||||
__ ldr(rscratch1, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size));
|
||||
__ cbnz(rscratch1, not_recursive);
|
||||
__ dec_held_monitor_count(rscratch1);
|
||||
__ b(done);
|
||||
}
|
||||
|
||||
__ bind(not_recursive);
|
||||
|
||||
// Must save r0 if if it is live now because cmpxchg must use it
|
||||
if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
|
||||
save_native_result(masm, ret_type, stack_slots);
|
||||
}
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ b(slow_path_unlock);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// get address of the stack lock
|
||||
__ lea(r0, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size));
|
||||
// get old displaced header
|
||||
__ ldr(old_hdr, Address(r0, 0));
|
||||
|
||||
// Atomic swap old header if oop still contains the stack lock
|
||||
Label count;
|
||||
__ cmpxchg_obj_header(r0, old_hdr, obj_reg, rscratch1, count, &slow_path_unlock);
|
||||
__ bind(count);
|
||||
__ dec_held_monitor_count(rscratch1);
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "");
|
||||
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
|
||||
}
|
||||
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
|
||||
|
||||
// slow path re-enters here
|
||||
__ bind(unlock_done);
|
||||
if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
|
||||
restore_native_result(masm, ret_type, stack_slots);
|
||||
}
|
||||
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
Label dtrace_method_exit, dtrace_method_exit_done;
|
||||
|
|
|
@ -1478,22 +1478,17 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||
__ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
|
||||
__ stlrw(rscratch1, rscratch2);
|
||||
|
||||
if (LockingMode != LM_LEGACY) {
|
||||
// Check preemption for Object.wait()
|
||||
Label not_preempted;
|
||||
__ ldr(rscratch1, Address(rthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ cbz(rscratch1, not_preempted);
|
||||
__ str(zr, Address(rthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ br(rscratch1);
|
||||
__ bind(native_return);
|
||||
__ restore_after_resume(true /* is_native */);
|
||||
// reload result_handler
|
||||
__ ldr(result_handler, Address(rfp, frame::interpreter_frame_result_handler_offset*wordSize));
|
||||
__ bind(not_preempted);
|
||||
} else {
|
||||
// any pc will do so just use this one for LM_LEGACY to keep code together.
|
||||
__ bind(native_return);
|
||||
}
|
||||
// Check preemption for Object.wait()
|
||||
Label not_preempted;
|
||||
__ ldr(rscratch1, Address(rthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ cbz(rscratch1, not_preempted);
|
||||
__ str(zr, Address(rthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ br(rscratch1);
|
||||
__ bind(native_return);
|
||||
__ restore_after_resume(true /* is_native */);
|
||||
// reload result_handler
|
||||
__ ldr(result_handler, Address(rfp, frame::interpreter_frame_result_handler_offset*wordSize));
|
||||
__ bind(not_preempted);
|
||||
|
||||
// reset_last_Java_frame
|
||||
__ reset_last_Java_frame(true);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/formatBuffer.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
int VM_Version::_cpu;
|
||||
int VM_Version::_model;
|
||||
|
@ -50,6 +51,8 @@ uintptr_t VM_Version::_pac_mask;
|
|||
|
||||
SpinWait VM_Version::_spin_wait;
|
||||
|
||||
const char* VM_Version::_features_names[MAX_CPU_FEATURES] = { nullptr };
|
||||
|
||||
static SpinWait get_spin_wait_desc() {
|
||||
SpinWait spin_wait(OnSpinWaitInst, OnSpinWaitInstCount);
|
||||
if (spin_wait.inst() == SpinWait::SB && !VM_Version::supports_sb()) {
|
||||
|
@ -60,6 +63,11 @@ static SpinWait get_spin_wait_desc() {
|
|||
}
|
||||
|
||||
void VM_Version::initialize() {
|
||||
#define SET_CPU_FEATURE_NAME(id, name, bit) \
|
||||
_features_names[bit] = XSTR(name);
|
||||
CPU_FEATURE_FLAGS(SET_CPU_FEATURE_NAME)
|
||||
#undef SET_CPU_FEATURE_NAME
|
||||
|
||||
_supports_atomic_getset4 = true;
|
||||
_supports_atomic_getadd4 = true;
|
||||
_supports_atomic_getset8 = true;
|
||||
|
@ -194,7 +202,7 @@ void VM_Version::initialize() {
|
|||
|
||||
// Cortex A53
|
||||
if (_cpu == CPU_ARM && model_is(0xd03)) {
|
||||
_features |= CPU_A53MAC;
|
||||
set_feature(CPU_A53MAC);
|
||||
if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
|
||||
FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false);
|
||||
}
|
||||
|
@ -234,7 +242,7 @@ void VM_Version::initialize() {
|
|||
}
|
||||
}
|
||||
|
||||
if (_features & (CPU_FP | CPU_ASIMD)) {
|
||||
if (supports_feature(CPU_FP) || supports_feature(CPU_ASIMD)) {
|
||||
if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
|
||||
FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
|
||||
}
|
||||
|
@ -397,7 +405,7 @@ void VM_Version::initialize() {
|
|||
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
|
||||
}
|
||||
|
||||
if (_features & CPU_ASIMD) {
|
||||
if (supports_feature(CPU_ASIMD)) {
|
||||
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
|
||||
UseChaCha20Intrinsics = true;
|
||||
}
|
||||
|
@ -408,7 +416,7 @@ void VM_Version::initialize() {
|
|||
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
|
||||
}
|
||||
|
||||
if (_features & CPU_ASIMD) {
|
||||
if (supports_feature(CPU_ASIMD)) {
|
||||
if (FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
|
||||
UseKyberIntrinsics = true;
|
||||
}
|
||||
|
@ -419,7 +427,7 @@ void VM_Version::initialize() {
|
|||
FLAG_SET_DEFAULT(UseKyberIntrinsics, false);
|
||||
}
|
||||
|
||||
if (_features & CPU_ASIMD) {
|
||||
if (supports_feature(CPU_ASIMD)) {
|
||||
if (FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
|
||||
UseDilithiumIntrinsics = true;
|
||||
}
|
||||
|
@ -620,32 +628,38 @@ void VM_Version::initialize() {
|
|||
|
||||
// Sync SVE related CPU features with flags
|
||||
if (UseSVE < 2) {
|
||||
_features &= ~CPU_SVE2;
|
||||
_features &= ~CPU_SVEBITPERM;
|
||||
clear_feature(CPU_SVE2);
|
||||
clear_feature(CPU_SVEBITPERM);
|
||||
}
|
||||
if (UseSVE < 1) {
|
||||
_features &= ~CPU_SVE;
|
||||
clear_feature(CPU_SVE);
|
||||
}
|
||||
|
||||
// Construct the "features" string
|
||||
char buf[512];
|
||||
int buf_used_len = os::snprintf_checked(buf, sizeof(buf), "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
|
||||
stringStream ss(512);
|
||||
ss.print("0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
|
||||
if (_model2) {
|
||||
os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2);
|
||||
ss.print("(0x%03x)", _model2);
|
||||
}
|
||||
size_t features_offset = strnlen(buf, sizeof(buf));
|
||||
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) \
|
||||
do { \
|
||||
if (VM_Version::supports_##name()) strcat(buf, ", " #name); \
|
||||
} while(0);
|
||||
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
|
||||
#undef ADD_FEATURE_IF_SUPPORTED
|
||||
ss.print(", ");
|
||||
int features_offset = (int)ss.size();
|
||||
insert_features_names(_features, ss);
|
||||
|
||||
_cpu_info_string = os::strdup(buf);
|
||||
_cpu_info_string = ss.as_string(true);
|
||||
_features_string = _cpu_info_string + features_offset;
|
||||
}
|
||||
|
||||
_features_string = extract_features_string(_cpu_info_string,
|
||||
strnlen(_cpu_info_string, sizeof(buf)),
|
||||
features_offset);
|
||||
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++];
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return (const char*)nullptr;
|
||||
}, ", ");
|
||||
}
|
||||
|
||||
#if defined(LINUX)
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include "runtime/abstract_vm_version.hpp"
|
||||
#include "utilities/sizes.hpp"
|
||||
|
||||
class stringStream;
|
||||
|
||||
#define BIT_MASK(flag) (1ULL<<(flag))
|
||||
|
||||
class VM_Version : public Abstract_VM_Version {
|
||||
friend class VMStructs;
|
||||
friend class JVMCIVMStructs;
|
||||
|
@ -66,6 +70,8 @@ public:
|
|||
static void initialize();
|
||||
static void check_virtualizations();
|
||||
|
||||
static void insert_features_names(uint64_t features, stringStream& ss);
|
||||
|
||||
static void print_platform_virtualization_info(outputStream*);
|
||||
|
||||
// Asserts
|
||||
|
@ -139,17 +145,32 @@ enum Ampere_CPU_Model {
|
|||
decl(A53MAC, a53mac, 31)
|
||||
|
||||
enum Feature_Flag {
|
||||
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit),
|
||||
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = bit,
|
||||
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
|
||||
#undef DECLARE_CPU_FEATURE_FLAG
|
||||
MAX_CPU_FEATURES
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(_features) * BitsPerByte >= MAX_CPU_FEATURES);
|
||||
|
||||
static const char* _features_names[MAX_CPU_FEATURES];
|
||||
|
||||
// Feature identification
|
||||
#define CPU_FEATURE_DETECTION(id, name, bit) \
|
||||
static bool supports_##name() { return (_features & CPU_##id) != 0; };
|
||||
static bool supports_##name() { return supports_feature(CPU_##id); }
|
||||
CPU_FEATURE_FLAGS(CPU_FEATURE_DETECTION)
|
||||
#undef CPU_FEATURE_DETECTION
|
||||
|
||||
static void set_feature(Feature_Flag flag) {
|
||||
_features |= BIT_MASK(flag);
|
||||
}
|
||||
static void clear_feature(Feature_Flag flag) {
|
||||
_features &= (~BIT_MASK(flag));
|
||||
}
|
||||
static bool supports_feature(Feature_Flag flag) {
|
||||
return (_features & BIT_MASK(flag)) != 0;
|
||||
}
|
||||
|
||||
static int cpu_family() { return _cpu; }
|
||||
static int cpu_model() { return _model; }
|
||||
static int cpu_model2() { return _model2; }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
|
@ -95,8 +95,6 @@
|
|||
}
|
||||
|
||||
static int adjust_reg_range(int range) {
|
||||
// Reduce the number of available regs (to free Rheap_base) in case of compressed oops
|
||||
if (UseCompressedOops || UseCompressedClassPointers) return range - 1;
|
||||
return range;
|
||||
}
|
||||
|
||||
|
|
|
@ -2229,16 +2229,9 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||
// We don't know the array types are compatible
|
||||
if (basic_type != T_OBJECT) {
|
||||
// Simple test for basic type arrays
|
||||
if (UseCompressedClassPointers) {
|
||||
// We don't need decode because we just need to compare
|
||||
__ ldr_u32(tmp, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
__ ldr_u32(tmp2, Address(dst, oopDesc::klass_offset_in_bytes()));
|
||||
__ cmp_32(tmp, tmp2);
|
||||
} else {
|
||||
__ load_klass(tmp, src);
|
||||
__ load_klass(tmp2, dst);
|
||||
__ cmp(tmp, tmp2);
|
||||
}
|
||||
__ load_klass(tmp, src);
|
||||
__ load_klass(tmp2, dst);
|
||||
__ cmp(tmp, tmp2);
|
||||
__ b(*stub->entry(), ne);
|
||||
} else {
|
||||
// For object arrays, if src is a sub class of dst then we can
|
||||
|
@ -2461,12 +2454,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
|
|||
if (info != nullptr) {
|
||||
add_debug_info_for_null_check_here(info);
|
||||
}
|
||||
|
||||
if (UseCompressedClassPointers) { // On 32 bit arm??
|
||||
__ ldr_u32(result, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
} else {
|
||||
__ ldr(result, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
__ ldr(result, Address(obj, oopDesc::klass_offset_in_bytes()));
|
||||
}
|
||||
|
||||
void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
|
||||
|
|
|
@ -174,6 +174,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||
break;
|
||||
case Interpreter::java_lang_math_fmaD:
|
||||
case Interpreter::java_lang_math_fmaF:
|
||||
case Interpreter::java_lang_math_sinh:
|
||||
case Interpreter::java_lang_math_tanh:
|
||||
case Interpreter::java_lang_math_cbrt:
|
||||
// TODO: Implement intrinsic
|
||||
|
|
|
@ -1089,6 +1089,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||
case Interpreter::java_lang_math_sin : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break;
|
||||
case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break;
|
||||
case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break;
|
||||
case Interpreter::java_lang_math_sinh : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_tanh : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_cbrt : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_abs : /* run interpreted */ break;
|
||||
|
|
|
@ -339,11 +339,7 @@ int LIR_Assembler::emit_unwind_handler() {
|
|||
if (method()->is_synchronized()) {
|
||||
monitor_address(0, FrameMap::r10_opr);
|
||||
stub = new MonitorExitStub(FrameMap::r10_opr, true, 0);
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ j(*stub->entry());
|
||||
} else {
|
||||
__ unlock_object(x15, x14, x10, x16, *stub->entry());
|
||||
}
|
||||
__ unlock_object(x15, x14, x10, x16, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
|
@ -1497,13 +1493,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
|||
Register hdr = op->hdr_opr()->as_register();
|
||||
Register lock = op->lock_opr()->as_register();
|
||||
Register temp = op->scratch_opr()->as_register();
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check_here(op->info());
|
||||
__ null_check(obj, -1);
|
||||
}
|
||||
__ j(*op->stub()->entry());
|
||||
} else if (op->code() == lir_lock) {
|
||||
if (op->code() == lir_lock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
// add debug info for NullPointerException only if one is possible
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry());
|
||||
|
@ -1831,7 +1821,7 @@ void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, C
|
|||
}
|
||||
|
||||
LIR_Address* adr = addr->as_address_ptr();
|
||||
Register dst = dest->as_register_lo();
|
||||
Register dst = dest->as_pointer_register();
|
||||
|
||||
assert_different_registers(dst, t0);
|
||||
if (adr->base()->is_valid() && dst == adr->base()->as_pointer_register() && (!adr->index()->is_cpu_register())) {
|
||||
|
|
|
@ -837,7 +837,7 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
|
|||
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
|
||||
const LIR_Opr result_reg = result_register_for(x->type());
|
||||
|
||||
LIR_Opr addr = new_pointer_register();
|
||||
LIR_Opr addr = new_register(T_ADDRESS);
|
||||
__ leal(LIR_OprFact::address(a), addr);
|
||||
|
||||
crc.load_item_force(cc->at(0));
|
||||
|
|
|
@ -49,8 +49,6 @@ void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
|
|||
}
|
||||
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord - 1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
|
||||
int null_check_offset = -1;
|
||||
|
||||
|
@ -61,97 +59,19 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
|||
|
||||
null_check_offset = offset();
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(disp_hdr, obj, hdr, temp, t1, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(hdr, obj);
|
||||
lbu(hdr, Address(hdr, Klass::misc_flags_offset()));
|
||||
test_bit(temp, hdr, exact_log2(KlassFlags::_misc_is_value_based_class));
|
||||
bnez(temp, slow_case, /* is_far */ true);
|
||||
}
|
||||
|
||||
Label done;
|
||||
// Load object header
|
||||
ld(hdr, Address(obj, hdr_offset));
|
||||
// and mark it as unlocked
|
||||
ori(hdr, hdr, markWord::unlocked_value);
|
||||
// save unlocked object header into the displaced header location on the stack
|
||||
sd(hdr, Address(disp_hdr, 0));
|
||||
// test if object header is still the same (i.e. unlocked), and if so, store the
|
||||
// displaced header address in the object header - if it is not the same, get the
|
||||
// object header instead
|
||||
la(temp, Address(obj, hdr_offset));
|
||||
// if the object header was the same, we're done
|
||||
cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
|
||||
// if the object header was not the same, it is now in the hdr register
|
||||
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
|
||||
//
|
||||
// 1) (hdr & aligned_mask) == 0
|
||||
// 2) sp <= hdr
|
||||
// 3) hdr <= sp + page_size
|
||||
//
|
||||
// these 3 tests can be done by evaluating the following expression:
|
||||
//
|
||||
// (hdr -sp) & (aligned_mask - page_size)
|
||||
//
|
||||
// assuming both the stack pointer and page_size have their least
|
||||
// significant 2 bits cleared and page_size is a power of 2
|
||||
sub(hdr, hdr, sp);
|
||||
mv(temp, aligned_mask - (int)os::vm_page_size());
|
||||
andr(hdr, hdr, temp);
|
||||
// for recursive locking, the result is zero => save it in the displaced header
|
||||
// location (null in the displaced hdr location indicates recursive locking)
|
||||
sd(hdr, Address(disp_hdr, 0));
|
||||
// otherwise we don't care about the result and handle locking via runtime call
|
||||
bnez(hdr, slow_case, /* is_far */ true);
|
||||
|
||||
// done
|
||||
bind(done);
|
||||
inc_held_monitor_count(t0);
|
||||
}
|
||||
lightweight_lock(disp_hdr, obj, hdr, temp, t1, slow_case);
|
||||
|
||||
return null_check_offset;
|
||||
}
|
||||
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord - 1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
|
||||
Label done;
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// load displaced header
|
||||
ld(hdr, Address(disp_hdr, 0));
|
||||
// if the loaded hdr is null we had recursive locking
|
||||
// if we had recursive locking, we are done
|
||||
beqz(hdr, done);
|
||||
}
|
||||
|
||||
// load object
|
||||
ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
verify_oop(obj);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_unlock(obj, hdr, temp, t1, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// test if object header is pointing to the displaced header, and if so, restore
|
||||
// the displaced header in the object - if the object header is not pointing to
|
||||
// the displaced header, get the object header instead
|
||||
// if the object header was not pointing to the displaced header,
|
||||
// we do unlocking via runtime call
|
||||
if (hdr_offset) {
|
||||
la(temp, Address(obj, hdr_offset));
|
||||
cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case);
|
||||
} else {
|
||||
cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
|
||||
}
|
||||
|
||||
// done
|
||||
bind(done);
|
||||
dec_held_monitor_count(t0);
|
||||
}
|
||||
lightweight_unlock(obj, hdr, temp, t1, slow_case);
|
||||
}
|
||||
|
||||
// Defines obj, preserves var_size_in_bytes
|
||||
|
|
|
@ -43,240 +43,11 @@
|
|||
|
||||
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
|
||||
|
||||
void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg,
|
||||
Register tmp1Reg, Register tmp2Reg, Register tmp3Reg, Register tmp4Reg) {
|
||||
// Use cr register to indicate the fast_lock result: zero for success; non-zero for failure.
|
||||
Register flag = t1;
|
||||
Register oop = objectReg;
|
||||
Register box = boxReg;
|
||||
Register disp_hdr = tmp1Reg;
|
||||
Register tmp = tmp2Reg;
|
||||
Label object_has_monitor;
|
||||
// Finish fast lock successfully. MUST branch to with flag == 0
|
||||
Label locked;
|
||||
// Finish fast lock unsuccessfully. slow_path MUST branch to with flag != 0
|
||||
Label slow_path;
|
||||
|
||||
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
|
||||
assert_different_registers(oop, box, tmp, disp_hdr, flag, tmp3Reg, t0);
|
||||
|
||||
mv(flag, 1);
|
||||
|
||||
// Load markWord from object into displaced_header.
|
||||
ld(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, oop);
|
||||
lbu(tmp, Address(tmp, Klass::misc_flags_offset()));
|
||||
test_bit(tmp, tmp, exact_log2(KlassFlags::_misc_is_value_based_class));
|
||||
bnez(tmp, slow_path);
|
||||
}
|
||||
|
||||
// Check for existing monitor
|
||||
test_bit(tmp, disp_hdr, exact_log2(markWord::monitor_value));
|
||||
bnez(tmp, object_has_monitor);
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
j(slow_path);
|
||||
} else {
|
||||
assert(LockingMode == LM_LEGACY, "must be");
|
||||
// Set tmp to be (markWord of object | UNLOCK_VALUE).
|
||||
ori(tmp, disp_hdr, markWord::unlocked_value);
|
||||
|
||||
// Initialize the box. (Must happen before we update the object mark!)
|
||||
sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
// Compare object markWord with an unlocked value (tmp) and if
|
||||
// equal exchange the stack address of our box with object markWord.
|
||||
// On failure disp_hdr contains the possibly locked markWord.
|
||||
cmpxchg(/*memory address*/oop, /*expected value*/tmp, /*new value*/box, Assembler::int64,
|
||||
Assembler::aq, Assembler::rl, /*result*/disp_hdr);
|
||||
beq(disp_hdr, tmp, locked);
|
||||
|
||||
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
|
||||
|
||||
// If the compare-and-exchange succeeded, then we found an unlocked
|
||||
// object, will have now locked it will continue at label locked
|
||||
// We did not see an unlocked object so try the fast recursive case.
|
||||
|
||||
// Check if the owner is self by comparing the value in the
|
||||
// markWord of object (disp_hdr) with the stack pointer.
|
||||
sub(disp_hdr, disp_hdr, sp);
|
||||
mv(tmp, (intptr_t) (~(os::vm_page_size()-1) | (uintptr_t)markWord::lock_mask_in_place));
|
||||
// If (mark & lock_mask) == 0 and mark - sp < page_size, we are stack-locking and goto label
|
||||
// locked, hence we can store 0 as the displaced header in the box, which indicates that it
|
||||
// is a recursive lock.
|
||||
andr(tmp/*==0?*/, disp_hdr, tmp);
|
||||
sd(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
beqz(tmp, locked);
|
||||
j(slow_path);
|
||||
}
|
||||
|
||||
// Handle existing monitor.
|
||||
bind(object_has_monitor);
|
||||
|
||||
// Try to CAS owner (no owner => current thread's _monitor_owner_id).
|
||||
add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset()) - markWord::monitor_value));
|
||||
Register tid = tmp4Reg;
|
||||
ld(tid, Address(xthread, JavaThread::monitor_owner_id_offset()));
|
||||
cmpxchg(/*memory address*/tmp, /*expected value*/zr, /*new value*/tid, Assembler::int64,
|
||||
Assembler::aq, Assembler::rl, /*result*/tmp3Reg); // cas succeeds if tmp3Reg == zr(expected)
|
||||
|
||||
// Store a non-null value into the box to avoid looking like a re-entrant
|
||||
// lock. The fast-path monitor unlock code checks for
|
||||
// markWord::monitor_value so use markWord::unused_mark which has the
|
||||
// relevant bit set, and also matches ObjectSynchronizer::slow_enter.
|
||||
mv(tmp, (address)markWord::unused_mark().value());
|
||||
sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
beqz(tmp3Reg, locked); // CAS success means locking succeeded
|
||||
|
||||
bne(tmp3Reg, tid, slow_path); // Check for recursive locking
|
||||
|
||||
// Recursive lock case
|
||||
increment(Address(disp_hdr, in_bytes(ObjectMonitor::recursions_offset()) - markWord::monitor_value), 1, tmp2Reg, tmp3Reg);
|
||||
|
||||
bind(locked);
|
||||
mv(flag, zr);
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
inc_held_monitor_count(t0);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// Check that locked label is reached with flag == 0.
|
||||
Label flag_correct;
|
||||
beqz(flag, flag_correct);
|
||||
stop("Fast Lock Flag != 0");
|
||||
#endif
|
||||
|
||||
bind(slow_path);
|
||||
#ifdef ASSERT
|
||||
// Check that slow_path label is reached with flag != 0.
|
||||
bnez(flag, flag_correct);
|
||||
stop("Fast Lock Flag == 0");
|
||||
bind(flag_correct);
|
||||
#endif
|
||||
// C2 uses the value of flag (0 vs !0) to determine the continuation.
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg,
|
||||
Register tmp1Reg, Register tmp2Reg) {
|
||||
// Use cr register to indicate the fast_unlock result: zero for success; non-zero for failure.
|
||||
Register flag = t1;
|
||||
Register oop = objectReg;
|
||||
Register box = boxReg;
|
||||
Register disp_hdr = tmp1Reg;
|
||||
Register owner_addr = tmp1Reg;
|
||||
Register tmp = tmp2Reg;
|
||||
Label object_has_monitor;
|
||||
// Finish fast lock successfully. MUST branch to with flag == 0
|
||||
Label unlocked;
|
||||
// Finish fast lock unsuccessfully. slow_path MUST branch to with flag != 0
|
||||
Label slow_path;
|
||||
|
||||
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_unlock_lightweight");
|
||||
assert_different_registers(oop, box, tmp, disp_hdr, flag, t0);
|
||||
|
||||
mv(flag, 1);
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
// Find the lock address and load the displaced header from the stack.
|
||||
ld(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
// If the displaced header is 0, we have a recursive unlock.
|
||||
beqz(disp_hdr, unlocked);
|
||||
}
|
||||
|
||||
// Handle existing monitor.
|
||||
ld(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
|
||||
test_bit(t0, tmp, exact_log2(markWord::monitor_value));
|
||||
bnez(t0, object_has_monitor);
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
j(slow_path);
|
||||
} else {
|
||||
assert(LockingMode == LM_LEGACY, "must be");
|
||||
// Check if it is still a light weight lock, this is true if we
|
||||
// see the stack address of the basicLock in the markWord of the
|
||||
// object.
|
||||
|
||||
cmpxchg(/*memory address*/oop, /*expected value*/box, /*new value*/disp_hdr, Assembler::int64,
|
||||
Assembler::relaxed, Assembler::rl, /*result*/tmp);
|
||||
beq(box, tmp, unlocked); // box == tmp if cas succeeds
|
||||
j(slow_path);
|
||||
}
|
||||
|
||||
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
|
||||
|
||||
// Handle existing monitor.
|
||||
bind(object_has_monitor);
|
||||
subi(tmp, tmp, (int)markWord::monitor_value); // monitor
|
||||
ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset()));
|
||||
|
||||
Label notRecursive;
|
||||
beqz(disp_hdr, notRecursive); // Will be 0 if not recursive.
|
||||
|
||||
// Recursive lock
|
||||
subi(disp_hdr, disp_hdr, 1);
|
||||
sd(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset()));
|
||||
j(unlocked);
|
||||
|
||||
bind(notRecursive);
|
||||
// Compute owner address.
|
||||
la(owner_addr, Address(tmp, ObjectMonitor::owner_offset()));
|
||||
|
||||
// Set owner to null.
|
||||
// Release to satisfy the JMM
|
||||
membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
|
||||
sd(zr, Address(owner_addr));
|
||||
// We need a full fence after clearing owner to avoid stranding.
|
||||
// StoreLoad achieves this.
|
||||
membar(StoreLoad);
|
||||
|
||||
// Check if the entry_list is empty.
|
||||
ld(t0, Address(tmp, ObjectMonitor::entry_list_offset()));
|
||||
beqz(t0, unlocked); // If so we are done.
|
||||
|
||||
// Check if there is a successor.
|
||||
ld(t0, Address(tmp, ObjectMonitor::succ_offset()));
|
||||
bnez(t0, unlocked); // If so we are done.
|
||||
|
||||
// Save the monitor pointer in the current thread, so we can try to
|
||||
// reacquire the lock in SharedRuntime::monitor_exit_helper().
|
||||
sd(tmp, Address(xthread, JavaThread::unlocked_inflated_monitor_offset()));
|
||||
|
||||
mv(flag, 1);
|
||||
j(slow_path);
|
||||
|
||||
bind(unlocked);
|
||||
mv(flag, zr);
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
dec_held_monitor_count(t0);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// Check that unlocked label is reached with flag == 0.
|
||||
Label flag_correct;
|
||||
beqz(flag, flag_correct);
|
||||
stop("Fast Lock Flag != 0");
|
||||
#endif
|
||||
|
||||
bind(slow_path);
|
||||
#ifdef ASSERT
|
||||
// Check that slow_path label is reached with flag != 0.
|
||||
bnez(flag, flag_correct);
|
||||
stop("Fast Lock Flag == 0");
|
||||
bind(flag_correct);
|
||||
#endif
|
||||
// C2 uses the value of flag (0 vs !0) to determine the continuation.
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box,
|
||||
Register tmp1, Register tmp2, Register tmp3, Register tmp4) {
|
||||
// Flag register, zero for success; non-zero for failure.
|
||||
Register flag = t1;
|
||||
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
assert_different_registers(obj, box, tmp1, tmp2, tmp3, tmp4, flag, t0);
|
||||
|
||||
mv(flag, 1);
|
||||
|
@ -439,7 +210,6 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box,
|
|||
// Flag register, zero for success; non-zero for failure.
|
||||
Register flag = t1;
|
||||
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
assert_different_registers(obj, box, tmp1, tmp2, tmp3, flag, t0);
|
||||
|
||||
mv(flag, 1);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2025, 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.
|
||||
*
|
||||
|
@ -49,11 +49,6 @@
|
|||
const int STUB_THRESHOLD, Label *STUB, Label *DONE);
|
||||
|
||||
public:
|
||||
// Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
|
||||
void fast_lock(Register object, Register box,
|
||||
Register tmp1, Register tmp2, Register tmp3, Register tmp4);
|
||||
void fast_unlock(Register object, Register box, Register tmp1, Register tmp2);
|
||||
|
||||
// Code used by cmpFastLockLightweight and cmpFastUnlockLightweight mach instructions in .ad file.
|
||||
void fast_lock_lightweight(Register object, Register box,
|
||||
Register tmp1, Register tmp2, Register tmp3, Register tmp4);
|
||||
|
|
|
@ -733,84 +733,26 @@ void InterpreterMacroAssembler::leave_jfr_critical_section() {
|
|||
void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
{
|
||||
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
} else {
|
||||
Label count, done;
|
||||
|
||||
const Register swap_reg = x10;
|
||||
const Register tmp = c_rarg2;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp2 = c_rarg4;
|
||||
const Register tmp3 = c_rarg5;
|
||||
const Register tmp = c_rarg2;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp2 = c_rarg4;
|
||||
const Register tmp3 = c_rarg5;
|
||||
|
||||
const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
|
||||
const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
|
||||
const int mark_offset = lock_offset +
|
||||
BasicLock::displaced_header_offset_in_bytes();
|
||||
// Load object pointer into obj_reg (c_rarg3)
|
||||
ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
Label slow_case;
|
||||
Label done, slow_case;
|
||||
lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
|
||||
j(done);
|
||||
|
||||
// Load object pointer into obj_reg c_rarg3
|
||||
ld(obj_reg, Address(lock_reg, obj_offset));
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
|
||||
j(done);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, obj_reg);
|
||||
lbu(tmp, Address(tmp, Klass::misc_flags_offset()));
|
||||
test_bit(tmp, tmp, exact_log2(KlassFlags::_misc_is_value_based_class));
|
||||
bnez(tmp, slow_case);
|
||||
}
|
||||
|
||||
// Load (object->mark() | 1) into swap_reg
|
||||
ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
ori(swap_reg, t0, 1);
|
||||
|
||||
// Save (object->mark() | 1) into BasicLock's displaced header
|
||||
sd(swap_reg, Address(lock_reg, mark_offset));
|
||||
|
||||
assert(lock_offset == 0,
|
||||
"displached header must be first word in BasicObjectLock");
|
||||
|
||||
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, tmp, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 7) == 0, and
|
||||
// 2) sp <= mark < mark + os::pagesize()
|
||||
//
|
||||
// These 3 tests can be done by evaluating the following
|
||||
// expression: ((mark - sp) & (7 - os::vm_page_size())),
|
||||
// assuming both stack pointer and pagesize have their
|
||||
// least significant 3 bits clear.
|
||||
// NOTE: the oopMark is in swap_reg x10 as the result of cmpxchg
|
||||
sub(swap_reg, swap_reg, sp);
|
||||
mv(t0, (int64_t)(7 - (int)os::vm_page_size()));
|
||||
andr(swap_reg, swap_reg, t0);
|
||||
|
||||
// Save the test result, for recursive case, the result is zero
|
||||
sd(swap_reg, Address(lock_reg, mark_offset));
|
||||
bnez(swap_reg, slow_case);
|
||||
|
||||
bind(count);
|
||||
inc_held_monitor_count(t0);
|
||||
j(done);
|
||||
}
|
||||
|
||||
bind(slow_case);
|
||||
|
||||
// Call the runtime routine for slow case
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
bind(done);
|
||||
}
|
||||
|
||||
|
||||
|
@ -829,58 +771,30 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
|
|||
{
|
||||
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
} else {
|
||||
Label count, done;
|
||||
const Register swap_reg = x10;
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock
|
||||
|
||||
const Register swap_reg = x10;
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock
|
||||
save_bcp(); // Save in case of exception
|
||||
|
||||
save_bcp(); // Save in case of exception
|
||||
// Load oop into obj_reg (c_rarg3)
|
||||
ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// Convert from BasicObjectLock structure to object and BasicLock
|
||||
// structure Store the BasicLock address into x10
|
||||
la(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
|
||||
}
|
||||
// Free entry
|
||||
sd(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
// Load oop into obj_reg(c_rarg3)
|
||||
ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
Label done, slow_case;
|
||||
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
|
||||
j(done);
|
||||
|
||||
// Free entry
|
||||
sd(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case.
|
||||
sd(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
|
||||
Label slow_case;
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
|
||||
j(done);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load the old header from BasicLock structure
|
||||
ld(header_reg, Address(swap_reg,
|
||||
BasicLock::displaced_header_offset_in_bytes()));
|
||||
|
||||
// Test for recursion
|
||||
beqz(header_reg, count);
|
||||
|
||||
// Atomic swap back the old header
|
||||
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, tmp_reg, count, &slow_case);
|
||||
|
||||
bind(count);
|
||||
dec_held_monitor_count(t0);
|
||||
j(done);
|
||||
}
|
||||
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case.
|
||||
sd(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
|
||||
bind(done);
|
||||
restore_bcp();
|
||||
}
|
||||
bind(done);
|
||||
restore_bcp();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6421,7 +6421,6 @@ void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) {
|
|||
// - tmp1, tmp2, tmp3: temporary registers, will be destroyed
|
||||
// - slow: branched to if locking fails
|
||||
void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Register tmp1, Register tmp2, Register tmp3, Label& slow) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
|
||||
assert_different_registers(basic_lock, obj, tmp1, tmp2, tmp3, t0);
|
||||
|
||||
Label push;
|
||||
|
@ -6481,7 +6480,6 @@ void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Registe
|
|||
// - tmp1, tmp2, tmp3: temporary registers
|
||||
// - slow: branched to if unlocking fails
|
||||
void MacroAssembler::lightweight_unlock(Register obj, Register tmp1, Register tmp2, Register tmp3, Label& slow) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
|
||||
assert_different_registers(obj, tmp1, tmp2, tmp3, t0);
|
||||
|
||||
#ifdef ASSERT
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
// Copyright (c) 2020, 2024, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
@ -11021,45 +11021,9 @@ instruct tlsLoadP(javaThread_RegP dst)
|
|||
|
||||
// inlined locking and unlocking
|
||||
// using t1 as the 'flag' register to bridge the BoolNode producers and consumers
|
||||
instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box,
|
||||
iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4)
|
||||
%{
|
||||
predicate(LockingMode != LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4);
|
||||
|
||||
ins_cost(10 * DEFAULT_COST);
|
||||
format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3,$tmp4 #@cmpFastLock" %}
|
||||
|
||||
ins_encode %{
|
||||
__ fast_lock($object$$Register, $box$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
// using t1 as the 'flag' register to bridge the BoolNode producers and consumers
|
||||
instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2)
|
||||
%{
|
||||
predicate(LockingMode != LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastUnlock object box));
|
||||
effect(TEMP tmp1, TEMP tmp2);
|
||||
|
||||
ins_cost(10 * DEFAULT_COST);
|
||||
format %{ "fastunlock $object,$box\t! kills $tmp1, $tmp2, #@cmpFastUnlock" %}
|
||||
|
||||
ins_encode %{
|
||||
__ fast_unlock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box,
|
||||
iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4)
|
||||
%{
|
||||
predicate(LockingMode == LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4);
|
||||
|
||||
|
@ -11074,10 +11038,10 @@ instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box,
|
|||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
// using t1 as the 'flag' register to bridge the BoolNode producers and consumers
|
||||
instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box,
|
||||
iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3)
|
||||
%{
|
||||
predicate(LockingMode == LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastUnlock object box));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
|
||||
|
||||
|
|
|
@ -1637,7 +1637,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// We use the same pc/oopMap repeatedly when we call out.
|
||||
|
||||
Label native_return;
|
||||
if (LockingMode != LM_LEGACY && method->is_object_wait0()) {
|
||||
if (method->is_object_wait0()) {
|
||||
// For convenience we use the pc we want to resume to in case of preemption on Object.wait.
|
||||
__ set_last_Java_frame(sp, noreg, native_return, t0);
|
||||
} else {
|
||||
|
@ -1679,8 +1679,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
Label lock_done;
|
||||
|
||||
if (method->is_synchronized()) {
|
||||
Label count;
|
||||
|
||||
const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes();
|
||||
|
||||
// Get the handle (the 2nd argument)
|
||||
|
@ -1693,42 +1691,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// Load the oop from the handle
|
||||
__ ld(obj_reg, Address(oop_handle_reg, 0));
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ j(slow_path_lock);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load (object->mark() | 1) into swap_reg % x10
|
||||
__ ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
__ ori(swap_reg, t0, 1);
|
||||
|
||||
// Save (object->mark() | 1) into BasicLock's displaced header
|
||||
__ sd(swap_reg, Address(lock_reg, mark_word_offset));
|
||||
|
||||
// src -> dest if dest == x10 else x10 <- dest
|
||||
__ cmpxchg_obj_header(x10, lock_reg, obj_reg, lock_tmp, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 3) == 0, and
|
||||
// 2) sp <= mark < mark + os::pagesize()
|
||||
// These 3 tests can be done by evaluating the following
|
||||
// expression: ((mark - sp) & (3 - os::vm_page_size())),
|
||||
// assuming both stack pointer and pagesize have their
|
||||
// least significant 2 bits clear.
|
||||
// NOTE: the oopMark is in swap_reg % 10 as the result of cmpxchg
|
||||
|
||||
__ sub(swap_reg, swap_reg, sp);
|
||||
__ mv(t0, 3 - (int)os::vm_page_size());
|
||||
__ andr(swap_reg, swap_reg, t0);
|
||||
|
||||
// Save the test result, for recursive case, the result is zero
|
||||
__ sd(swap_reg, Address(lock_reg, mark_word_offset));
|
||||
__ bnez(swap_reg, slow_path_lock);
|
||||
|
||||
__ bind(count);
|
||||
__ inc_held_monitor_count(t0);
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
__ lightweight_lock(lock_reg, obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
|
||||
}
|
||||
__ lightweight_lock(lock_reg, obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
|
||||
|
||||
// Slow path will re-enter here
|
||||
__ bind(lock_done);
|
||||
|
@ -1789,7 +1752,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
__ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
|
||||
__ sw(t0, Address(t1));
|
||||
|
||||
if (LockingMode != LM_LEGACY && method->is_object_wait0()) {
|
||||
if (method->is_object_wait0()) {
|
||||
// Check preemption for Object.wait()
|
||||
__ ld(t1, Address(xthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ beqz(t1, native_return);
|
||||
|
@ -1818,48 +1781,18 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// Get locked oop from the handle we passed to jni
|
||||
__ ld(obj_reg, Address(oop_handle_reg, 0));
|
||||
|
||||
Label done, not_recursive;
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
// Simple recursive lock?
|
||||
__ ld(t0, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size));
|
||||
__ bnez(t0, not_recursive);
|
||||
__ dec_held_monitor_count(t0);
|
||||
__ j(done);
|
||||
}
|
||||
|
||||
__ bind(not_recursive);
|
||||
|
||||
// Must save x10 if if it is live now because cmpxchg must use it
|
||||
if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
|
||||
save_native_result(masm, ret_type, stack_slots);
|
||||
}
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ j(slow_path_unlock);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// get address of the stack lock
|
||||
__ la(x10, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size));
|
||||
// get old displaced header
|
||||
__ ld(old_hdr, Address(x10, 0));
|
||||
|
||||
// Atomic swap old header if oop still contains the stack lock
|
||||
Label count;
|
||||
__ cmpxchg_obj_header(x10, old_hdr, obj_reg, lock_tmp, count, &slow_path_unlock);
|
||||
__ bind(count);
|
||||
__ dec_held_monitor_count(t0);
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "");
|
||||
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
|
||||
}
|
||||
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
|
||||
|
||||
// slow path re-enters here
|
||||
__ bind(unlock_done);
|
||||
if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
|
||||
restore_native_result(masm, ret_type, stack_slots);
|
||||
}
|
||||
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
Label dtrace_method_exit, dtrace_method_exit_done;
|
||||
|
|
|
@ -1253,22 +1253,17 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||
__ mv(t0, _thread_in_Java);
|
||||
__ sw(t0, Address(xthread, JavaThread::thread_state_offset()));
|
||||
|
||||
if (LockingMode != LM_LEGACY) {
|
||||
// Check preemption for Object.wait()
|
||||
Label not_preempted;
|
||||
__ ld(t1, Address(xthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ beqz(t1, not_preempted);
|
||||
__ sd(zr, Address(xthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ jr(t1);
|
||||
__ bind(native_return);
|
||||
__ restore_after_resume(true /* is_native */);
|
||||
// reload result_handler
|
||||
__ ld(result_handler, Address(fp, frame::interpreter_frame_result_handler_offset * wordSize));
|
||||
__ bind(not_preempted);
|
||||
} else {
|
||||
// any pc will do so just use this one for LM_LEGACY to keep code together.
|
||||
__ bind(native_return);
|
||||
}
|
||||
// Check preemption for Object.wait()
|
||||
Label not_preempted;
|
||||
__ ld(t1, Address(xthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ beqz(t1, not_preempted);
|
||||
__ sd(zr, Address(xthread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ jr(t1);
|
||||
__ bind(native_return);
|
||||
__ restore_after_resume(true /* is_native */);
|
||||
// reload result_handler
|
||||
__ ld(result_handler, Address(fp, frame::interpreter_frame_result_handler_offset * wordSize));
|
||||
__ bind(not_preempted);
|
||||
|
||||
// reset_last_Java_frame
|
||||
__ reset_last_Java_frame(true);
|
||||
|
|
|
@ -1239,6 +1239,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||
case Interpreter::java_lang_math_sin : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break;
|
||||
case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break;
|
||||
case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break;
|
||||
case Interpreter::java_lang_math_sinh : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_tanh : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_cbrt : /* run interpreted */ break;
|
||||
case Interpreter::java_lang_math_abs : /* run interpreted */ break;
|
||||
|
|
|
@ -413,11 +413,7 @@ int LIR_Assembler::emit_unwind_handler() {
|
|||
if (method()->is_synchronized()) {
|
||||
monitor_address(0, FrameMap::rax_opr);
|
||||
stub = new MonitorExitStub(FrameMap::rax_opr, true, 0);
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ jmp(*stub->entry());
|
||||
} else {
|
||||
__ unlock_object(rdi, rsi, rax, *stub->entry());
|
||||
}
|
||||
__ unlock_object(rdi, rsi, rax, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
|
@ -2733,15 +2729,9 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
|||
Register obj = op->obj_opr()->as_register(); // may not be an oop
|
||||
Register hdr = op->hdr_opr()->as_register();
|
||||
Register lock = op->lock_opr()->as_register();
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check_here(op->info());
|
||||
__ null_check(obj);
|
||||
}
|
||||
__ jmp(*op->stub()->entry());
|
||||
} else if (op->code() == lir_lock) {
|
||||
if (op->code() == lir_lock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
Register tmp = LockingMode == LM_LIGHTWEIGHT ? op->scratch_opr()->as_register() : noreg;
|
||||
Register tmp = op->scratch_opr()->as_register();
|
||||
// add debug info for NullPointerException only if one is possible
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, tmp, *op->stub()->entry());
|
||||
if (op->info() != nullptr) {
|
||||
|
|
|
@ -289,7 +289,7 @@ void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
|
|||
// this CodeEmitInfo must not have the xhandlers because here the
|
||||
// object is already locked (xhandlers expect object to be unlocked)
|
||||
CodeEmitInfo* info = state_for(x, x->state(), true);
|
||||
LIR_Opr tmp = LockingMode == LM_LIGHTWEIGHT ? new_register(T_ADDRESS) : LIR_OprFact::illegalOpr;
|
||||
LIR_Opr tmp = new_register(T_ADDRESS);
|
||||
monitor_enter(obj.result(), lock, syncTempOpr(), tmp,
|
||||
x->monitor_no(), info_for_exception, info);
|
||||
}
|
||||
|
@ -720,8 +720,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
|
|||
if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||
|
||||
x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos ||
|
||||
x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan ||
|
||||
x->id() == vmIntrinsics::_dlog10 || x->id() == vmIntrinsics::_dtanh ||
|
||||
x->id() == vmIntrinsics::_dcbrt
|
||||
x->id() == vmIntrinsics::_dlog10 || x->id() == vmIntrinsics::_dsinh ||
|
||||
x->id() == vmIntrinsics::_dtanh || x->id() == vmIntrinsics::_dcbrt
|
||||
) {
|
||||
do_LibmIntrinsic(x);
|
||||
return;
|
||||
|
@ -835,6 +835,12 @@ void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {
|
|||
__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args());
|
||||
}
|
||||
break;
|
||||
case vmIntrinsics::_dsinh:
|
||||
assert(StubRoutines::dsinh() != nullptr, "sinh intrinsic not found");
|
||||
if (StubRoutines::dsinh() != nullptr) {
|
||||
__ call_runtime_leaf(StubRoutines::dsinh(), getThreadTemp(), result_reg, cc->args());
|
||||
}
|
||||
break;
|
||||
case vmIntrinsics::_dtanh:
|
||||
assert(StubRoutines::dtanh() != nullptr, "tanh intrinsic not found");
|
||||
if (StubRoutines::dtanh() != nullptr) {
|
||||
|
@ -955,7 +961,7 @@ void LIRGenerator::do_update_CRC32(Intrinsic* x) {
|
|||
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
|
||||
const LIR_Opr result_reg = result_register_for(x->type());
|
||||
|
||||
LIR_Opr addr = new_pointer_register();
|
||||
LIR_Opr addr = new_register(T_ADDRESS);
|
||||
__ leal(LIR_OprFact::address(a), addr);
|
||||
|
||||
crc.load_item_force(cc->at(0));
|
||||
|
@ -1094,10 +1100,10 @@ void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
|
|||
CallingConvention* cc = frame_map()->c_calling_convention(&signature);
|
||||
const LIR_Opr result_reg = result_register_for(x->type());
|
||||
|
||||
LIR_Opr ptr_addr_a = new_pointer_register();
|
||||
LIR_Opr ptr_addr_a = new_register(T_ADDRESS);
|
||||
__ leal(LIR_OprFact::address(addr_a), ptr_addr_a);
|
||||
|
||||
LIR_Opr ptr_addr_b = new_pointer_register();
|
||||
LIR_Opr ptr_addr_b = new_register(T_ADDRESS);
|
||||
__ leal(LIR_OprFact::address(addr_b), ptr_addr_b);
|
||||
|
||||
__ move(ptr_addr_a, cc->at(0));
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register tmp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord -1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
|
||||
assert_different_registers(hdr, obj, disp_hdr, tmp);
|
||||
int null_check_offset = -1;
|
||||
|
@ -55,93 +53,20 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
|||
|
||||
null_check_offset = offset();
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(disp_hdr, obj, hdr, tmp, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
Label done;
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(hdr, obj, rscratch1);
|
||||
testb(Address(hdr, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class);
|
||||
jcc(Assembler::notZero, slow_case);
|
||||
}
|
||||
|
||||
// Load object header
|
||||
movptr(hdr, Address(obj, hdr_offset));
|
||||
// and mark it as unlocked
|
||||
orptr(hdr, markWord::unlocked_value);
|
||||
// save unlocked object header into the displaced header location on the stack
|
||||
movptr(Address(disp_hdr, 0), hdr);
|
||||
// test if object header is still the same (i.e. unlocked), and if so, store the
|
||||
// displaced header address in the object header - if it is not the same, get the
|
||||
// object header instead
|
||||
MacroAssembler::lock(); // must be immediately before cmpxchg!
|
||||
cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
|
||||
// if the object header was the same, we're done
|
||||
jcc(Assembler::equal, done);
|
||||
// if the object header was not the same, it is now in the hdr register
|
||||
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
|
||||
//
|
||||
// 1) (hdr & aligned_mask) == 0
|
||||
// 2) rsp <= hdr
|
||||
// 3) hdr <= rsp + page_size
|
||||
//
|
||||
// these 3 tests can be done by evaluating the following expression:
|
||||
//
|
||||
// (hdr - rsp) & (aligned_mask - page_size)
|
||||
//
|
||||
// assuming both the stack pointer and page_size have their least
|
||||
// significant 2 bits cleared and page_size is a power of 2
|
||||
subptr(hdr, rsp);
|
||||
andptr(hdr, aligned_mask - (int)os::vm_page_size());
|
||||
// for recursive locking, the result is zero => save it in the displaced header
|
||||
// location (null in the displaced hdr location indicates recursive locking)
|
||||
movptr(Address(disp_hdr, 0), hdr);
|
||||
// otherwise we don't care about the result and handle locking via runtime call
|
||||
jcc(Assembler::notZero, slow_case);
|
||||
// done
|
||||
bind(done);
|
||||
inc_held_monitor_count();
|
||||
}
|
||||
lightweight_lock(disp_hdr, obj, hdr, tmp, slow_case);
|
||||
|
||||
return null_check_offset;
|
||||
}
|
||||
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord -1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction");
|
||||
assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
|
||||
Label done;
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// load displaced header
|
||||
movptr(hdr, Address(disp_hdr, 0));
|
||||
// if the loaded hdr is null we had recursive locking
|
||||
testptr(hdr, hdr);
|
||||
// if we had recursive locking, we are done
|
||||
jcc(Assembler::zero, done);
|
||||
}
|
||||
|
||||
// load object
|
||||
movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
verify_oop(obj);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_unlock(obj, disp_hdr, hdr, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// test if object header is pointing to the displaced header, and if so, restore
|
||||
// the displaced header in the object - if the object header is not pointing to
|
||||
// the displaced header, get the object header instead
|
||||
MacroAssembler::lock(); // must be immediately before cmpxchg!
|
||||
cmpxchgptr(hdr, Address(obj, hdr_offset));
|
||||
// if the object header was not pointing to the displaced header,
|
||||
// we do unlocking via runtime call
|
||||
jcc(Assembler::notEqual, slow_case);
|
||||
// done
|
||||
bind(done);
|
||||
dec_held_monitor_count();
|
||||
}
|
||||
lightweight_unlock(obj, disp_hdr, hdr, slow_case);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -219,244 +219,11 @@ inline Assembler::AvxVectorLen C2_MacroAssembler::vector_length_encoding(int vle
|
|||
|
||||
|
||||
// obj: object to lock
|
||||
// box: on-stack box address (displaced header location) - KILLED
|
||||
// rax,: tmp -- KILLED
|
||||
// scr: tmp -- KILLED
|
||||
void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmpReg,
|
||||
Register scrReg, Register cx1Reg, Register cx2Reg, Register thread,
|
||||
Metadata* method_data) {
|
||||
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
|
||||
// Ensure the register assignments are disjoint
|
||||
assert(tmpReg == rax, "");
|
||||
assert(cx1Reg == noreg, "");
|
||||
assert(cx2Reg == noreg, "");
|
||||
assert_different_registers(objReg, boxReg, tmpReg, scrReg);
|
||||
|
||||
// Possible cases that we'll encounter in fast_lock
|
||||
// ------------------------------------------------
|
||||
// * Inflated
|
||||
// -- unlocked
|
||||
// -- Locked
|
||||
// = by self
|
||||
// = by other
|
||||
// * neutral
|
||||
// * stack-locked
|
||||
// -- by self
|
||||
// = sp-proximity test hits
|
||||
// = sp-proximity test generates false-negative
|
||||
// -- by other
|
||||
//
|
||||
|
||||
Label IsInflated, DONE_LABEL, NO_COUNT, COUNT;
|
||||
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmpReg, objReg, scrReg);
|
||||
testb(Address(tmpReg, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class);
|
||||
jcc(Assembler::notZero, DONE_LABEL);
|
||||
}
|
||||
|
||||
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // [FETCH]
|
||||
testptr(tmpReg, markWord::monitor_value); // inflated vs stack-locked|neutral
|
||||
jcc(Assembler::notZero, IsInflated);
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
// Clear ZF so that we take the slow path at the DONE label. objReg is known to be not 0.
|
||||
testptr(objReg, objReg);
|
||||
} else {
|
||||
assert(LockingMode == LM_LEGACY, "must be");
|
||||
// Attempt stack-locking ...
|
||||
orptr (tmpReg, markWord::unlocked_value);
|
||||
movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS
|
||||
lock();
|
||||
cmpxchgptr(boxReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Updates tmpReg
|
||||
jcc(Assembler::equal, COUNT); // Success
|
||||
|
||||
// Recursive locking.
|
||||
// The object is stack-locked: markword contains stack pointer to BasicLock.
|
||||
// Locked by current thread if difference with current SP is less than one page.
|
||||
subptr(tmpReg, rsp);
|
||||
// Next instruction set ZFlag == 1 (Success) if difference is less then one page.
|
||||
andptr(tmpReg, (int32_t) (7 - (int)os::vm_page_size()) );
|
||||
movptr(Address(boxReg, 0), tmpReg);
|
||||
}
|
||||
jmp(DONE_LABEL);
|
||||
|
||||
bind(IsInflated);
|
||||
// The object is inflated. tmpReg contains pointer to ObjectMonitor* + markWord::monitor_value
|
||||
|
||||
// Unconditionally set box->_displaced_header = markWord::unused_mark().
|
||||
// Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
|
||||
movptr(Address(boxReg, 0), checked_cast<int32_t>(markWord::unused_mark().value()));
|
||||
|
||||
// It's inflated and we use scrReg for ObjectMonitor* in this section.
|
||||
movptr(boxReg, Address(r15_thread, JavaThread::monitor_owner_id_offset()));
|
||||
movq(scrReg, tmpReg);
|
||||
xorq(tmpReg, tmpReg);
|
||||
lock();
|
||||
cmpxchgptr(boxReg, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
|
||||
|
||||
// Propagate ICC.ZF from CAS above into DONE_LABEL.
|
||||
jccb(Assembler::equal, COUNT); // CAS above succeeded; propagate ZF = 1 (success)
|
||||
|
||||
cmpptr(boxReg, rax); // Check if we are already the owner (recursive lock)
|
||||
jccb(Assembler::notEqual, NO_COUNT); // If not recursive, ZF = 0 at this point (fail)
|
||||
incq(Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
|
||||
xorq(rax, rax); // Set ZF = 1 (success) for recursive lock, denoting locking success
|
||||
bind(DONE_LABEL);
|
||||
|
||||
// ZFlag == 1 count in fast path
|
||||
// ZFlag == 0 count in slow path
|
||||
jccb(Assembler::notZero, NO_COUNT); // jump if ZFlag == 0
|
||||
|
||||
bind(COUNT);
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
// Count monitors in fast path
|
||||
increment(Address(thread, JavaThread::held_monitor_count_offset()));
|
||||
}
|
||||
xorl(tmpReg, tmpReg); // Set ZF == 1
|
||||
|
||||
bind(NO_COUNT);
|
||||
|
||||
// At NO_COUNT the icc ZFlag is set as follows ...
|
||||
// fast_unlock uses the same protocol.
|
||||
// ZFlag == 1 -> Success
|
||||
// ZFlag == 0 -> Failure - force control through the slow path
|
||||
}
|
||||
|
||||
// obj: object to unlock
|
||||
// box: box address (displaced header location), killed. Must be EAX.
|
||||
// tmp: killed, cannot be obj nor box.
|
||||
//
|
||||
// Some commentary on balanced locking:
|
||||
//
|
||||
// fast_lock and fast_unlock are emitted only for provably balanced lock sites.
|
||||
// Methods that don't have provably balanced locking are forced to run in the
|
||||
// interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
|
||||
// The interpreter provides two properties:
|
||||
// I1: At return-time the interpreter automatically and quietly unlocks any
|
||||
// objects acquired the current activation (frame). Recall that the
|
||||
// interpreter maintains an on-stack list of locks currently held by
|
||||
// a frame.
|
||||
// I2: If a method attempts to unlock an object that is not held by the
|
||||
// the frame the interpreter throws IMSX.
|
||||
//
|
||||
// Lets say A(), which has provably balanced locking, acquires O and then calls B().
|
||||
// B() doesn't have provably balanced locking so it runs in the interpreter.
|
||||
// Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O
|
||||
// is still locked by A().
|
||||
//
|
||||
// The only other source of unbalanced locking would be JNI. The "Java Native Interface:
|
||||
// Programmer's Guide and Specification" claims that an object locked by jni_monitorenter
|
||||
// should not be unlocked by "normal" java-level locking and vice-versa. The specification
|
||||
// doesn't specify what will occur if a program engages in such mixed-mode locking, however.
|
||||
// Arguably given that the spec legislates the JNI case as undefined our implementation
|
||||
// could reasonably *avoid* checking owner in fast_unlock().
|
||||
// In the interest of performance we elide m->Owner==Self check in unlock.
|
||||
// A perfectly viable alternative is to elide the owner check except when
|
||||
// Xcheck:jni is enabled.
|
||||
|
||||
void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register tmpReg) {
|
||||
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_unlock_lightweight");
|
||||
assert(boxReg == rax, "");
|
||||
assert_different_registers(objReg, boxReg, tmpReg);
|
||||
|
||||
Label DONE_LABEL, Stacked, COUNT, NO_COUNT;
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
cmpptr(Address(boxReg, 0), NULL_WORD); // Examine the displaced header
|
||||
jcc (Assembler::zero, COUNT); // 0 indicates recursive stack-lock
|
||||
}
|
||||
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Examine the object's markword
|
||||
if (LockingMode != LM_MONITOR) {
|
||||
testptr(tmpReg, markWord::monitor_value); // Inflated?
|
||||
jcc(Assembler::zero, Stacked);
|
||||
}
|
||||
|
||||
// It's inflated.
|
||||
|
||||
// Despite our balanced locking property we still check that m->_owner == Self
|
||||
// as java routines or native JNI code called by this thread might
|
||||
// have released the lock.
|
||||
//
|
||||
// If there's no contention try a 1-0 exit. That is, exit without
|
||||
// a costly MEMBAR or CAS. See synchronizer.cpp for details on how
|
||||
// we detect and recover from the race that the 1-0 exit admits.
|
||||
//
|
||||
// Conceptually fast_unlock() must execute a STST|LDST "release" barrier
|
||||
// before it STs null into _owner, releasing the lock. Updates
|
||||
// to data protected by the critical section must be visible before
|
||||
// we drop the lock (and thus before any other thread could acquire
|
||||
// the lock and observe the fields protected by the lock).
|
||||
// IA32's memory-model is SPO, so STs are ordered with respect to
|
||||
// each other and there's no need for an explicit barrier (fence).
|
||||
// See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
|
||||
Label LSuccess, LNotRecursive;
|
||||
|
||||
cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), 0);
|
||||
jccb(Assembler::equal, LNotRecursive);
|
||||
|
||||
// Recursive inflated unlock
|
||||
decrement(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
|
||||
jmpb(LSuccess);
|
||||
|
||||
bind(LNotRecursive);
|
||||
|
||||
// Set owner to null.
|
||||
// Release to satisfy the JMM
|
||||
movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), NULL_WORD);
|
||||
// We need a full fence after clearing owner to avoid stranding.
|
||||
// StoreLoad achieves this.
|
||||
membar(StoreLoad);
|
||||
|
||||
// Check if the entry_list is empty.
|
||||
cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(entry_list)), NULL_WORD);
|
||||
jccb(Assembler::zero, LSuccess); // If so we are done.
|
||||
|
||||
// Check if there is a successor.
|
||||
cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), NULL_WORD);
|
||||
jccb(Assembler::notZero, LSuccess); // If so we are done.
|
||||
|
||||
// Save the monitor pointer in the current thread, so we can try to
|
||||
// reacquire the lock in SharedRuntime::monitor_exit_helper().
|
||||
andptr(tmpReg, ~(int32_t)markWord::monitor_value);
|
||||
movptr(Address(r15_thread, JavaThread::unlocked_inflated_monitor_offset()), tmpReg);
|
||||
|
||||
orl (boxReg, 1); // set ICC.ZF=0 to indicate failure
|
||||
jmpb (DONE_LABEL);
|
||||
|
||||
bind (LSuccess);
|
||||
testl (boxReg, 0); // set ICC.ZF=1 to indicate success
|
||||
jmpb (DONE_LABEL);
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
bind (Stacked);
|
||||
movptr(tmpReg, Address (boxReg, 0)); // re-fetch
|
||||
lock();
|
||||
cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box
|
||||
// Intentional fall-thru into DONE_LABEL
|
||||
}
|
||||
|
||||
bind(DONE_LABEL);
|
||||
|
||||
// ZFlag == 1 count in fast path
|
||||
// ZFlag == 0 count in slow path
|
||||
jccb(Assembler::notZero, NO_COUNT);
|
||||
|
||||
bind(COUNT);
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
// Count monitors in fast path
|
||||
decrementq(Address(r15_thread, JavaThread::held_monitor_count_offset()));
|
||||
}
|
||||
|
||||
xorl(tmpReg, tmpReg); // Set ZF == 1
|
||||
|
||||
bind(NO_COUNT);
|
||||
}
|
||||
|
||||
// box: on-stack box address -- KILLED
|
||||
// rax: tmp -- KILLED
|
||||
// t : tmp -- KILLED
|
||||
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Register rax_reg,
|
||||
Register t, Register thread) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
assert(rax_reg == rax, "Used for CAS");
|
||||
assert_different_registers(obj, box, rax_reg, t, thread);
|
||||
|
||||
|
@ -616,8 +383,39 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist
|
|||
// C2 uses the value of ZF to determine the continuation.
|
||||
}
|
||||
|
||||
// obj: object to lock
|
||||
// rax: tmp -- KILLED
|
||||
// t : tmp - cannot be obj nor rax -- KILLED
|
||||
//
|
||||
// Some commentary on balanced locking:
|
||||
//
|
||||
// fast_lock and fast_unlock are emitted only for provably balanced lock sites.
|
||||
// Methods that don't have provably balanced locking are forced to run in the
|
||||
// interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
|
||||
// The interpreter provides two properties:
|
||||
// I1: At return-time the interpreter automatically and quietly unlocks any
|
||||
// objects acquired in the current activation (frame). Recall that the
|
||||
// interpreter maintains an on-stack list of locks currently held by
|
||||
// a frame.
|
||||
// I2: If a method attempts to unlock an object that is not held by the
|
||||
// frame the interpreter throws IMSX.
|
||||
//
|
||||
// Lets say A(), which has provably balanced locking, acquires O and then calls B().
|
||||
// B() doesn't have provably balanced locking so it runs in the interpreter.
|
||||
// Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O
|
||||
// is still locked by A().
|
||||
//
|
||||
// The only other source of unbalanced locking would be JNI. The "Java Native Interface
|
||||
// Specification" states that an object locked by JNI's MonitorEnter should not be
|
||||
// unlocked by "normal" java-level locking and vice-versa. The specification doesn't
|
||||
// specify what will occur if a program engages in such mixed-mode locking, however.
|
||||
// Arguably given that the spec legislates the JNI case as undefined our implementation
|
||||
// could reasonably *avoid* checking owner in fast_unlock().
|
||||
// In the interest of performance we elide m->Owner==Self check in unlock.
|
||||
// A perfectly viable alternative is to elide the owner check except when
|
||||
// Xcheck:jni is enabled.
|
||||
|
||||
void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register reg_rax, Register t, Register thread) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
assert(reg_rax == rax, "Used for CAS");
|
||||
assert_different_registers(obj, reg_rax, t);
|
||||
|
||||
|
|
|
@ -34,12 +34,7 @@ public:
|
|||
Assembler::AvxVectorLen vector_length_encoding(int vlen_in_bytes);
|
||||
|
||||
// Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
|
||||
// See full description in macroAssembler_x86.cpp.
|
||||
void fast_lock(Register obj, Register box, Register tmp,
|
||||
Register scr, Register cx1, Register cx2, Register thread,
|
||||
Metadata* method_data);
|
||||
void fast_unlock(Register obj, Register box, Register tmp);
|
||||
|
||||
// See full description in c2_MacroAssembler_x86.cpp.
|
||||
void fast_lock_lightweight(Register obj, Register box, Register rax_reg,
|
||||
Register t, Register thread);
|
||||
void fast_unlock_lightweight(Register obj, Register reg_rax, Register t, Register thread);
|
||||
|
|
|
@ -1024,100 +1024,25 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
|
|||
void InterpreterMacroAssembler::lock_object(Register lock_reg) {
|
||||
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
} else {
|
||||
Label count_locking, done, slow_case;
|
||||
Label done, slow_case;
|
||||
|
||||
const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|
||||
const Register tmp_reg = rbx;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register rklass_decode_tmp = rscratch1;
|
||||
const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|
||||
const Register tmp_reg = rbx;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
|
||||
const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
|
||||
const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
|
||||
const int mark_offset = lock_offset +
|
||||
BasicLock::displaced_header_offset_in_bytes();
|
||||
// Load object pointer into obj_reg
|
||||
movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
// Load object pointer into obj_reg
|
||||
movptr(obj_reg, Address(lock_reg, obj_offset));
|
||||
lightweight_lock(lock_reg, obj_reg, swap_reg, tmp_reg, slow_case);
|
||||
jmp(done);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(lock_reg, obj_reg, swap_reg, tmp_reg, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp_reg, obj_reg, rklass_decode_tmp);
|
||||
testb(Address(tmp_reg, Klass::misc_flags_offset()), KlassFlags::_misc_is_value_based_class);
|
||||
jcc(Assembler::notZero, slow_case);
|
||||
}
|
||||
bind(slow_case);
|
||||
|
||||
// Load immediate 1 into swap_reg %rax
|
||||
movl(swap_reg, 1);
|
||||
|
||||
// Load (object->mark() | 1) into swap_reg %rax
|
||||
orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
// Save (object->mark() | 1) into BasicLock's displaced header
|
||||
movptr(Address(lock_reg, mark_offset), swap_reg);
|
||||
|
||||
assert(lock_offset == 0,
|
||||
"displaced header must be first word in BasicObjectLock");
|
||||
|
||||
lock();
|
||||
cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
jcc(Assembler::zero, count_locking);
|
||||
|
||||
const int zero_bits = 7;
|
||||
|
||||
// Fast check for recursive lock.
|
||||
//
|
||||
// Can apply the optimization only if this is a stack lock
|
||||
// allocated in this thread. For efficiency, we can focus on
|
||||
// recently allocated stack locks (instead of reading the stack
|
||||
// base and checking whether 'mark' points inside the current
|
||||
// thread stack):
|
||||
// 1) (mark & zero_bits) == 0, and
|
||||
// 2) rsp <= mark < mark + os::pagesize()
|
||||
//
|
||||
// Warning: rsp + os::pagesize can overflow the stack base. We must
|
||||
// neither apply the optimization for an inflated lock allocated
|
||||
// just above the thread stack (this is why condition 1 matters)
|
||||
// nor apply the optimization if the stack lock is inside the stack
|
||||
// of another thread. The latter is avoided even in case of overflow
|
||||
// because we have guard pages at the end of all stacks. Hence, if
|
||||
// we go over the stack base and hit the stack of another thread,
|
||||
// this should not be in a writeable area that could contain a
|
||||
// stack lock allocated by that thread. As a consequence, a stack
|
||||
// lock less than page size away from rsp is guaranteed to be
|
||||
// owned by the current thread.
|
||||
//
|
||||
// These 3 tests can be done by evaluating the following
|
||||
// expression: ((mark - rsp) & (zero_bits - os::vm_page_size())),
|
||||
// assuming both stack pointer and pagesize have their
|
||||
// least significant bits clear.
|
||||
// NOTE: the mark is in swap_reg %rax as the result of cmpxchg
|
||||
subptr(swap_reg, rsp);
|
||||
andptr(swap_reg, zero_bits - (int)os::vm_page_size());
|
||||
|
||||
// Save the test result, for recursive case, the result is zero
|
||||
movptr(Address(lock_reg, mark_offset), swap_reg);
|
||||
jcc(Assembler::notZero, slow_case);
|
||||
|
||||
bind(count_locking);
|
||||
inc_held_monitor_count();
|
||||
}
|
||||
jmp(done);
|
||||
|
||||
bind(slow_case);
|
||||
|
||||
// Call the runtime routine for slow case
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
bind(done);
|
||||
}
|
||||
// Call the runtime routine for slow case
|
||||
call_VM_preemptable(noreg,
|
||||
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
|
||||
lock_reg);
|
||||
bind(done);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1136,63 +1061,31 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) {
|
|||
void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
|
||||
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
} else {
|
||||
Label count_locking, done, slow_case;
|
||||
Label done, slow_case;
|
||||
|
||||
const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
|
||||
save_bcp(); // Save in case of exception
|
||||
save_bcp(); // Save in case of exception
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// Convert from BasicObjectLock structure to object and BasicLock
|
||||
// structure Store the BasicLock address into %rax
|
||||
lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
|
||||
}
|
||||
// Load oop into obj_reg(%c_rarg3)
|
||||
movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
|
||||
// Load oop into obj_reg(%c_rarg3)
|
||||
movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
|
||||
// Free entry
|
||||
movptr(Address(lock_reg, BasicObjectLock::obj_offset()), NULL_WORD);
|
||||
|
||||
// Free entry
|
||||
movptr(Address(lock_reg, BasicObjectLock::obj_offset()), NULL_WORD);
|
||||
lightweight_unlock(obj_reg, swap_reg, header_reg, slow_case);
|
||||
jmp(done);
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_unlock(obj_reg, swap_reg, header_reg, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load the old header from BasicLock structure
|
||||
movptr(header_reg, Address(swap_reg,
|
||||
BasicLock::displaced_header_offset_in_bytes()));
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case.
|
||||
movptr(Address(lock_reg, BasicObjectLock::obj_offset()), obj_reg); // restore obj
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
|
||||
// Test for recursion
|
||||
testptr(header_reg, header_reg);
|
||||
bind(done);
|
||||
|
||||
// zero for recursive case
|
||||
jcc(Assembler::zero, count_locking);
|
||||
|
||||
// Atomic swap back the old header
|
||||
lock();
|
||||
cmpxchgptr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
// zero for simple unlock of a stack-lock case
|
||||
jcc(Assembler::notZero, slow_case);
|
||||
|
||||
bind(count_locking);
|
||||
dec_held_monitor_count();
|
||||
}
|
||||
jmp(done);
|
||||
|
||||
bind(slow_case);
|
||||
// Call the runtime routine for slow case.
|
||||
movptr(Address(lock_reg, BasicObjectLock::obj_offset()), obj_reg); // restore obj
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
|
||||
|
||||
bind(done);
|
||||
|
||||
restore_bcp();
|
||||
}
|
||||
restore_bcp();
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
|
||||
|
|
|
@ -137,7 +137,7 @@ void MethodHandles::verify_method(MacroAssembler* _masm, Register method, Regist
|
|||
case vmIntrinsicID::_invokeBasic:
|
||||
// Require compiled LambdaForm class to be fully initialized.
|
||||
__ cmpb(Address(method_holder, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
|
||||
__ jccb(Assembler::equal, L_ok);
|
||||
__ jcc(Assembler::equal, L_ok);
|
||||
break;
|
||||
|
||||
case vmIntrinsicID::_linkToStatic:
|
||||
|
@ -154,7 +154,7 @@ void MethodHandles::verify_method(MacroAssembler* _masm, Register method, Regist
|
|||
// init_state check failed, but it may be an abstract interface method
|
||||
__ load_unsigned_short(temp, Address(method, Method::access_flags_offset()));
|
||||
__ testl(temp, JVM_ACC_ABSTRACT);
|
||||
__ jccb(Assembler::notZero, L_ok);
|
||||
__ jcc(Assembler::notZero, L_ok);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -59,17 +59,10 @@ void SharedRuntime::inline_check_hashcode_from_object_header(MacroAssembler* mas
|
|||
|
||||
__ movptr(result, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
if (!UseObjectMonitorTable) {
|
||||
// check if monitor
|
||||
__ testptr(result, markWord::monitor_value);
|
||||
__ jcc(Assembler::notZero, slowCase);
|
||||
}
|
||||
} else {
|
||||
// check if locked
|
||||
__ testptr(result, markWord::unlocked_value);
|
||||
__ jcc(Assembler::zero, slowCase);
|
||||
if (!UseObjectMonitorTable) {
|
||||
// check if monitor
|
||||
__ testptr(result, markWord::monitor_value);
|
||||
__ jcc(Assembler::notZero, slowCase);
|
||||
}
|
||||
|
||||
// get hash
|
||||
|
|
|
@ -2133,7 +2133,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// We use the same pc/oopMap repeatedly when we call out
|
||||
|
||||
Label native_return;
|
||||
if (LockingMode != LM_LEGACY && method->is_object_wait0()) {
|
||||
if (method->is_object_wait0()) {
|
||||
// For convenience we use the pc we want to resume to in case of preemption on Object.wait.
|
||||
__ set_last_Java_frame(rsp, noreg, native_return, rscratch1);
|
||||
} else {
|
||||
|
@ -2174,16 +2174,11 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|
||||
const Register obj_reg = rbx; // Will contain the oop
|
||||
const Register lock_reg = r13; // Address of compiler lock object (BasicLock)
|
||||
const Register old_hdr = r13; // value of old header at unlock time
|
||||
|
||||
Label slow_path_lock;
|
||||
Label lock_done;
|
||||
|
||||
if (method->is_synchronized()) {
|
||||
Label count_mon;
|
||||
|
||||
const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes();
|
||||
|
||||
// Get the handle (the 2nd argument)
|
||||
__ mov(oop_handle_reg, c_rarg1);
|
||||
|
||||
|
@ -2194,47 +2189,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// Load the oop from the handle
|
||||
__ movptr(obj_reg, Address(oop_handle_reg, 0));
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ jmp(slow_path_lock);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load immediate 1 into swap_reg %rax
|
||||
__ movl(swap_reg, 1);
|
||||
|
||||
// Load (object->mark() | 1) into swap_reg %rax
|
||||
__ orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
// Save (object->mark() | 1) into BasicLock's displaced header
|
||||
__ movptr(Address(lock_reg, mark_word_offset), swap_reg);
|
||||
|
||||
// src -> dest iff dest == rax else rax <- dest
|
||||
__ lock();
|
||||
__ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
__ jcc(Assembler::equal, count_mon);
|
||||
|
||||
// Hmm should this move to the slow path code area???
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 3) == 0, and
|
||||
// 2) rsp <= mark < mark + os::pagesize()
|
||||
// These 3 tests can be done by evaluating the following
|
||||
// expression: ((mark - rsp) & (3 - os::vm_page_size())),
|
||||
// assuming both stack pointer and pagesize have their
|
||||
// least significant 2 bits clear.
|
||||
// NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg
|
||||
|
||||
__ subptr(swap_reg, rsp);
|
||||
__ andptr(swap_reg, 3 - (int)os::vm_page_size());
|
||||
|
||||
// Save the test result, for recursive case, the result is zero
|
||||
__ movptr(Address(lock_reg, mark_word_offset), swap_reg);
|
||||
__ jcc(Assembler::notEqual, slow_path_lock);
|
||||
|
||||
__ bind(count_mon);
|
||||
__ inc_held_monitor_count();
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
__ lightweight_lock(lock_reg, obj_reg, swap_reg, rscratch1, slow_path_lock);
|
||||
}
|
||||
__ lightweight_lock(lock_reg, obj_reg, swap_reg, rscratch1, slow_path_lock);
|
||||
|
||||
// Slow path will re-enter here
|
||||
__ bind(lock_done);
|
||||
|
@ -2322,7 +2277,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// change thread state
|
||||
__ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java);
|
||||
|
||||
if (LockingMode != LM_LEGACY && method->is_object_wait0()) {
|
||||
if (method->is_object_wait0()) {
|
||||
// Check preemption for Object.wait()
|
||||
__ movptr(rscratch1, Address(r15_thread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ cmpptr(rscratch1, NULL_WORD);
|
||||
|
@ -2354,38 +2309,12 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||
// Get locked oop from the handle we passed to jni
|
||||
__ movptr(obj_reg, Address(oop_handle_reg, 0));
|
||||
|
||||
if (LockingMode == LM_LEGACY) {
|
||||
Label not_recur;
|
||||
// Simple recursive lock?
|
||||
__ cmpptr(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), NULL_WORD);
|
||||
__ jcc(Assembler::notEqual, not_recur);
|
||||
__ dec_held_monitor_count();
|
||||
__ jmpb(fast_done);
|
||||
__ bind(not_recur);
|
||||
}
|
||||
|
||||
// Must save rax if it is live now because cmpxchg must use it
|
||||
if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
|
||||
save_native_result(masm, ret_type, stack_slots);
|
||||
}
|
||||
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ jmp(slow_path_unlock);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// get address of the stack lock
|
||||
__ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size));
|
||||
// get old displaced header
|
||||
__ movptr(old_hdr, Address(rax, 0));
|
||||
|
||||
// Atomic swap old header if oop still contains the stack lock
|
||||
__ lock();
|
||||
__ cmpxchgptr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
__ jcc(Assembler::notEqual, slow_path_unlock);
|
||||
__ dec_held_monitor_count();
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
__ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock);
|
||||
}
|
||||
__ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock);
|
||||
|
||||
// slow path re-enters here
|
||||
__ bind(unlock_done);
|
||||
|
|
|
@ -3689,6 +3689,9 @@ void StubGenerator::generate_libm_stubs() {
|
|||
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
|
||||
StubRoutines::_dtan = generate_libmTan(); // from stubGenerator_x86_64_tan.cpp
|
||||
}
|
||||
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsinh)) {
|
||||
StubRoutines::_dsinh = generate_libmSinh(); // from stubGenerator_x86_64_sinh.cpp
|
||||
}
|
||||
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtanh)) {
|
||||
StubRoutines::_dtanh = generate_libmTanh(); // from stubGenerator_x86_64_tanh.cpp
|
||||
}
|
||||
|
|
|
@ -555,6 +555,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||
address generate_libmSin();
|
||||
address generate_libmCos();
|
||||
address generate_libmTan();
|
||||
address generate_libmSinh();
|
||||
address generate_libmTanh();
|
||||
address generate_libmCbrt();
|
||||
address generate_libmExp();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2025, Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Copyright (C) 2021, Tencent. All rights reserved.
|
||||
* Intel Math Library (LIBM) Source Code
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2025, Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Copyright (C) 2021, Tencent. All rights reserved.
|
||||
* Intel Math Library (LIBM) Source Code
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2025, Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Copyright (C) 2021, Tencent. All rights reserved.
|
||||
* Intel Math Library (LIBM) Source Code
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
|
525
src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp
Normal file
525
src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp
Normal file
|
@ -0,0 +1,525 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Intel Corporation. All rights reserved.
|
||||
* Intel Math Library (LIBM) Source Code
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "macroAssembler_x86.hpp"
|
||||
#include "stubGenerator_x86_64.hpp"
|
||||
|
||||
/******************************************************************************/
|
||||
// ALGORITHM DESCRIPTION
|
||||
// ---------------------
|
||||
//
|
||||
// sinh(x)=(exp(x)-exp(-x))/2
|
||||
//
|
||||
// Let |x|=xH+xL (upper 26 bits, lower 27 bits)
|
||||
// log2(e) rounded to 26 bits (high part) plus a double precision low part is
|
||||
// L2EH+L2EL (upper 26, lower 53 bits)
|
||||
//
|
||||
// Let xH*L2EH=k+f+r`, where (k+f)*2^7=int(xH*L2EH*2^7),
|
||||
// f=0.b1 b2 ... b7, k integer
|
||||
// 2^f is approximated as Tp[f]+Dp[f], and 2^{-f} as Tn[f]+Dn[f]
|
||||
// Tp stores the high 53 bits, Dp stores (2^f-Tp[f]) rounded to double precision
|
||||
//
|
||||
// e^|x|=2^{k+f}*2^r, r=r`+xL*L2EH+|x|*L2EL, |r|<2^{-8}+2^{-14},
|
||||
// for |x| in [23/64,3*2^7)
|
||||
// e^{-|x|}=2^{-k-f}*2^{-r}
|
||||
//
|
||||
// e^|x| is approximated as 2^k*Tp+2^k*Tp*c1*r(1+c2*r+..+c5*r^4)+2^k*Dp=
|
||||
// =2^k*Tp+2^k*Tp*P15+2^k*Dp
|
||||
// e^{-|x|} approximated as 2^{-k}*Tn-2^{-k}*Tn*c1*r(1-c2*r+..+c5*r^4)+2^{-k}*Dn
|
||||
//
|
||||
// For |x| in [1/8, 3*2^7), sinh(x) is formed as
|
||||
// RN(2^k*Tp-2^{-k}*Tn)+2^k*Tp*P15-2^{-k}*Tn*P`15-2^{-k}*TnL-2^{-k}*Dn+2^k*Dp
|
||||
//
|
||||
// For x in (3*2^7, 3*2^8), sign(x)*(e^|x|)/2 is returned, and
|
||||
// the result is checked for overflow.
|
||||
//
|
||||
// For |x|<23/64, a Taylor polynomial expansion is used (degree 13)
|
||||
// To reduce rounding errors, the p3*x^3 term is computed as
|
||||
// (p3*xh^3)_high+[(p3*xl*(3*x*xh+xl^2))+(p3*xh^3)_low],
|
||||
// where x=xh+xl, (xh are the leading 17 bits of x), and
|
||||
// (p3*xh^3)_high=RN(x+p3*xh^3)-x
|
||||
//
|
||||
// Error bound:
|
||||
// 0.51 ulp
|
||||
//
|
||||
// Special cases:
|
||||
// sinh(NaN) = quiet NaN, and raise invalid exception
|
||||
// sinh(+/-INF) = +/-INF
|
||||
// sinh(+/-0) = +/-0
|
||||
/******************************************************************************/
|
||||
|
||||
ATTRIBUTE_ALIGNED(8) static const juint _HALFMASK[] =
|
||||
{
|
||||
0xF8000000UL, 0x7FFFFFFFUL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _MASK3[] =
|
||||
{
|
||||
0x00000000UL, 0xFFFFFFF0UL, 0x00000000UL, 0xFFFFFFF0UL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _L2E[] =
|
||||
{
|
||||
0x60000000UL, 0x40671547UL, 0xF85DDF44UL, 0x3EC4AE0BUL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _Shifter[] =
|
||||
{
|
||||
0x00000000UL, 0x43380000UL, 0x00000000UL, 0xC3380000UL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _cv[] =
|
||||
{
|
||||
0xD704A0C0UL, 0x3E3C6B08UL, 0xD704A0C0UL, 0xBE3C6B08UL, 0xFEFA39EFUL,
|
||||
0x3F662E42UL, 0xFEFA39EFUL, 0xBF662E42UL, 0x7F907D8BUL, 0x3D9F8445UL,
|
||||
0x7F907D8BUL, 0x3D9F8445UL, 0xFFAC83B4UL, 0x3ED47FD3UL, 0xFFAC83B4UL,
|
||||
0x3ED47FD3UL, 0xFEFA39EFUL, 0x3F762E42UL, 0xFEFA39EFUL, 0x3F762E42UL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _pv[] =
|
||||
{
|
||||
0x13A86D08UL, 0x3DE61246UL, 0xA556C732UL, 0x3EC71DE3UL, 0x11111111UL,
|
||||
0x3F811111UL, 0x55555555UL, 0x3FC55555UL, 0x67F544E1UL, 0x3E5AE645UL,
|
||||
0x1A01A019UL, 0x3F2A01A0UL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _T2f[] =
|
||||
{
|
||||
0x00000000UL, 0x3FF00000UL, 0x00000000UL, 0x00000000UL, 0xA9FB3335UL, 0x3FF0163DUL,
|
||||
0x9AB8CDB7UL, 0x3C9B6129UL, 0x3E778061UL, 0x3FF02C9AUL, 0x535B085DUL, 0xBC719083UL,
|
||||
0xE86E7F85UL, 0x3FF04315UL, 0x1977C96EUL, 0xBC90A31CUL, 0xD3158574UL, 0x3FF059B0UL,
|
||||
0xA475B465UL, 0x3C8D73E2UL, 0x29DDF6DEUL, 0x3FF0706BUL, 0xE2B13C27UL, 0xBC8C91DFUL,
|
||||
0x18759BC8UL, 0x3FF08745UL, 0x4BB284FFUL, 0x3C6186BEUL, 0xCAC6F383UL, 0x3FF09E3EUL,
|
||||
0x18316136UL, 0x3C914878UL, 0x6CF9890FUL, 0x3FF0B558UL, 0x4ADC610BUL, 0x3C98A62EUL,
|
||||
0x2B7247F7UL, 0x3FF0CC92UL, 0x16E24F71UL, 0x3C901EDCUL, 0x32D3D1A2UL, 0x3FF0E3ECUL,
|
||||
0x27C57B52UL, 0x3C403A17UL, 0xAFFED31BUL, 0x3FF0FB66UL, 0xC44EBD7BUL, 0xBC6B9BEDUL,
|
||||
0xD0125B51UL, 0x3FF11301UL, 0x39449B3AUL, 0xBC96C510UL, 0xC06C31CCUL, 0x3FF12ABDUL,
|
||||
0xB36CA5C7UL, 0xBC51B514UL, 0xAEA92DE0UL, 0x3FF1429AUL, 0x9AF1369EUL, 0xBC932FBFUL,
|
||||
0xC8A58E51UL, 0x3FF15A98UL, 0xB9EEAB0AUL, 0x3C82406AUL, 0x3C7D517BUL, 0x3FF172B8UL,
|
||||
0xB9D78A76UL, 0xBC819041UL, 0x388C8DEAUL, 0x3FF18AF9UL, 0xD1970F6CUL, 0xBC911023UL,
|
||||
0xEB6FCB75UL, 0x3FF1A35BUL, 0x7B4968E4UL, 0x3C8E5B4CUL, 0x84045CD4UL, 0x3FF1BBE0UL,
|
||||
0x352EF607UL, 0xBC995386UL, 0x3168B9AAUL, 0x3FF1D487UL, 0x00A2643CUL, 0x3C9E016EUL,
|
||||
0x22FCD91DUL, 0x3FF1ED50UL, 0x027BB78CUL, 0xBC91DF98UL, 0x88628CD6UL, 0x3FF2063BUL,
|
||||
0x814A8495UL, 0x3C8DC775UL, 0x917DDC96UL, 0x3FF21F49UL, 0x9494A5EEUL, 0x3C82A97EUL,
|
||||
0x6E756238UL, 0x3FF2387AUL, 0xB6C70573UL, 0x3C99B07EUL, 0x4FB2A63FUL, 0x3FF251CEUL,
|
||||
0xBEF4F4A4UL, 0x3C8AC155UL, 0x65E27CDDUL, 0x3FF26B45UL, 0x9940E9D9UL, 0x3C82BD33UL,
|
||||
0xE1F56381UL, 0x3FF284DFUL, 0x8C3F0D7EUL, 0xBC9A4C3AUL, 0xF51FDEE1UL, 0x3FF29E9DUL,
|
||||
0xAFAD1255UL, 0x3C8612E8UL, 0xD0DAD990UL, 0x3FF2B87FUL, 0xD6381AA4UL, 0xBC410ADCUL,
|
||||
0xA6E4030BUL, 0x3FF2D285UL, 0x54DB41D5UL, 0x3C900247UL, 0xA93E2F56UL, 0x3FF2ECAFUL,
|
||||
0x45D52383UL, 0x3C71CA0FUL, 0x0A31B715UL, 0x3FF306FEUL, 0xD23182E4UL, 0x3C86F46AUL,
|
||||
0xFC4CD831UL, 0x3FF32170UL, 0x8E18047CUL, 0x3C8A9CE7UL, 0xB26416FFUL, 0x3FF33C08UL,
|
||||
0x843659A6UL, 0x3C932721UL, 0x5F929FF1UL, 0x3FF356C5UL, 0x5C4E4628UL, 0xBC8B5CEEUL,
|
||||
0x373AA9CBUL, 0x3FF371A7UL, 0xBF42EAE2UL, 0xBC963AEAUL, 0x6D05D866UL, 0x3FF38CAEUL,
|
||||
0x3C9904BDUL, 0xBC9E958DUL, 0x34E59FF7UL, 0x3FF3A7DBUL, 0xD661F5E3UL, 0xBC75E436UL,
|
||||
0xC313A8E5UL, 0x3FF3C32DUL, 0x375D29C3UL, 0xBC9EFFF8UL, 0x4C123422UL, 0x3FF3DEA6UL,
|
||||
0x11F09EBCUL, 0x3C8ADA09UL, 0x04AC801CUL, 0x3FF3FA45UL, 0xF956F9F3UL, 0xBC97D023UL,
|
||||
0x21F72E2AUL, 0x3FF4160AUL, 0x1C309278UL, 0xBC5EF369UL, 0xD950A897UL, 0x3FF431F5UL,
|
||||
0xE35F7999UL, 0xBC81C7DDUL, 0x6061892DUL, 0x3FF44E08UL, 0x04EF80D0UL, 0x3C489B7AUL,
|
||||
0xED1D0057UL, 0x3FF46A41UL, 0xD1648A76UL, 0x3C9C944BUL, 0xB5C13CD0UL, 0x3FF486A2UL,
|
||||
0xB69062F0UL, 0x3C73C1A3UL, 0xF0D7D3DEUL, 0x3FF4A32AUL, 0xF3D1BE56UL, 0x3C99CB62UL,
|
||||
0xD5362A27UL, 0x3FF4BFDAUL, 0xAFEC42E2UL, 0x3C7D4397UL, 0x99FDDD0DUL, 0x3FF4DCB2UL,
|
||||
0xBC6A7833UL, 0x3C98ECDBUL, 0x769D2CA7UL, 0x3FF4F9B2UL, 0xD25957E3UL, 0xBC94B309UL,
|
||||
0xA2CF6642UL, 0x3FF516DAUL, 0x69BD93EFUL, 0xBC8F7685UL, 0x569D4F82UL, 0x3FF5342BUL,
|
||||
0x1DB13CADUL, 0xBC807ABEUL, 0xCA5D920FUL, 0x3FF551A4UL, 0xEFEDE59BUL, 0xBC8D689CUL,
|
||||
0x36B527DAUL, 0x3FF56F47UL, 0x011D93ADUL, 0x3C99BB2CUL, 0xD497C7FDUL, 0x3FF58D12UL,
|
||||
0x5B9A1DE8UL, 0x3C8295E1UL, 0xDD485429UL, 0x3FF5AB07UL, 0x054647ADUL, 0x3C96324CUL,
|
||||
0x8A5946B7UL, 0x3FF5C926UL, 0x816986A2UL, 0x3C3C4B1BUL, 0x15AD2148UL, 0x3FF5E76FUL,
|
||||
0x3080E65EUL, 0x3C9BA6F9UL, 0xB976DC09UL, 0x3FF605E1UL, 0x9B56DE47UL, 0xBC93E242UL,
|
||||
0xB03A5585UL, 0x3FF6247EUL, 0x7E40B497UL, 0xBC9383C1UL, 0x34CCC320UL, 0x3FF64346UL,
|
||||
0x759D8933UL, 0xBC8C483CUL, 0x82552225UL, 0x3FF66238UL, 0x87591C34UL, 0xBC9BB609UL,
|
||||
0xD44CA973UL, 0x3FF68155UL, 0x44F73E65UL, 0x3C6038AEUL, 0x667F3BCDUL, 0x3FF6A09EUL,
|
||||
0x13B26456UL, 0xBC9BDD34UL, 0x750BDABFUL, 0x3FF6C012UL, 0x67FF0B0DUL, 0xBC728956UL,
|
||||
0x3C651A2FUL, 0x3FF6DFB2UL, 0x683C88ABUL, 0xBC6BBE3AUL, 0xF9519484UL, 0x3FF6FF7DUL,
|
||||
0x25860EF6UL, 0xBC883C0FUL, 0xE8EC5F74UL, 0x3FF71F75UL, 0x86887A99UL, 0xBC816E47UL,
|
||||
0x48A58174UL, 0x3FF73F9AUL, 0x6C65D53CUL, 0xBC90A8D9UL, 0x564267C9UL, 0x3FF75FEBUL,
|
||||
0x57316DD3UL, 0xBC902459UL, 0x4FDE5D3FUL, 0x3FF78069UL, 0x0A02162DUL, 0x3C9866B8UL,
|
||||
0x73EB0187UL, 0x3FF7A114UL, 0xEE04992FUL, 0xBC841577UL, 0x0130C132UL, 0x3FF7C1EDUL,
|
||||
0xD1164DD6UL, 0x3C9F124CUL, 0x36CF4E62UL, 0x3FF7E2F3UL, 0xBA15797EUL, 0x3C705D02UL,
|
||||
0x543E1A12UL, 0x3FF80427UL, 0x626D972BUL, 0xBC927C86UL, 0x994CCE13UL, 0x3FF82589UL,
|
||||
0xD41532D8UL, 0xBC9D4C1DUL, 0x4623C7ADUL, 0x3FF8471AUL, 0xA341CDFBUL, 0xBC88D684UL,
|
||||
0x9B4492EDUL, 0x3FF868D9UL, 0x9BD4F6BAUL, 0xBC9FC6F8UL, 0xD98A6699UL, 0x3FF88AC7UL,
|
||||
0xF37CB53AUL, 0x3C9994C2UL, 0x422AA0DBUL, 0x3FF8ACE5UL, 0x56864B27UL, 0x3C96E9F1UL,
|
||||
0x16B5448CUL, 0x3FF8CF32UL, 0x32E9E3AAUL, 0xBC70D55EUL, 0x99157736UL, 0x3FF8F1AEUL,
|
||||
0xA2E3976CUL, 0x3C85CC13UL, 0x0B91FFC6UL, 0x3FF9145BUL, 0x2E582524UL, 0xBC9DD679UL,
|
||||
0xB0CDC5E5UL, 0x3FF93737UL, 0x81B57EBCUL, 0xBC675FC7UL, 0xCBC8520FUL, 0x3FF95A44UL,
|
||||
0x96A5F039UL, 0xBC764B7CUL, 0x9FDE4E50UL, 0x3FF97D82UL, 0x7C1B85D1UL, 0xBC9D185BUL,
|
||||
0x70CA07BAUL, 0x3FF9A0F1UL, 0x91CEE632UL, 0xBC9173BDUL, 0x82A3F090UL, 0x3FF9C491UL,
|
||||
0xB071F2BEUL, 0x3C7C7C46UL, 0x19E32323UL, 0x3FF9E863UL, 0x78E64C6EUL, 0x3C7824CAUL,
|
||||
0x7B5DE565UL, 0x3FFA0C66UL, 0x5D1CD533UL, 0xBC935949UL, 0xEC4A2D33UL, 0x3FFA309BUL,
|
||||
0x7DDC36ABUL, 0x3C96305CUL, 0xB23E255DUL, 0x3FFA5503UL, 0xDB8D41E1UL, 0xBC9D2F6EUL,
|
||||
0x1330B358UL, 0x3FFA799EUL, 0xCAC563C7UL, 0x3C9BCB7EUL, 0x5579FDBFUL, 0x3FFA9E6BUL,
|
||||
0x0EF7FD31UL, 0x3C90FAC9UL, 0xBFD3F37AUL, 0x3FFAC36BUL, 0xCAE76CD0UL, 0xBC8F9234UL,
|
||||
0x995AD3ADUL, 0x3FFAE89FUL, 0x345DCC81UL, 0x3C97A1CDUL, 0x298DB666UL, 0x3FFB0E07UL,
|
||||
0x4C80E425UL, 0xBC9BDEF5UL, 0xB84F15FBUL, 0x3FFB33A2UL, 0x3084D708UL, 0xBC62805EUL,
|
||||
0x8DE5593AUL, 0x3FFB5972UL, 0xBBBA6DE3UL, 0xBC9C71DFUL, 0xF2FB5E47UL, 0x3FFB7F76UL,
|
||||
0x7E54AC3BUL, 0xBC75584FUL, 0x30A1064AUL, 0x3FFBA5B0UL, 0x0E54292EUL, 0xBC9EFCD3UL,
|
||||
0x904BC1D2UL, 0x3FFBCC1EUL, 0x7A2D9E84UL, 0x3C823DD0UL, 0x5BD71E09UL, 0x3FFBF2C2UL,
|
||||
0x3F6B9C73UL, 0xBC9EFDCAUL, 0xDD85529CUL, 0x3FFC199BUL, 0x895048DDUL, 0x3C811065UL,
|
||||
0x5FFFD07AUL, 0x3FFC40ABUL, 0xE083C60AUL, 0x3C9B4537UL, 0x2E57D14BUL, 0x3FFC67F1UL,
|
||||
0xFF483CADUL, 0x3C92884DUL, 0x9406E7B5UL, 0x3FFC8F6DUL, 0x48805C44UL, 0x3C71ACBCUL,
|
||||
0xDCEF9069UL, 0x3FFCB720UL, 0xD1E949DCUL, 0x3C7503CBUL, 0x555DC3FAUL, 0x3FFCDF0BUL,
|
||||
0x53829D72UL, 0xBC8DD83BUL, 0x4A07897CUL, 0x3FFD072DUL, 0x43797A9CUL, 0xBC9CBC37UL,
|
||||
0x080D89F2UL, 0x3FFD2F87UL, 0x719D8578UL, 0xBC9D487BUL, 0xDCFBA487UL, 0x3FFD5818UL,
|
||||
0xD75B3707UL, 0x3C82ED02UL, 0x16C98398UL, 0x3FFD80E3UL, 0x8BEDDFE8UL, 0xBC911EC1UL,
|
||||
0x03DB3285UL, 0x3FFDA9E6UL, 0x696DB532UL, 0x3C9C2300UL, 0xF301B460UL, 0x3FFDD321UL,
|
||||
0x78F018C3UL, 0x3C92DA57UL, 0x337B9B5FUL, 0x3FFDFC97UL, 0x4F184B5CUL, 0xBC91A5CDUL,
|
||||
0x14F5A129UL, 0x3FFE2646UL, 0x817A1496UL, 0xBC97B627UL, 0xE78B3FF6UL, 0x3FFE502EUL,
|
||||
0x80A9CC8FUL, 0x3C839E89UL, 0xFBC74C83UL, 0x3FFE7A51UL, 0xCA0C8DE2UL, 0x3C92D522UL,
|
||||
0xA2A490DAUL, 0x3FFEA4AFUL, 0x179C2893UL, 0xBC9E9C23UL, 0x2D8E67F1UL, 0x3FFECF48UL,
|
||||
0xB411AD8CUL, 0xBC9C93F3UL, 0xEE615A27UL, 0x3FFEFA1BUL, 0x86A4B6B0UL, 0x3C9DC7F4UL,
|
||||
0x376BBA97UL, 0x3FFF252BUL, 0xBF0D8E43UL, 0x3C93A1A5UL, 0x5B6E4540UL, 0x3FFF5076UL,
|
||||
0x2DD8A18BUL, 0x3C99D3E1UL, 0xAD9CBE14UL, 0x3FFF7BFDUL, 0xD006350AUL, 0xBC9DBB12UL,
|
||||
0x819E90D8UL, 0x3FFFA7C1UL, 0xF3A5931EUL, 0x3C874853UL, 0x2B8F71F1UL, 0x3FFFD3C2UL,
|
||||
0x966579E7UL, 0x3C62EB74UL
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) static const juint _T2_neg_f[] =
|
||||
{
|
||||
0x00000000UL, 0x3FF00000UL, 0x00000000UL, 0x00000000UL, 0x2B8F71F1UL, 0x3FEFD3C2UL,
|
||||
0x966579E7UL, 0x3C52EB74UL, 0x819E90D8UL, 0x3FEFA7C1UL, 0xF3A5931EUL, 0x3C774853UL,
|
||||
0xAD9CBE14UL, 0x3FEF7BFDUL, 0xD006350AUL, 0xBC8DBB12UL, 0x5B6E4540UL, 0x3FEF5076UL,
|
||||
0x2DD8A18BUL, 0x3C89D3E1UL, 0x376BBA97UL, 0x3FEF252BUL, 0xBF0D8E43UL, 0x3C83A1A5UL,
|
||||
0xEE615A27UL, 0x3FEEFA1BUL, 0x86A4B6B0UL, 0x3C8DC7F4UL, 0x2D8E67F1UL, 0x3FEECF48UL,
|
||||
0xB411AD8CUL, 0xBC8C93F3UL, 0xA2A490DAUL, 0x3FEEA4AFUL, 0x179C2893UL, 0xBC8E9C23UL,
|
||||
0xFBC74C83UL, 0x3FEE7A51UL, 0xCA0C8DE2UL, 0x3C82D522UL, 0xE78B3FF6UL, 0x3FEE502EUL,
|
||||
0x80A9CC8FUL, 0x3C739E89UL, 0x14F5A129UL, 0x3FEE2646UL, 0x817A1496UL, 0xBC87B627UL,
|
||||
0x337B9B5FUL, 0x3FEDFC97UL, 0x4F184B5CUL, 0xBC81A5CDUL, 0xF301B460UL, 0x3FEDD321UL,
|
||||
0x78F018C3UL, 0x3C82DA57UL, 0x03DB3285UL, 0x3FEDA9E6UL, 0x696DB532UL, 0x3C8C2300UL,
|
||||
0x16C98398UL, 0x3FED80E3UL, 0x8BEDDFE8UL, 0xBC811EC1UL, 0xDCFBA487UL, 0x3FED5818UL,
|
||||
0xD75B3707UL, 0x3C72ED02UL, 0x080D89F2UL, 0x3FED2F87UL, 0x719D8578UL, 0xBC8D487BUL,
|
||||
0x4A07897CUL, 0x3FED072DUL, 0x43797A9CUL, 0xBC8CBC37UL, 0x555DC3FAUL, 0x3FECDF0BUL,
|
||||
0x53829D72UL, 0xBC7DD83BUL, 0xDCEF9069UL, 0x3FECB720UL, 0xD1E949DCUL, 0x3C6503CBUL,
|
||||
0x9406E7B5UL, 0x3FEC8F6DUL, 0x48805C44UL, 0x3C61ACBCUL, 0x2E57D14BUL, 0x3FEC67F1UL,
|
||||
0xFF483CADUL, 0x3C82884DUL, 0x5FFFD07AUL, 0x3FEC40ABUL, 0xE083C60AUL, 0x3C8B4537UL,
|
||||
0xDD85529CUL, 0x3FEC199BUL, 0x895048DDUL, 0x3C711065UL, 0x5BD71E09UL, 0x3FEBF2C2UL,
|
||||
0x3F6B9C73UL, 0xBC8EFDCAUL, 0x904BC1D2UL, 0x3FEBCC1EUL, 0x7A2D9E84UL, 0x3C723DD0UL,
|
||||
0x30A1064AUL, 0x3FEBA5B0UL, 0x0E54292EUL, 0xBC8EFCD3UL, 0xF2FB5E47UL, 0x3FEB7F76UL,
|
||||
0x7E54AC3BUL, 0xBC65584FUL, 0x8DE5593AUL, 0x3FEB5972UL, 0xBBBA6DE3UL, 0xBC8C71DFUL,
|
||||
0xB84F15FBUL, 0x3FEB33A2UL, 0x3084D708UL, 0xBC52805EUL, 0x298DB666UL, 0x3FEB0E07UL,
|
||||
0x4C80E425UL, 0xBC8BDEF5UL, 0x995AD3ADUL, 0x3FEAE89FUL, 0x345DCC81UL, 0x3C87A1CDUL,
|
||||
0xBFD3F37AUL, 0x3FEAC36BUL, 0xCAE76CD0UL, 0xBC7F9234UL, 0x5579FDBFUL, 0x3FEA9E6BUL,
|
||||
0x0EF7FD31UL, 0x3C80FAC9UL, 0x1330B358UL, 0x3FEA799EUL, 0xCAC563C7UL, 0x3C8BCB7EUL,
|
||||
0xB23E255DUL, 0x3FEA5503UL, 0xDB8D41E1UL, 0xBC8D2F6EUL, 0xEC4A2D33UL, 0x3FEA309BUL,
|
||||
0x7DDC36ABUL, 0x3C86305CUL, 0x7B5DE565UL, 0x3FEA0C66UL, 0x5D1CD533UL, 0xBC835949UL,
|
||||
0x19E32323UL, 0x3FE9E863UL, 0x78E64C6EUL, 0x3C6824CAUL, 0x82A3F090UL, 0x3FE9C491UL,
|
||||
0xB071F2BEUL, 0x3C6C7C46UL, 0x70CA07BAUL, 0x3FE9A0F1UL, 0x91CEE632UL, 0xBC8173BDUL,
|
||||
0x9FDE4E50UL, 0x3FE97D82UL, 0x7C1B85D1UL, 0xBC8D185BUL, 0xCBC8520FUL, 0x3FE95A44UL,
|
||||
0x96A5F039UL, 0xBC664B7CUL, 0xB0CDC5E5UL, 0x3FE93737UL, 0x81B57EBCUL, 0xBC575FC7UL,
|
||||
0x0B91FFC6UL, 0x3FE9145BUL, 0x2E582524UL, 0xBC8DD679UL, 0x99157736UL, 0x3FE8F1AEUL,
|
||||
0xA2E3976CUL, 0x3C75CC13UL, 0x16B5448CUL, 0x3FE8CF32UL, 0x32E9E3AAUL, 0xBC60D55EUL,
|
||||
0x422AA0DBUL, 0x3FE8ACE5UL, 0x56864B27UL, 0x3C86E9F1UL, 0xD98A6699UL, 0x3FE88AC7UL,
|
||||
0xF37CB53AUL, 0x3C8994C2UL, 0x9B4492EDUL, 0x3FE868D9UL, 0x9BD4F6BAUL, 0xBC8FC6F8UL,
|
||||
0x4623C7ADUL, 0x3FE8471AUL, 0xA341CDFBUL, 0xBC78D684UL, 0x994CCE13UL, 0x3FE82589UL,
|
||||
0xD41532D8UL, 0xBC8D4C1DUL, 0x543E1A12UL, 0x3FE80427UL, 0x626D972BUL, 0xBC827C86UL,
|
||||
0x36CF4E62UL, 0x3FE7E2F3UL, 0xBA15797EUL, 0x3C605D02UL, 0x0130C132UL, 0x3FE7C1EDUL,
|
||||
0xD1164DD6UL, 0x3C8F124CUL, 0x73EB0187UL, 0x3FE7A114UL, 0xEE04992FUL, 0xBC741577UL,
|
||||
0x4FDE5D3FUL, 0x3FE78069UL, 0x0A02162DUL, 0x3C8866B8UL, 0x564267C9UL, 0x3FE75FEBUL,
|
||||
0x57316DD3UL, 0xBC802459UL, 0x48A58174UL, 0x3FE73F9AUL, 0x6C65D53CUL, 0xBC80A8D9UL,
|
||||
0xE8EC5F74UL, 0x3FE71F75UL, 0x86887A99UL, 0xBC716E47UL, 0xF9519484UL, 0x3FE6FF7DUL,
|
||||
0x25860EF6UL, 0xBC783C0FUL, 0x3C651A2FUL, 0x3FE6DFB2UL, 0x683C88ABUL, 0xBC5BBE3AUL,
|
||||
0x750BDABFUL, 0x3FE6C012UL, 0x67FF0B0DUL, 0xBC628956UL, 0x667F3BCDUL, 0x3FE6A09EUL,
|
||||
0x13B26456UL, 0xBC8BDD34UL, 0xD44CA973UL, 0x3FE68155UL, 0x44F73E65UL, 0x3C5038AEUL,
|
||||
0x82552225UL, 0x3FE66238UL, 0x87591C34UL, 0xBC8BB609UL, 0x34CCC320UL, 0x3FE64346UL,
|
||||
0x759D8933UL, 0xBC7C483CUL, 0xB03A5585UL, 0x3FE6247EUL, 0x7E40B497UL, 0xBC8383C1UL,
|
||||
0xB976DC09UL, 0x3FE605E1UL, 0x9B56DE47UL, 0xBC83E242UL, 0x15AD2148UL, 0x3FE5E76FUL,
|
||||
0x3080E65EUL, 0x3C8BA6F9UL, 0x8A5946B7UL, 0x3FE5C926UL, 0x816986A2UL, 0x3C2C4B1BUL,
|
||||
0xDD485429UL, 0x3FE5AB07UL, 0x054647ADUL, 0x3C86324CUL, 0xD497C7FDUL, 0x3FE58D12UL,
|
||||
0x5B9A1DE8UL, 0x3C7295E1UL, 0x36B527DAUL, 0x3FE56F47UL, 0x011D93ADUL, 0x3C89BB2CUL,
|
||||
0xCA5D920FUL, 0x3FE551A4UL, 0xEFEDE59BUL, 0xBC7D689CUL, 0x569D4F82UL, 0x3FE5342BUL,
|
||||
0x1DB13CADUL, 0xBC707ABEUL, 0xA2CF6642UL, 0x3FE516DAUL, 0x69BD93EFUL, 0xBC7F7685UL,
|
||||
0x769D2CA7UL, 0x3FE4F9B2UL, 0xD25957E3UL, 0xBC84B309UL, 0x99FDDD0DUL, 0x3FE4DCB2UL,
|
||||
0xBC6A7833UL, 0x3C88ECDBUL, 0xD5362A27UL, 0x3FE4BFDAUL, 0xAFEC42E2UL, 0x3C6D4397UL,
|
||||
0xF0D7D3DEUL, 0x3FE4A32AUL, 0xF3D1BE56UL, 0x3C89CB62UL, 0xB5C13CD0UL, 0x3FE486A2UL,
|
||||
0xB69062F0UL, 0x3C63C1A3UL, 0xED1D0057UL, 0x3FE46A41UL, 0xD1648A76UL, 0x3C8C944BUL,
|
||||
0x6061892DUL, 0x3FE44E08UL, 0x04EF80D0UL, 0x3C389B7AUL, 0xD950A897UL, 0x3FE431F5UL,
|
||||
0xE35F7999UL, 0xBC71C7DDUL, 0x21F72E2AUL, 0x3FE4160AUL, 0x1C309278UL, 0xBC4EF369UL,
|
||||
0x04AC801CUL, 0x3FE3FA45UL, 0xF956F9F3UL, 0xBC87D023UL, 0x4C123422UL, 0x3FE3DEA6UL,
|
||||
0x11F09EBCUL, 0x3C7ADA09UL, 0xC313A8E5UL, 0x3FE3C32DUL, 0x375D29C3UL, 0xBC8EFFF8UL,
|
||||
0x34E59FF7UL, 0x3FE3A7DBUL, 0xD661F5E3UL, 0xBC65E436UL, 0x6D05D866UL, 0x3FE38CAEUL,
|
||||
0x3C9904BDUL, 0xBC8E958DUL, 0x373AA9CBUL, 0x3FE371A7UL, 0xBF42EAE2UL, 0xBC863AEAUL,
|
||||
0x5F929FF1UL, 0x3FE356C5UL, 0x5C4E4628UL, 0xBC7B5CEEUL, 0xB26416FFUL, 0x3FE33C08UL,
|
||||
0x843659A6UL, 0x3C832721UL, 0xFC4CD831UL, 0x3FE32170UL, 0x8E18047CUL, 0x3C7A9CE7UL,
|
||||
0x0A31B715UL, 0x3FE306FEUL, 0xD23182E4UL, 0x3C76F46AUL, 0xA93E2F56UL, 0x3FE2ECAFUL,
|
||||
0x45D52383UL, 0x3C61CA0FUL, 0xA6E4030BUL, 0x3FE2D285UL, 0x54DB41D5UL, 0x3C800247UL,
|
||||
0xD0DAD990UL, 0x3FE2B87FUL, 0xD6381AA4UL, 0xBC310ADCUL, 0xF51FDEE1UL, 0x3FE29E9DUL,
|
||||
0xAFAD1255UL, 0x3C7612E8UL, 0xE1F56381UL, 0x3FE284DFUL, 0x8C3F0D7EUL, 0xBC8A4C3AUL,
|
||||
0x65E27CDDUL, 0x3FE26B45UL, 0x9940E9D9UL, 0x3C72BD33UL, 0x4FB2A63FUL, 0x3FE251CEUL,
|
||||
0xBEF4F4A4UL, 0x3C7AC155UL, 0x6E756238UL, 0x3FE2387AUL, 0xB6C70573UL, 0x3C89B07EUL,
|
||||
0x917DDC96UL, 0x3FE21F49UL, 0x9494A5EEUL, 0x3C72A97EUL, 0x88628CD6UL, 0x3FE2063BUL,
|
||||
0x814A8495UL, 0x3C7DC775UL, 0x22FCD91DUL, 0x3FE1ED50UL, 0x027BB78CUL, 0xBC81DF98UL,
|
||||
0x3168B9AAUL, 0x3FE1D487UL, 0x00A2643CUL, 0x3C8E016EUL, 0x84045CD4UL, 0x3FE1BBE0UL,
|
||||
0x352EF607UL, 0xBC895386UL, 0xEB6FCB75UL, 0x3FE1A35BUL, 0x7B4968E4UL, 0x3C7E5B4CUL,
|
||||
0x388C8DEAUL, 0x3FE18AF9UL, 0xD1970F6CUL, 0xBC811023UL, 0x3C7D517BUL, 0x3FE172B8UL,
|
||||
0xB9D78A76UL, 0xBC719041UL, 0xC8A58E51UL, 0x3FE15A98UL, 0xB9EEAB0AUL, 0x3C72406AUL,
|
||||
0xAEA92DE0UL, 0x3FE1429AUL, 0x9AF1369EUL, 0xBC832FBFUL, 0xC06C31CCUL, 0x3FE12ABDUL,
|
||||
0xB36CA5C7UL, 0xBC41B514UL, 0xD0125B51UL, 0x3FE11301UL, 0x39449B3AUL, 0xBC86C510UL,
|
||||
0xAFFED31BUL, 0x3FE0FB66UL, 0xC44EBD7BUL, 0xBC5B9BEDUL, 0x32D3D1A2UL, 0x3FE0E3ECUL,
|
||||
0x27C57B52UL, 0x3C303A17UL, 0x2B7247F7UL, 0x3FE0CC92UL, 0x16E24F71UL, 0x3C801EDCUL,
|
||||
0x6CF9890FUL, 0x3FE0B558UL, 0x4ADC610BUL, 0x3C88A62EUL, 0xCAC6F383UL, 0x3FE09E3EUL,
|
||||
0x18316136UL, 0x3C814878UL, 0x18759BC8UL, 0x3FE08745UL, 0x4BB284FFUL, 0x3C5186BEUL,
|
||||
0x29DDF6DEUL, 0x3FE0706BUL, 0xE2B13C27UL, 0xBC7C91DFUL, 0xD3158574UL, 0x3FE059B0UL,
|
||||
0xA475B465UL, 0x3C7D73E2UL, 0xE86E7F85UL, 0x3FE04315UL, 0x1977C96EUL, 0xBC80A31CUL,
|
||||
0x3E778061UL, 0x3FE02C9AUL, 0x535B085DUL, 0xBC619083UL, 0xA9FB3335UL, 0x3FE0163DUL,
|
||||
0x9AB8CDB7UL, 0x3C8B6129UL
|
||||
};
|
||||
|
||||
#define __ _masm->
|
||||
|
||||
address StubGenerator::generate_libmSinh() {
|
||||
StubId stub_id = StubId::stubgen_dsinh_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
address start = __ pc();
|
||||
|
||||
Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_3_0_2, L_2TAG_PACKET_4_0_2;
|
||||
Label L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2;
|
||||
Label B1_2, B1_5;
|
||||
|
||||
address HALFMASK = (address)_HALFMASK;
|
||||
address MASK3 = (address)_MASK3;
|
||||
address L2E = (address)_L2E;
|
||||
address Shifter = (address)_Shifter;
|
||||
address cv = (address)_cv;
|
||||
address pv = (address)_pv;
|
||||
address T2f = (address) _T2f;
|
||||
address T2_neg_f = (address) _T2_neg_f;
|
||||
|
||||
__ enter(); // required for proper stackwalking of RuntimeStub frame
|
||||
|
||||
__ bind(B1_2);
|
||||
__ xorpd(xmm4, xmm4);
|
||||
__ movsd(xmm1, ExternalAddress(L2E), r11 /*rscratch*/);
|
||||
__ movl(rax, 32768);
|
||||
__ pinsrw(xmm4, rax, 3);
|
||||
__ pextrw(rcx, xmm0, 3);
|
||||
__ andnpd(xmm4, xmm0);
|
||||
__ pshufd(xmm5, xmm4, 68);
|
||||
__ movl(rdx, 32768);
|
||||
__ andl(rdx, rcx);
|
||||
__ andl(rcx, 32767);
|
||||
__ subl(rcx, 16343);
|
||||
__ cmpl(rcx, 177);
|
||||
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_0_0_2); // Branch only if |x| is not in [23/64, 3*2^8)
|
||||
__ movsd(xmm3, ExternalAddress(HALFMASK), r11 /*rscratch*/);
|
||||
__ movsd(xmm2, ExternalAddress(L2E + 8), r11 /*rscratch*/);
|
||||
__ movsd(xmm6, ExternalAddress(Shifter), r11 /*rscratch*/);
|
||||
__ andpd(xmm3, xmm0);
|
||||
__ subsd(xmm4, xmm3);
|
||||
__ mulsd(xmm3, xmm1);
|
||||
__ mulsd(xmm2, xmm5);
|
||||
__ cvtsd2siq(rax, xmm3);
|
||||
__ shll(rdx, 3);
|
||||
__ orl(rax, rdx);
|
||||
__ movq(xmm7, xmm3);
|
||||
__ addsd(xmm3, xmm6);
|
||||
__ mulsd(xmm1, xmm4);
|
||||
__ xorpd(xmm5, xmm5);
|
||||
__ subsd(xmm3, xmm6);
|
||||
__ movapd(xmm4, ExternalAddress(cv), r11 /*rscratch*/);
|
||||
__ addsd(xmm2, xmm1);
|
||||
__ movapd(xmm6, ExternalAddress(cv + 16), r11 /*rscratch*/);
|
||||
__ subsd(xmm7, xmm3);
|
||||
__ movl(rdx, 32704);
|
||||
__ pinsrw(xmm5, rdx, 3);
|
||||
__ movapd(xmm1, ExternalAddress(cv + 32), r11 /*rscratch*/);
|
||||
__ addsd(xmm2, xmm7);
|
||||
__ movl(rdx, 127);
|
||||
__ andl(rdx, rax);
|
||||
__ addl(rdx, rdx);
|
||||
__ shrl(rax, 3);
|
||||
__ andl(rax, 65520);
|
||||
__ addl(rax, 16352);
|
||||
__ xorpd(xmm0, xmm0);
|
||||
__ cmpl(rcx, 161);
|
||||
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_1_0_2); // Branch only if |x| is not in [23/64, 3*2^7)
|
||||
__ pshufd(xmm5, xmm5, 68);
|
||||
__ pinsrw(xmm0, rax, 3);
|
||||
__ pshufd(xmm0, xmm0, 68);
|
||||
__ psubw(xmm5, xmm0);
|
||||
__ lea(r8, ExternalAddress(T2f));
|
||||
__ mulpd(xmm0, Address(r8, rdx, Address::times_8));
|
||||
__ lea(r8, ExternalAddress(T2_neg_f));
|
||||
__ mulpd(xmm5, Address(r8, rdx, Address::times_8));
|
||||
__ pshufd(xmm3, xmm2, 68);
|
||||
__ movapd(xmm7, ExternalAddress(cv + 48), r11 /*rscratch*/);
|
||||
__ pshufd(xmm2, xmm2, 68);
|
||||
__ mulpd(xmm3, xmm3);
|
||||
__ mulpd(xmm4, xmm2);
|
||||
__ mulpd(xmm6, xmm2);
|
||||
__ mulpd(xmm2, ExternalAddress(cv + 64), r11 /*rscratch*/);
|
||||
__ mulpd(xmm1, xmm3);
|
||||
__ mulpd(xmm7, xmm3);
|
||||
__ mulpd(xmm4, xmm3);
|
||||
__ mulpd(xmm1, xmm3);
|
||||
__ addpd(xmm6, xmm7);
|
||||
__ movq(xmm7, xmm0);
|
||||
__ addpd(xmm4, xmm1);
|
||||
__ shufpd(xmm7, xmm5, 0);
|
||||
__ subpd(xmm0, xmm5);
|
||||
__ mulpd(xmm2, xmm7);
|
||||
__ addpd(xmm4, xmm6);
|
||||
__ subsd(xmm7, xmm0);
|
||||
__ mulpd(xmm4, xmm2);
|
||||
__ pshufd(xmm6, xmm0, 238);
|
||||
__ subsd(xmm7, xmm5);
|
||||
__ addpd(xmm4, xmm2);
|
||||
__ addsd(xmm7, xmm6);
|
||||
__ pshufd(xmm2, xmm4, 238);
|
||||
__ addsd(xmm2, xmm7);
|
||||
__ addsd(xmm2, xmm4);
|
||||
__ addsd(xmm0, xmm2);
|
||||
__ jmp(B1_5);
|
||||
|
||||
__ bind(L_2TAG_PACKET_1_0_2);
|
||||
__ subl(rax, 16352);
|
||||
__ movl(rcx, rax);
|
||||
__ andl(rax, 32752);
|
||||
__ shrl(rax, 1);
|
||||
__ andl(rax, 65520);
|
||||
__ subl(rcx, rax);
|
||||
__ addl(rax, 16352);
|
||||
__ pinsrw(xmm0, rax, 3);
|
||||
__ pshufd(xmm0, xmm0, 68);
|
||||
__ lea(r8, ExternalAddress(T2f));
|
||||
__ mulpd(xmm0, Address(r8, rdx, Address::times_8));
|
||||
__ pshufd(xmm3, xmm2, 68);
|
||||
__ movsd(xmm7, ExternalAddress(cv + 48), r11 /*rscratch*/);
|
||||
__ mulsd(xmm3, xmm3);
|
||||
__ mulsd(xmm4, xmm2);
|
||||
__ mulsd(xmm6, xmm2);
|
||||
__ mulsd(xmm2, ExternalAddress(cv + 64), r11 /*rscratch*/);
|
||||
__ mulsd(xmm1, xmm3);
|
||||
__ mulsd(xmm7, xmm3);
|
||||
__ mulsd(xmm4, xmm3);
|
||||
__ addl(rcx, 16368);
|
||||
__ pinsrw(xmm5, rcx, 3);
|
||||
__ mulsd(xmm1, xmm3);
|
||||
__ addsd(xmm6, xmm7);
|
||||
__ addsd(xmm4, xmm1);
|
||||
__ mulsd(xmm2, xmm0);
|
||||
__ addsd(xmm4, xmm6);
|
||||
__ mulsd(xmm4, xmm2);
|
||||
__ pshufd(xmm6, xmm0, 238);
|
||||
__ addsd(xmm4, xmm6);
|
||||
__ addsd(xmm2, xmm4);
|
||||
__ addsd(xmm0, xmm2);
|
||||
__ mulsd(xmm0, xmm5);
|
||||
__ jmp(B1_5);
|
||||
|
||||
__ bind(L_2TAG_PACKET_0_0_2);
|
||||
__ addl(rcx, 16343);
|
||||
__ cmpl(rcx, 16343);
|
||||
__ jcc(Assembler::above, L_2TAG_PACKET_3_0_2); // Branch only if |x| > 23/64
|
||||
__ cmpl(rcx, 15856);
|
||||
__ jcc(Assembler::below, L_2TAG_PACKET_4_0_2); // Branch only if |x| < 2^-32
|
||||
__ movapd(xmm1, ExternalAddress(pv), r11 /*rscratch*/);
|
||||
__ pshufd(xmm6, xmm0, 68);
|
||||
__ mulpd(xmm5, xmm5);
|
||||
__ movapd(xmm2, ExternalAddress(pv + 16), r11 /*rscratch*/);
|
||||
__ pshufd(xmm7, xmm0, 68);
|
||||
__ movapd(xmm3, ExternalAddress(pv + 32), r11 /*rscratch*/);
|
||||
__ pshufd(xmm4, xmm0, 68);
|
||||
__ andpd(xmm6, ExternalAddress(MASK3), r11 /*rscratch*/);
|
||||
__ mulpd(xmm1, xmm5);
|
||||
__ mulsd(xmm2, xmm5);
|
||||
__ subpd(xmm4, xmm6);
|
||||
__ mulpd(xmm7, xmm5);
|
||||
__ addpd(xmm1, xmm3);
|
||||
__ pshufd(xmm3, xmm6, 68);
|
||||
__ mulpd(xmm5, xmm5);
|
||||
__ mulsd(xmm2, xmm7);
|
||||
__ mulpd(xmm1, xmm7);
|
||||
__ pshufd(xmm7, xmm0, 68);
|
||||
__ mulsd(xmm6, xmm6);
|
||||
__ addsd(xmm7, xmm7);
|
||||
__ mulsd(xmm4, xmm4);
|
||||
__ mulpd(xmm1, xmm5);
|
||||
__ addsd(xmm7, xmm0);
|
||||
__ mulsd(xmm6, xmm3);
|
||||
__ mulsd(xmm7, xmm3);
|
||||
__ pshufd(xmm3, xmm1, 238);
|
||||
__ mulsd(xmm1, xmm5);
|
||||
__ pshufd(xmm5, xmm4, 238);
|
||||
__ addsd(xmm3, xmm2);
|
||||
__ pshufd(xmm2, xmm2, 238);
|
||||
__ addsd(xmm7, xmm4);
|
||||
__ movq(xmm4, xmm0);
|
||||
__ mulsd(xmm6, xmm2);
|
||||
__ mulsd(xmm7, xmm5);
|
||||
__ addsd(xmm0, xmm6);
|
||||
__ mulsd(xmm7, xmm2);
|
||||
__ subsd(xmm4, xmm0);
|
||||
__ addsd(xmm1, xmm7);
|
||||
__ addsd(xmm6, xmm4);
|
||||
__ addsd(xmm1, xmm3);
|
||||
__ addsd(xmm1, xmm6);
|
||||
__ addsd(xmm0, xmm1);
|
||||
__ jmp(B1_5);
|
||||
|
||||
__ bind(L_2TAG_PACKET_4_0_2);
|
||||
__ cmpl(rcx, 16);
|
||||
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_5_0_2); // Branch only if |x| is not denormalized
|
||||
__ movq(xmm1, xmm0);
|
||||
__ mulsd(xmm1, xmm1);
|
||||
__ jmp(B1_5);
|
||||
|
||||
__ bind(L_2TAG_PACKET_5_0_2);
|
||||
__ xorpd(xmm2, xmm2);
|
||||
__ movl(rcx, 17392);
|
||||
__ pinsrw(xmm2, rcx, 3);
|
||||
__ xorpd(xmm3, xmm3);
|
||||
__ movl(rdx, 15344);
|
||||
__ pinsrw(xmm3, rdx, 3);
|
||||
__ mulsd(xmm2, xmm0);
|
||||
__ addsd(xmm0, xmm2);
|
||||
__ mulsd(xmm0, xmm3);
|
||||
__ jmp(B1_5);
|
||||
|
||||
__ bind(L_2TAG_PACKET_3_0_2);
|
||||
__ cmpl(rcx, 32752);
|
||||
__ jcc(Assembler::aboveEqual, L_2TAG_PACKET_6_0_2); // Branch only if |x| is INF or NaN
|
||||
__ xorpd(xmm0, xmm0);
|
||||
__ movl(rax, 32736);
|
||||
__ pinsrw(xmm0, rax, 3);
|
||||
__ orl(rax, rdx);
|
||||
__ pinsrw(xmm1, rax, 3);
|
||||
__ mulsd(xmm0, xmm1);
|
||||
__ jmp(B1_5);
|
||||
|
||||
__ bind(L_2TAG_PACKET_6_0_2);
|
||||
__ xorpd(xmm1, xmm1);
|
||||
__ movl(rax, 32768);
|
||||
__ pinsrw(xmm1, rax, 3);
|
||||
__ andnpd(xmm1, xmm0);
|
||||
__ mulsd(xmm0, xmm1);
|
||||
|
||||
__ bind(B1_5);
|
||||
__ leave(); // required for proper stackwalking of RuntimeStub frame
|
||||
__ ret(0);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
#undef __
|
|
@ -1017,21 +1017,16 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
|||
// change thread state
|
||||
__ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
|
||||
|
||||
if (LockingMode != LM_LEGACY) {
|
||||
// Check preemption for Object.wait()
|
||||
Label not_preempted;
|
||||
__ movptr(rscratch1, Address(r15_thread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ cmpptr(rscratch1, NULL_WORD);
|
||||
__ jccb(Assembler::equal, not_preempted);
|
||||
__ movptr(Address(r15_thread, JavaThread::preempt_alternate_return_offset()), NULL_WORD);
|
||||
__ jmp(rscratch1);
|
||||
__ bind(native_return);
|
||||
__ restore_after_resume(true /* is_native */);
|
||||
__ bind(not_preempted);
|
||||
} else {
|
||||
// any pc will do so just use this one for LM_LEGACY to keep code together.
|
||||
__ bind(native_return);
|
||||
}
|
||||
// Check preemption for Object.wait()
|
||||
Label not_preempted;
|
||||
__ movptr(rscratch1, Address(r15_thread, JavaThread::preempt_alternate_return_offset()));
|
||||
__ cmpptr(rscratch1, NULL_WORD);
|
||||
__ jccb(Assembler::equal, not_preempted);
|
||||
__ movptr(Address(r15_thread, JavaThread::preempt_alternate_return_offset()), NULL_WORD);
|
||||
__ jmp(rscratch1);
|
||||
__ bind(native_return);
|
||||
__ restore_after_resume(true /* is_native */);
|
||||
__ bind(not_preempted);
|
||||
|
||||
// reset_last_Java_frame
|
||||
__ reset_last_Java_frame(true);
|
||||
|
|
|
@ -464,6 +464,13 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||
} else {
|
||||
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
|
||||
}
|
||||
} else if (kind == Interpreter::java_lang_math_sinh) {
|
||||
if (StubRoutines::dsinh() != nullptr) {
|
||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsinh())));
|
||||
} else {
|
||||
return nullptr; // Fallback to default implementation
|
||||
}
|
||||
} else if (kind == Interpreter::java_lang_math_tanh) {
|
||||
if (StubRoutines::dtanh() != nullptr) {
|
||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "runtime/stubCodeGenerator.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/checkedCast.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
#include "utilities/virtualizationSupport.hpp"
|
||||
|
||||
|
@ -1097,21 +1098,16 @@ void VM_Version::get_processor_features() {
|
|||
}
|
||||
}
|
||||
|
||||
char buf[2048];
|
||||
size_t cpu_info_size = jio_snprintf(
|
||||
buf, sizeof(buf),
|
||||
"(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x",
|
||||
cores_per_cpu(), threads_per_core(),
|
||||
cpu_family(), _model, _stepping, os::cpu_microcode_revision());
|
||||
assert(cpu_info_size > 0, "not enough temporary space allocated");
|
||||
stringStream ss(2048);
|
||||
ss.print("(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x",
|
||||
cores_per_cpu(), threads_per_core(),
|
||||
cpu_family(), _model, _stepping, os::cpu_microcode_revision());
|
||||
ss.print(", ");
|
||||
int features_offset = (int)ss.size();
|
||||
insert_features_names(_features, ss);
|
||||
|
||||
insert_features_names(_features, buf + cpu_info_size, sizeof(buf) - cpu_info_size);
|
||||
|
||||
_cpu_info_string = os::strdup(buf);
|
||||
|
||||
_features_string = extract_features_string(_cpu_info_string,
|
||||
strnlen(_cpu_info_string, sizeof(buf)),
|
||||
cpu_info_size);
|
||||
_cpu_info_string = ss.as_string(true);
|
||||
_features_string = _cpu_info_string + features_offset;
|
||||
|
||||
// Use AES instructions if available.
|
||||
if (supports_aes()) {
|
||||
|
@ -3266,13 +3262,15 @@ bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void VM_Version::insert_features_names(VM_Version::VM_Features features, char* buf, size_t buflen) {
|
||||
for (int i = 0; i < MAX_CPU_FEATURES; i++) {
|
||||
if (features.supports_feature((VM_Version::Feature_Flag)i)) {
|
||||
int res = jio_snprintf(buf, buflen, ", %s", _features_names[i]);
|
||||
assert(res > 0, "not enough temporary space allocated");
|
||||
buf += res;
|
||||
buflen -= res;
|
||||
void VM_Version::insert_features_names(VM_Version::VM_Features features, stringStream& ss) {
|
||||
int i = 0;
|
||||
ss.join([&]() {
|
||||
while (i < MAX_CPU_FEATURES) {
|
||||
if (_features.supports_feature((VM_Version::Feature_Flag)i)) {
|
||||
return _features_names[i++];
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
return (const char*)nullptr;
|
||||
}, ", ");
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "utilities/macros.hpp"
|
||||
#include "utilities/sizes.hpp"
|
||||
|
||||
class stringStream;
|
||||
|
||||
class VM_Version : public Abstract_VM_Version {
|
||||
friend class VMStructs;
|
||||
friend class JVMCIVMStructs;
|
||||
|
@ -922,7 +924,7 @@ public:
|
|||
|
||||
static bool is_intel_tsc_synched_at_init();
|
||||
|
||||
static void insert_features_names(VM_Version::VM_Features features, char* buf, size_t buflen);
|
||||
static void insert_features_names(VM_Version::VM_Features features, stringStream& ss);
|
||||
|
||||
// This checks if the JVM is potentially affected by an erratum on Intel CPUs (SKX102)
|
||||
// that causes unpredictable behaviour when jcc crosses 64 byte boundaries. Its microcode
|
||||
|
|
|
@ -14073,33 +14073,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
|||
// ============================================================================
|
||||
// inlined locking and unlocking
|
||||
|
||||
instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{
|
||||
predicate(LockingMode != LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP tmp, TEMP scr, USE_KILL box);
|
||||
ins_cost(300);
|
||||
format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
|
||||
ins_encode %{
|
||||
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
|
||||
$scr$$Register, noreg, noreg, r15_thread, nullptr);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
|
||||
predicate(LockingMode != LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastUnlock object box));
|
||||
effect(TEMP tmp, USE_KILL box);
|
||||
ins_cost(300);
|
||||
format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
|
||||
ins_encode %{
|
||||
__ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{
|
||||
predicate(LockingMode == LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP rax_reg, TEMP tmp, USE_KILL box);
|
||||
ins_cost(300);
|
||||
|
@ -14111,7 +14085,6 @@ instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_Re
|
|||
%}
|
||||
|
||||
instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{
|
||||
predicate(LockingMode == LM_LIGHTWEIGHT);
|
||||
match(Set cr (FastUnlock object rax_reg));
|
||||
effect(TEMP tmp, USE_KILL rax_reg);
|
||||
ins_cost(300);
|
||||
|
|
|
@ -56,11 +56,11 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
|||
const BasicType *sig_bt,
|
||||
const VMRegPair *regs,
|
||||
AdapterHandlerEntry* handler) {
|
||||
// VM expects i2c entry to be always filled. The rest can be unset.
|
||||
handler->set_entry_points(CAST_FROM_FN_PTR(address,zero_null_code_stub),
|
||||
CAST_FROM_FN_PTR(address,zero_null_code_stub),
|
||||
CAST_FROM_FN_PTR(address,zero_null_code_stub),
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
|
|
|
@ -2343,8 +2343,7 @@ int os::open(const char *path, int oflag, int mode) {
|
|||
// specifically destined for a subprocess should have the
|
||||
// close-on-exec flag set. If we don't set it, then careless 3rd
|
||||
// party native code might fork and exec without closing all
|
||||
// appropriate file descriptors (e.g. as we do in closeDescriptors in
|
||||
// UNIXProcess.c), and this in turn might:
|
||||
// appropriate file descriptors, and this in turn might:
|
||||
//
|
||||
// - cause end-of-file to fail to be detected on some file
|
||||
// descriptors, resulting in mysterious hangs, or
|
||||
|
|
|
@ -233,10 +233,10 @@ public:
|
|||
mach_msg_type_number_t num_out = TASK_VM_INFO_COUNT;
|
||||
kern_return_t err = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)(&vm_info), &num_out);
|
||||
if (err == KERN_SUCCESS) {
|
||||
st->print_cr(" vsize: %llu (%llu%s)", vm_info.virtual_size, PROPERFMTARGS(vm_info.virtual_size));
|
||||
st->print_cr(" rss: %llu (%llu%s)", vm_info.resident_size, PROPERFMTARGS(vm_info.resident_size));
|
||||
st->print_cr(" peak rss: %llu (%llu%s)", vm_info.resident_size_peak, PROPERFMTARGS(vm_info.resident_size_peak));
|
||||
st->print_cr(" page size: %d (%ld%s)", vm_info.page_size, PROPERFMTARGS((size_t)vm_info.page_size));
|
||||
st->print_cr(" vsize: %llu (" PROPERFMT ")", vm_info.virtual_size, PROPERFMTARGS((size_t)vm_info.virtual_size));
|
||||
st->print_cr(" rss: %llu (" PROPERFMT ")", vm_info.resident_size, PROPERFMTARGS((size_t)vm_info.resident_size));
|
||||
st->print_cr(" peak rss: %llu (" PROPERFMT ")", vm_info.resident_size_peak, PROPERFMTARGS((size_t)vm_info.resident_size_peak));
|
||||
st->print_cr(" page size: %d (" PROPERFMT ")", vm_info.page_size, PROPERFMTARGS((size_t)vm_info.page_size));
|
||||
} else {
|
||||
st->print_cr("error getting vm_info %d", err);
|
||||
}
|
||||
|
|
|
@ -2251,8 +2251,7 @@ int os::open(const char *path, int oflag, int mode) {
|
|||
// specifically destined for a subprocess should have the
|
||||
// close-on-exec flag set. If we don't set it, then careless 3rd
|
||||
// party native code might fork and exec without closing all
|
||||
// appropriate file descriptors (e.g. as we do in closeDescriptors in
|
||||
// UNIXProcess.c), and this in turn might:
|
||||
// appropriate file descriptors, and this in turn might:
|
||||
//
|
||||
// - cause end-of-file to fail to be detected on some file
|
||||
// descriptors, resulting in mysterious hangs, or
|
||||
|
|
|
@ -4872,9 +4872,8 @@ int os::open(const char *path, int oflag, int mode) {
|
|||
// All file descriptors that are opened in the Java process and not
|
||||
// specifically destined for a subprocess should have the close-on-exec
|
||||
// flag set. If we don't set it, then careless 3rd party native code
|
||||
// might fork and exec without closing all appropriate file descriptors
|
||||
// (e.g. as we do in closeDescriptors in UNIXProcess.c), and this in
|
||||
// turn might:
|
||||
// might fork and exec without closing all appropriate file descriptors,
|
||||
// and this in turn might:
|
||||
//
|
||||
// - cause end-of-file to fail to be detected on some file
|
||||
// descriptors, resulting in mysterious hangs, or
|
||||
|
|
|
@ -3297,10 +3297,43 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
|
|||
}
|
||||
|
||||
size_t os::commit_memory_limit() {
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
GlobalMemoryStatusEx(&ms);
|
||||
return (size_t)ms.ullAvailVirtual;
|
||||
BOOL is_in_job_object = false;
|
||||
BOOL res = IsProcessInJob(GetCurrentProcess(), nullptr, &is_in_job_object);
|
||||
if (!res) {
|
||||
char buf[512];
|
||||
size_t buf_len = os::lasterror(buf, sizeof(buf));
|
||||
warning("Attempt to determine whether the process is running in a job failed for commit limit: %s", buf_len != 0 ? buf : "<unknown error>");
|
||||
|
||||
// Conservatively assume no limit when there was an error calling IsProcessInJob.
|
||||
return SIZE_MAX;
|
||||
}
|
||||
|
||||
if (!is_in_job_object) {
|
||||
// Not limited by a Job Object
|
||||
return SIZE_MAX;
|
||||
}
|
||||
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {};
|
||||
res = QueryInformationJobObject(nullptr, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli), nullptr);
|
||||
if (!res) {
|
||||
char buf[512];
|
||||
size_t buf_len = os::lasterror(buf, sizeof(buf));
|
||||
warning("Attempt to query job object information failed for commit limit: %s", buf_len != 0 ? buf : "<unknown error>");
|
||||
|
||||
// Conservatively assume no limit when there was an error calling QueryInformationJobObject.
|
||||
return SIZE_MAX;
|
||||
}
|
||||
|
||||
if (jeli.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_PROCESS_MEMORY) {
|
||||
return jeli.ProcessMemoryLimit;
|
||||
}
|
||||
|
||||
if (jeli.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_JOB_MEMORY) {
|
||||
return jeli.JobMemoryLimit;
|
||||
}
|
||||
|
||||
// No limit
|
||||
return SIZE_MAX;
|
||||
}
|
||||
|
||||
size_t os::reserve_memory_limit() {
|
||||
|
|
|
@ -67,7 +67,8 @@ void VM_Version::get_os_cpu_info() {
|
|||
// 2) ID_AA64PFR0_EL1 describes AdvSIMD always equals to FP field.
|
||||
// See the Arm ARM, section "ID_AA64PFR0_EL1, AArch64 Processor Feature
|
||||
// Register 0".
|
||||
_features = CPU_FP | CPU_ASIMD;
|
||||
set_feature(CPU_FP);
|
||||
set_feature(CPU_ASIMD);
|
||||
|
||||
// All Apple-darwin Arm processors have AES, PMULL, SHA1 and SHA2.
|
||||
// See https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/arm/commpage/commpage.c#L412
|
||||
|
@ -75,25 +76,28 @@ void VM_Version::get_os_cpu_info() {
|
|||
// these four CPU features, e.g., "hw.optional.arm.FEAT_AES", but the
|
||||
// corresponding string names are not available before xnu-8019 version.
|
||||
// Hence, assertions are omitted considering backward compatibility.
|
||||
_features |= CPU_AES | CPU_PMULL | CPU_SHA1 | CPU_SHA2;
|
||||
set_feature(CPU_AES);
|
||||
set_feature(CPU_PMULL);
|
||||
set_feature(CPU_SHA1);
|
||||
set_feature(CPU_SHA2);
|
||||
|
||||
if (cpu_has("hw.optional.armv8_crc32")) {
|
||||
_features |= CPU_CRC32;
|
||||
set_feature(CPU_CRC32);
|
||||
}
|
||||
if (cpu_has("hw.optional.arm.FEAT_LSE") ||
|
||||
cpu_has("hw.optional.armv8_1_atomics")) {
|
||||
_features |= CPU_LSE;
|
||||
set_feature(CPU_LSE);
|
||||
}
|
||||
if (cpu_has("hw.optional.arm.FEAT_SHA512") ||
|
||||
cpu_has("hw.optional.armv8_2_sha512")) {
|
||||
_features |= CPU_SHA512;
|
||||
set_feature(CPU_SHA512);
|
||||
}
|
||||
if (cpu_has("hw.optional.arm.FEAT_SHA3") ||
|
||||
cpu_has("hw.optional.armv8_2_sha3")) {
|
||||
_features |= CPU_SHA3;
|
||||
set_feature(CPU_SHA3);
|
||||
}
|
||||
if (cpu_has("hw.optional.arm.FEAT_SB")) {
|
||||
_features |= CPU_SB;
|
||||
set_feature(CPU_SB);
|
||||
}
|
||||
|
||||
int cache_line_size;
|
||||
|
|
|
@ -117,22 +117,22 @@ void VM_Version::get_os_cpu_info() {
|
|||
uint64_t auxv = getauxval(AT_HWCAP);
|
||||
uint64_t auxv2 = getauxval(AT_HWCAP2);
|
||||
|
||||
static_assert(CPU_FP == HWCAP_FP, "Flag CPU_FP must follow Linux HWCAP");
|
||||
static_assert(CPU_ASIMD == HWCAP_ASIMD, "Flag CPU_ASIMD must follow Linux HWCAP");
|
||||
static_assert(CPU_EVTSTRM == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow Linux HWCAP");
|
||||
static_assert(CPU_AES == HWCAP_AES, "Flag CPU_AES must follow Linux HWCAP");
|
||||
static_assert(CPU_PMULL == HWCAP_PMULL, "Flag CPU_PMULL must follow Linux HWCAP");
|
||||
static_assert(CPU_SHA1 == HWCAP_SHA1, "Flag CPU_SHA1 must follow Linux HWCAP");
|
||||
static_assert(CPU_SHA2 == HWCAP_SHA2, "Flag CPU_SHA2 must follow Linux HWCAP");
|
||||
static_assert(CPU_CRC32 == HWCAP_CRC32, "Flag CPU_CRC32 must follow Linux HWCAP");
|
||||
static_assert(CPU_LSE == HWCAP_ATOMICS, "Flag CPU_LSE must follow Linux HWCAP");
|
||||
static_assert(CPU_DCPOP == HWCAP_DCPOP, "Flag CPU_DCPOP must follow Linux HWCAP");
|
||||
static_assert(CPU_SHA3 == HWCAP_SHA3, "Flag CPU_SHA3 must follow Linux HWCAP");
|
||||
static_assert(CPU_SHA512 == HWCAP_SHA512, "Flag CPU_SHA512 must follow Linux HWCAP");
|
||||
static_assert(CPU_SVE == HWCAP_SVE, "Flag CPU_SVE must follow Linux HWCAP");
|
||||
static_assert(CPU_PACA == HWCAP_PACA, "Flag CPU_PACA must follow Linux HWCAP");
|
||||
static_assert(CPU_FPHP == HWCAP_FPHP, "Flag CPU_FPHP must follow Linux HWCAP");
|
||||
static_assert(CPU_ASIMDHP == HWCAP_ASIMDHP, "Flag CPU_ASIMDHP must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_FP) == HWCAP_FP, "Flag CPU_FP must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_ASIMD) == HWCAP_ASIMD, "Flag CPU_ASIMD must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_EVTSTRM) == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_AES) == HWCAP_AES, "Flag CPU_AES must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_PMULL) == HWCAP_PMULL, "Flag CPU_PMULL must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_SHA1) == HWCAP_SHA1, "Flag CPU_SHA1 must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_SHA2) == HWCAP_SHA2, "Flag CPU_SHA2 must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_CRC32) == HWCAP_CRC32, "Flag CPU_CRC32 must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_LSE) == HWCAP_ATOMICS, "Flag CPU_LSE must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_DCPOP) == HWCAP_DCPOP, "Flag CPU_DCPOP must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_SHA3) == HWCAP_SHA3, "Flag CPU_SHA3 must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_SHA512) == HWCAP_SHA512, "Flag CPU_SHA512 must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_SVE) == HWCAP_SVE, "Flag CPU_SVE must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_PACA) == HWCAP_PACA, "Flag CPU_PACA must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_FPHP) == HWCAP_FPHP, "Flag CPU_FPHP must follow Linux HWCAP");
|
||||
static_assert(BIT_MASK(CPU_ASIMDHP) == HWCAP_ASIMDHP, "Flag CPU_ASIMDHP must follow Linux HWCAP");
|
||||
_features = auxv & (
|
||||
HWCAP_FP |
|
||||
HWCAP_ASIMD |
|
||||
|
@ -152,8 +152,12 @@ void VM_Version::get_os_cpu_info() {
|
|||
HWCAP_FPHP |
|
||||
HWCAP_ASIMDHP);
|
||||
|
||||
if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
|
||||
if (auxv2 & HWCAP2_SVEBITPERM) _features |= CPU_SVEBITPERM;
|
||||
if (auxv2 & HWCAP2_SVE2) {
|
||||
set_feature(CPU_SVE2);
|
||||
}
|
||||
if (auxv2 & HWCAP2_SVEBITPERM) {
|
||||
set_feature(CPU_SVEBITPERM);
|
||||
}
|
||||
|
||||
uint64_t ctr_el0;
|
||||
uint64_t dczid_el0;
|
||||
|
@ -187,7 +191,7 @@ void VM_Version::get_os_cpu_info() {
|
|||
_revision = v;
|
||||
} else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) {
|
||||
if (strstr(p+1, "dcpop")) {
|
||||
guarantee(_features & CPU_DCPOP, "dcpop availability should be consistent");
|
||||
guarantee(supports_feature(CPU_DCPOP), "dcpop availability should be consistent");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,8 +209,16 @@ frame os::fetch_compiled_frame_from_context(const void* ucVoid) {
|
|||
}
|
||||
|
||||
intptr_t* os::fetch_bcp_from_context(const void* ucVoid) {
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
assert(ucVoid != nullptr, "invariant");
|
||||
const ucontext_t* uc = (const ucontext_t*)ucVoid;
|
||||
assert(os::Posix::ucontext_is_interpreter(uc), "invariant");
|
||||
#if (FP_REG_NUM == 11)
|
||||
assert(Rbcp == R7, "expected FP=R11, Rbcp=R7");
|
||||
return (intptr_t*)uc->uc_mcontext.arm_r7;
|
||||
#else
|
||||
assert(Rbcp == R11, "expected FP=R7, Rbcp=R11");
|
||||
return (intptr_t*)uc->uc_mcontext.arm_fp; // r11
|
||||
#endif
|
||||
}
|
||||
|
||||
frame os::get_sender_for_C_frame(frame* fr) {
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "utilities/debug.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/linkedlist.hpp"
|
||||
#include "utilities/resizeableResourceHash.hpp"
|
||||
#include "utilities/resizableHashTable.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
template <typename T>
|
||||
|
@ -545,7 +545,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) {
|
|||
address dest;
|
||||
LinkedListImpl<int> offsets;
|
||||
};
|
||||
typedef ResizeableResourceHashtable<address, SharedTrampolineRequestsValue, AnyObj::C_HEAP, mtCompiler>
|
||||
typedef ResizeableHashTable<address, SharedTrampolineRequestsValue, AnyObj::C_HEAP, mtCompiler>
|
||||
SharedTrampolineRequests;
|
||||
|
||||
private:
|
||||
|
|
|
@ -166,6 +166,7 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
|
|||
case vmIntrinsics::_dcos:
|
||||
case vmIntrinsics::_dtan:
|
||||
#if defined(AMD64)
|
||||
case vmIntrinsics::_dsinh:
|
||||
case vmIntrinsics::_dtanh:
|
||||
case vmIntrinsics::_dcbrt:
|
||||
#endif
|
||||
|
|
|
@ -3296,6 +3296,7 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
|
|||
case vmIntrinsics::_dsin : // fall through
|
||||
case vmIntrinsics::_dcos : // fall through
|
||||
case vmIntrinsics::_dtan : // fall through
|
||||
case vmIntrinsics::_dsinh : // fall through
|
||||
case vmIntrinsics::_dtanh : // fall through
|
||||
case vmIntrinsics::_dcbrt : // fall through
|
||||
case vmIntrinsics::_dlog : // fall through
|
||||
|
|
|
@ -2865,6 +2865,7 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) {
|
|||
case vmIntrinsics::_dsqrt: // fall through
|
||||
case vmIntrinsics::_dsqrt_strict: // fall through
|
||||
case vmIntrinsics::_dtan: // fall through
|
||||
case vmIntrinsics::_dsinh: // fall through
|
||||
case vmIntrinsics::_dtanh: // fall through
|
||||
case vmIntrinsics::_dsin : // fall through
|
||||
case vmIntrinsics::_dcos : // fall through
|
||||
|
|
|
@ -362,6 +362,7 @@ const char* Runtime1::name_for_address(address entry) {
|
|||
FUNCTION_CASE(entry, StubRoutines::dsin());
|
||||
FUNCTION_CASE(entry, StubRoutines::dcos());
|
||||
FUNCTION_CASE(entry, StubRoutines::dtan());
|
||||
FUNCTION_CASE(entry, StubRoutines::dsinh());
|
||||
FUNCTION_CASE(entry, StubRoutines::dtanh());
|
||||
FUNCTION_CASE(entry, StubRoutines::dcbrt());
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/trainingData.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
|
||||
// All the classes that should be included in the AOT cache (in at least the "allocated" state)
|
||||
static GrowableArrayCHeap<Klass*, mtClassShared>* _all_cached_classes = nullptr;
|
||||
|
@ -47,7 +47,7 @@ static GrowableArrayCHeap<Klass*, mtClassShared>* _all_cached_classes = nullptr;
|
|||
static GrowableArrayCHeap<InstanceKlass*, mtClassShared>* _pending_aot_inited_classes = nullptr;
|
||||
|
||||
static const int TABLE_SIZE = 15889; // prime number
|
||||
using ClassesTable = ResourceHashtable<Klass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared>;
|
||||
using ClassesTable = HashTable<Klass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared>;
|
||||
static ClassesTable* _seen_classes; // all classes that have been seen by AOTArtifactFinder
|
||||
static ClassesTable* _aot_inited_classes; // all classes that need to be AOT-initialized.
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
class AOTLinkedClassTable;
|
||||
class InstanceKlass;
|
||||
|
@ -69,7 +69,7 @@ enum class AOTLinkedClassCategory : int;
|
|||
//
|
||||
class AOTClassLinker : AllStatic {
|
||||
static const int TABLE_SIZE = 15889; // prime number
|
||||
using ClassesTable = ResourceHashtable<InstanceKlass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared>;
|
||||
using ClassesTable = HashTable<InstanceKlass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared>;
|
||||
|
||||
// Classes loaded inside vmClasses::resolve_all()
|
||||
static ClassesTable* _vm_classes;
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "runtime/handles.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
class ConstantPool;
|
||||
class constantPoolHandle;
|
||||
|
@ -53,7 +53,7 @@ template <typename T> class GrowableArray;
|
|||
// if all of its supertypes are loaded from the CDS archive.
|
||||
class AOTConstantPoolResolver : AllStatic {
|
||||
static const int TABLE_SIZE = 15889; // prime number
|
||||
using ClassesTable = ResourceHashtable<InstanceKlass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared> ;
|
||||
using ClassesTable = HashTable<InstanceKlass*, bool, TABLE_SIZE, AnyObj::C_HEAP, mtClassShared> ;
|
||||
static ClassesTable* _processed_classes;
|
||||
|
||||
#ifdef ASSERT
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "runtime/fieldDescriptor.inline.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
|
||||
// Handling of java.lang.ref.Reference objects in the AOT cache
|
||||
// ============================================================
|
||||
|
@ -92,7 +92,7 @@
|
|||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
class KeepAliveObjectsTable : public ResourceHashtable<oop, bool,
|
||||
class KeepAliveObjectsTable : public HashTable<oop, bool,
|
||||
36137, // prime number
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#include "runtime/os.hpp"
|
||||
#include "utilities/bitMap.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/resizeableResourceHash.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
#include "utilities/resizableHashTable.hpp"
|
||||
|
||||
class ArchiveHeapInfo;
|
||||
class CHeapBitMap;
|
||||
|
@ -229,8 +229,8 @@ private:
|
|||
|
||||
SourceObjList _rw_src_objs; // objs to put in rw region
|
||||
SourceObjList _ro_src_objs; // objs to put in ro region
|
||||
ResizeableResourceHashtable<address, SourceObjInfo, AnyObj::C_HEAP, mtClassShared> _src_obj_table;
|
||||
ResizeableResourceHashtable<address, address, AnyObj::C_HEAP, mtClassShared> _buffered_to_src_table;
|
||||
ResizeableHashTable<address, SourceObjInfo, AnyObj::C_HEAP, mtClassShared> _src_obj_table;
|
||||
ResizeableHashTable<address, address, AnyObj::C_HEAP, mtClassShared> _buffered_to_src_table;
|
||||
GrowableArray<Klass*>* _klasses;
|
||||
GrowableArray<Symbol*>* _symbols;
|
||||
unsigned int _entropy_seed;
|
||||
|
|
|
@ -348,10 +348,10 @@ bool ArchiveHeapLoader::load_heap_region(FileMapInfo* mapinfo) {
|
|||
}
|
||||
|
||||
class VerifyLoadedHeapEmbeddedPointers: public BasicOopIterateClosure {
|
||||
ResourceHashtable<uintptr_t, bool>* _table;
|
||||
HashTable<uintptr_t, bool>* _table;
|
||||
|
||||
public:
|
||||
VerifyLoadedHeapEmbeddedPointers(ResourceHashtable<uintptr_t, bool>* table) : _table(table) {}
|
||||
VerifyLoadedHeapEmbeddedPointers(HashTable<uintptr_t, bool>* table) : _table(table) {}
|
||||
|
||||
virtual void do_oop(narrowOop* p) {
|
||||
// This should be called before the loaded region is modified, so all the embedded pointers
|
||||
|
@ -411,7 +411,7 @@ void ArchiveHeapLoader::verify_loaded_heap() {
|
|||
log_info(aot, heap)("Verify all oops and pointers in loaded heap");
|
||||
|
||||
ResourceMark rm;
|
||||
ResourceHashtable<uintptr_t, bool> table;
|
||||
HashTable<uintptr_t, bool> table;
|
||||
VerifyLoadedHeapEmbeddedPointers verifier(&table);
|
||||
HeapWord* bottom = (HeapWord*)_loaded_heap_bottom;
|
||||
HeapWord* top = (HeapWord*)_loaded_heap_top;
|
||||
|
|
|
@ -70,7 +70,7 @@ ArchiveHeapWriter::BufferOffsetToSourceObjectTable*
|
|||
ArchiveHeapWriter::_buffer_offset_to_source_obj_table = nullptr;
|
||||
|
||||
|
||||
typedef ResourceHashtable<
|
||||
typedef HashTable<
|
||||
size_t, // offset of a filler from ArchiveHeapWriter::buffer_bottom()
|
||||
size_t, // size of this filler (in bytes)
|
||||
127, // prime number
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include "utilities/bitMap.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
class MemRegion;
|
||||
|
||||
|
@ -152,7 +152,7 @@ private:
|
|||
};
|
||||
static GrowableArrayCHeap<HeapObjOrder, mtClassShared>* _source_objs_order;
|
||||
|
||||
typedef ResizeableResourceHashtable<size_t, oop,
|
||||
typedef ResizeableHashTable<size_t, oop,
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared> BufferOffsetToSourceObjectTable;
|
||||
static BufferOffsetToSourceObjectTable* _buffer_offset_to_source_obj_table;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "cds/heapShared.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
|
||||
class InstanceKlass;
|
||||
class Symbol;
|
||||
|
@ -47,7 +47,7 @@ class CDSHeapVerifier : public KlassClosure {
|
|||
Symbol* _name;
|
||||
};
|
||||
|
||||
ResourceHashtable<oop, StaticFieldInfo,
|
||||
HashTable<oop, StaticFieldInfo,
|
||||
15889, // prime number
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
// Overrides KlassClosure::do_klass()
|
||||
virtual void do_klass(Klass* k);
|
||||
|
||||
// For ResourceHashtable::iterate()
|
||||
// For HashTable::iterate()
|
||||
inline bool do_entry(oop& orig_obj, HeapShared::CachedOopInfo& value);
|
||||
|
||||
static void verify();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/istream.hpp"
|
||||
#include "utilities/resizeableResourceHash.hpp"
|
||||
#include "utilities/resizableHashTable.hpp"
|
||||
|
||||
class constantPoolHandle;
|
||||
class Thread;
|
||||
|
@ -77,7 +77,7 @@ public:
|
|||
|
||||
private:
|
||||
// Must be C_HEAP allocated -- we don't want nested resource allocations.
|
||||
typedef ResizeableResourceHashtable<int, InstanceKlass*,
|
||||
typedef ResizeableHashTable<int, InstanceKlass*,
|
||||
AnyObj::C_HEAP, mtClassShared> ID2KlassTable;
|
||||
|
||||
enum {
|
||||
|
|
|
@ -66,7 +66,7 @@ void ClassListWriter::write(const InstanceKlass* k, const ClassFileStream* cfs)
|
|||
write_to_stream(k, w.stream(), cfs);
|
||||
}
|
||||
|
||||
class ClassListWriter::IDTable : public ResourceHashtable<
|
||||
class ClassListWriter::IDTable : public HashTable<
|
||||
const InstanceKlass*, int,
|
||||
15889, // prime number
|
||||
AnyObj::C_HEAP> {};
|
||||
|
|
|
@ -240,7 +240,7 @@ inline unsigned DumpTimeSharedClassTable_hash(T* const& k) {
|
|||
}
|
||||
}
|
||||
|
||||
using DumpTimeSharedClassTableBaseType = ResourceHashtable<
|
||||
using DumpTimeSharedClassTableBaseType = HashTable<
|
||||
InstanceKlass*,
|
||||
DumpTimeClassInfo,
|
||||
15889, // prime number
|
||||
|
|
|
@ -367,7 +367,7 @@ bool HeapShared::archive_object(oop obj, oop referrer, KlassSubGraphInfo* subgra
|
|||
}
|
||||
}
|
||||
|
||||
class MetaspaceObjToOopHandleTable: public ResourceHashtable<MetaspaceObj*, OopHandle,
|
||||
class MetaspaceObjToOopHandleTable: public HashTable<MetaspaceObj*, OopHandle,
|
||||
36137, // prime number
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared> {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "oops/oopHandle.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
class DumpedInternedStrings;
|
||||
|
@ -202,14 +202,14 @@ public:
|
|||
private:
|
||||
static const int INITIAL_TABLE_SIZE = 15889; // prime number
|
||||
static const int MAX_TABLE_SIZE = 1000000;
|
||||
typedef ResizeableResourceHashtable<oop, CachedOopInfo,
|
||||
typedef ResizeableHashTable<oop, CachedOopInfo,
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
HeapShared::oop_hash> ArchivedObjectCache;
|
||||
static ArchivedObjectCache* _archived_object_cache;
|
||||
|
||||
class DumpTimeKlassSubGraphInfoTable
|
||||
: public ResourceHashtable<Klass*, KlassSubGraphInfo,
|
||||
: public HashTable<Klass*, KlassSubGraphInfo,
|
||||
137, // prime number
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
|
@ -264,7 +264,7 @@ private:
|
|||
// !UseCompressedOops only: used to relocate pointers to the archived objects
|
||||
static ptrdiff_t _runtime_delta;
|
||||
|
||||
typedef ResizeableResourceHashtable<oop, bool,
|
||||
typedef ResizeableHashTable<oop, bool,
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
HeapShared::oop_hash> SeenObjectsTable;
|
||||
|
@ -468,14 +468,14 @@ private:
|
|||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
class DumpedInternedStrings :
|
||||
public ResizeableResourceHashtable<oop, bool,
|
||||
public ResizeableHashTable<oop, bool,
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
HeapShared::string_oop_hash>
|
||||
{
|
||||
public:
|
||||
DumpedInternedStrings(unsigned size, unsigned max_size) :
|
||||
ResizeableResourceHashtable<oop, bool,
|
||||
ResizeableHashTable<oop, bool,
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared,
|
||||
HeapShared::string_oop_hash>(size, max_size) {}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "classfile/javaClasses.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
|
||||
// This file contains *legacy* optimization for lambdas before JEP 483. May be removed in the future.
|
||||
//
|
||||
|
@ -249,7 +249,7 @@ public:
|
|||
};
|
||||
|
||||
class DumpTimeLambdaProxyClassDictionary
|
||||
: public ResourceHashtable<LambdaProxyClassKey,
|
||||
: public HashTable<LambdaProxyClassKey,
|
||||
DumpTimeLambdaProxyClassInfo,
|
||||
137, // prime number
|
||||
AnyObj::C_HEAP,
|
||||
|
|
|
@ -97,9 +97,9 @@
|
|||
#include "utilities/align.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "utilities/defaultStream.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -178,7 +178,7 @@ class DumpClassListCLDClosure : public CLDClosure {
|
|||
static const int MAX_TABLE_SIZE = 61333;
|
||||
|
||||
fileStream *_stream;
|
||||
ResizeableResourceHashtable<InstanceKlass*, bool,
|
||||
ResizeableHashTable<InstanceKlass*, bool,
|
||||
AnyObj::C_HEAP, mtClassShared> _dumped_classes;
|
||||
|
||||
void dump(InstanceKlass* ik) {
|
||||
|
@ -245,7 +245,7 @@ static bool shared_base_too_high(char* specified_base, char* aligned_base, size_
|
|||
static char* compute_shared_base(size_t cds_max) {
|
||||
char* specified_base = (char*)SharedBaseAddress;
|
||||
size_t alignment = MetaspaceShared::core_region_alignment();
|
||||
if (UseCompressedClassPointers) {
|
||||
if (UseCompressedClassPointers && CompressedKlassPointers::needs_class_space()) {
|
||||
alignment = MAX2(alignment, Metaspace::reserve_alignment());
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "utilities/hashTable.hpp"
|
||||
|
||||
using RegeneratedObjTable = ResourceHashtable<address, address, 15889, AnyObj::C_HEAP, mtClassShared>;
|
||||
using RegeneratedObjTable = HashTable<address, address, 15889, AnyObj::C_HEAP, mtClassShared>;
|
||||
static RegeneratedObjTable* _regenerated_objs = nullptr; // InstanceKlass* and Method* orig_obj -> regen_obj
|
||||
static RegeneratedObjTable* _original_objs = nullptr; // InstanceKlass* and Method* regen_obj -> orig_obj
|
||||
static GrowableArrayCHeap<OopHandle, mtClassShared>* _regenerated_mirrors = nullptr;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue