Merge
This commit is contained in:
commit
9212c2d707
@ -231,3 +231,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
|
|||||||
0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107
|
0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107
|
||||||
9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108
|
9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108
|
||||||
91f47e8da5c60de58ed195e9b57f3bf192a18f83 jdk8-b109
|
91f47e8da5c60de58ed195e9b57f3bf192a18f83 jdk8-b109
|
||||||
|
4faa09c7fe555de086dd9048d3c5cc92317d6f45 jdk8-b110
|
||||||
|
@ -66,7 +66,7 @@ else
|
|||||||
else
|
else
|
||||||
# We are building multiple configurations.
|
# We are building multiple configurations.
|
||||||
# First, find out the valid targets
|
# First, find out the valid targets
|
||||||
# Run the makefile with an arbitraty SPEC using -p -q (quiet dry-run and dump rules) to find
|
# Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find
|
||||||
# available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
|
# available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
|
||||||
all_phony_targets=$(filter-out $(global_targets) bundles-only, $(strip $(shell \
|
all_phony_targets=$(filter-out $(global_targets) bundles-only, $(strip $(shell \
|
||||||
$(MAKE) -p -q -f common/makefiles/Main.gmk FRC SPEC=$(firstword $(SPEC)) | \
|
$(MAKE) -p -q -f common/makefiles/Main.gmk FRC SPEC=$(firstword $(SPEC)) | \
|
||||||
|
@ -1016,8 +1016,8 @@ with_cacerts_file
|
|||||||
enable_unlimited_crypto
|
enable_unlimited_crypto
|
||||||
with_milestone
|
with_milestone
|
||||||
with_update_version
|
with_update_version
|
||||||
with_build_number
|
|
||||||
with_user_release_suffix
|
with_user_release_suffix
|
||||||
|
with_build_number
|
||||||
with_boot_jdk
|
with_boot_jdk
|
||||||
with_boot_jdk_jvmargs
|
with_boot_jdk_jvmargs
|
||||||
with_add_source_root
|
with_add_source_root
|
||||||
@ -1755,10 +1755,10 @@ Optional Packages:
|
|||||||
--with-cacerts-file specify alternative cacerts file
|
--with-cacerts-file specify alternative cacerts file
|
||||||
--with-milestone Set milestone value for build [internal]
|
--with-milestone Set milestone value for build [internal]
|
||||||
--with-update-version Set update version value for build [b00]
|
--with-update-version Set update version value for build [b00]
|
||||||
--with-build-number Set build number value for build [b00]
|
|
||||||
--with-user-release-suffix
|
--with-user-release-suffix
|
||||||
Add a custom string to the version string if build
|
Add a custom string to the version string if build
|
||||||
number isn't set.[username_builddateb00]
|
number isn't set.[username_builddateb00]
|
||||||
|
--with-build-number Set build number value for build [b00]
|
||||||
--with-boot-jdk path to Boot JDK (used to bootstrap build) [probed]
|
--with-boot-jdk path to Boot JDK (used to bootstrap build) [probed]
|
||||||
--with-boot-jdk-jvmargs specify JVM arguments to be passed to all
|
--with-boot-jdk-jvmargs specify JVM arguments to be passed to all
|
||||||
invocations of the Boot JDK, overriding the default
|
invocations of the Boot JDK, overriding the default
|
||||||
@ -3818,7 +3818,7 @@ fi
|
|||||||
#CUSTOM_AUTOCONF_INCLUDE
|
#CUSTOM_AUTOCONF_INCLUDE
|
||||||
|
|
||||||
# Do not change or remove the following line, it is needed for consistency checks:
|
# Do not change or remove the following line, it is needed for consistency checks:
|
||||||
DATE_WHEN_GENERATED=1379504921
|
DATE_WHEN_GENERATED=1381162713
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -10935,7 +10935,7 @@ BUILD_HEADLESS="BUILD_HEADLESS:=true"
|
|||||||
|
|
||||||
if test "x$SUPPORT_HEADFUL" = xyes; then
|
if test "x$SUPPORT_HEADFUL" = xyes; then
|
||||||
# We are building both headful and headless.
|
# We are building both headful and headless.
|
||||||
headful_msg="inlude support for both headful and headless"
|
headful_msg="include support for both headful and headless"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$SUPPORT_HEADFUL" = xno; then
|
if test "x$SUPPORT_HEADFUL" = xno; then
|
||||||
@ -11048,6 +11048,18 @@ elif test "x$with_update_version" != x; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --with-user-release-suffix was given.
|
||||||
|
if test "${with_user_release_suffix+set}" = set; then :
|
||||||
|
withval=$with_user_release_suffix;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$with_user_release_suffix" = xyes; then
|
||||||
|
as_fn_error $? "Release suffix must have a value" "$LINENO" 5
|
||||||
|
elif test "x$with_user_release_suffix" != x; then
|
||||||
|
USER_RELEASE_SUFFIX="$with_user_release_suffix"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-build-number was given.
|
# Check whether --with-build-number was given.
|
||||||
if test "${with_build_number+set}" = set; then :
|
if test "${with_build_number+set}" = set; then :
|
||||||
withval=$with_build_number;
|
withval=$with_build_number;
|
||||||
@ -11058,27 +11070,16 @@ if test "x$with_build_number" = xyes; then
|
|||||||
elif test "x$with_build_number" != x; then
|
elif test "x$with_build_number" != x; then
|
||||||
JDK_BUILD_NUMBER="$with_build_number"
|
JDK_BUILD_NUMBER="$with_build_number"
|
||||||
fi
|
fi
|
||||||
|
# Define default USER_RELEASE_SUFFIX if BUILD_NUMBER and USER_RELEASE_SUFFIX are not set
|
||||||
if test "x$JDK_BUILD_NUMBER" = x; then
|
if test "x$JDK_BUILD_NUMBER" = x; then
|
||||||
JDK_BUILD_NUMBER=b00
|
JDK_BUILD_NUMBER=b00
|
||||||
fi
|
if test "x$USER_RELEASE_SUFFIX" = x; then
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-user-release-suffix was given.
|
|
||||||
if test "${with_user_release_suffix+set}" = set; then :
|
|
||||||
withval=$with_user_release_suffix;
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x$with_user_release_suffix" = xyes; then
|
|
||||||
as_fn_error $? "Release suffix must have a value" "$LINENO" 5
|
|
||||||
elif test "x$with_user_release_suffix" != x; then
|
|
||||||
USER_RELEASE_SUFFIX="$with_user_release_suffix"
|
|
||||||
else
|
|
||||||
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
|
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
|
||||||
# Avoid [:alnum:] since it depends on the locale.
|
# Avoid [:alnum:] since it depends on the locale.
|
||||||
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
|
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
|
||||||
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Now set the JDK version, milestone, build number etc.
|
# Now set the JDK version, milestone, build number etc.
|
||||||
|
|
||||||
@ -11095,6 +11096,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
COPYRIGHT_YEAR=`date +'%Y'`
|
COPYRIGHT_YEAR=`date +'%Y'`
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ BUILD_HEADLESS="BUILD_HEADLESS:=true"
|
|||||||
|
|
||||||
if test "x$SUPPORT_HEADFUL" = xyes; then
|
if test "x$SUPPORT_HEADFUL" = xyes; then
|
||||||
# We are building both headful and headless.
|
# We are building both headful and headless.
|
||||||
headful_msg="inlude support for both headful and headless"
|
headful_msg="include support for both headful and headless"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$SUPPORT_HEADFUL" = xno; then
|
if test "x$SUPPORT_HEADFUL" = xno; then
|
||||||
@ -426,6 +426,14 @@ elif test "x$with_update_version" != x; then
|
|||||||
JDK_UPDATE_VERSION="$with_update_version"
|
JDK_UPDATE_VERSION="$with_update_version"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_WITH(user-release-suffix, [AS_HELP_STRING([--with-user-release-suffix],
|
||||||
|
[Add a custom string to the version string if build number isn't set.@<:@username_builddateb00@:>@])])
|
||||||
|
if test "x$with_user_release_suffix" = xyes; then
|
||||||
|
AC_MSG_ERROR([Release suffix must have a value])
|
||||||
|
elif test "x$with_user_release_suffix" != x; then
|
||||||
|
USER_RELEASE_SUFFIX="$with_user_release_suffix"
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_WITH(build-number, [AS_HELP_STRING([--with-build-number],
|
AC_ARG_WITH(build-number, [AS_HELP_STRING([--with-build-number],
|
||||||
[Set build number value for build @<:@b00@:>@])])
|
[Set build number value for build @<:@b00@:>@])])
|
||||||
if test "x$with_build_number" = xyes; then
|
if test "x$with_build_number" = xyes; then
|
||||||
@ -433,25 +441,19 @@ if test "x$with_build_number" = xyes; then
|
|||||||
elif test "x$with_build_number" != x; then
|
elif test "x$with_build_number" != x; then
|
||||||
JDK_BUILD_NUMBER="$with_build_number"
|
JDK_BUILD_NUMBER="$with_build_number"
|
||||||
fi
|
fi
|
||||||
|
# Define default USER_RELEASE_SUFFIX if BUILD_NUMBER and USER_RELEASE_SUFFIX are not set
|
||||||
if test "x$JDK_BUILD_NUMBER" = x; then
|
if test "x$JDK_BUILD_NUMBER" = x; then
|
||||||
JDK_BUILD_NUMBER=b00
|
JDK_BUILD_NUMBER=b00
|
||||||
fi
|
if test "x$USER_RELEASE_SUFFIX" = x; then
|
||||||
|
|
||||||
AC_ARG_WITH(user-release-suffix, [AS_HELP_STRING([--with-user-release-suffix],
|
|
||||||
[Add a custom string to the version string if build number isn't set.@<:@username_builddateb00@:>@])])
|
|
||||||
if test "x$with_user_release_suffix" = xyes; then
|
|
||||||
AC_MSG_ERROR([Release suffix must have a value])
|
|
||||||
elif test "x$with_user_release_suffix" != x; then
|
|
||||||
USER_RELEASE_SUFFIX="$with_user_release_suffix"
|
|
||||||
else
|
|
||||||
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
|
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
|
||||||
# Avoid [:alnum:] since it depends on the locale.
|
# Avoid [:alnum:] since it depends on the locale.
|
||||||
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
|
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
|
||||||
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||||
fi
|
fi
|
||||||
AC_SUBST(USER_RELEASE_SUFFIX)
|
fi
|
||||||
|
|
||||||
# Now set the JDK version, milestone, build number etc.
|
# Now set the JDK version, milestone, build number etc.
|
||||||
|
AC_SUBST(USER_RELEASE_SUFFIX)
|
||||||
AC_SUBST(JDK_MAJOR_VERSION)
|
AC_SUBST(JDK_MAJOR_VERSION)
|
||||||
AC_SUBST(JDK_MINOR_VERSION)
|
AC_SUBST(JDK_MINOR_VERSION)
|
||||||
AC_SUBST(JDK_MICRO_VERSION)
|
AC_SUBST(JDK_MICRO_VERSION)
|
||||||
|
@ -161,6 +161,7 @@ JDK_RC_PLATFORM_NAME:=@JDK_RC_PLATFORM_NAME@
|
|||||||
COMPANY_NAME:=@COMPANY_NAME@
|
COMPANY_NAME:=@COMPANY_NAME@
|
||||||
MACOSX_BUNDLE_NAME_BASE=@MACOSX_BUNDLE_NAME_BASE@
|
MACOSX_BUNDLE_NAME_BASE=@MACOSX_BUNDLE_NAME_BASE@
|
||||||
MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@
|
MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@
|
||||||
|
USER_RELEASE_SUFFIX=@USER_RELEASE_SUFFIX@
|
||||||
|
|
||||||
# Different version strings generated from the above information.
|
# Different version strings generated from the above information.
|
||||||
JDK_VERSION:=@JDK_VERSION@
|
JDK_VERSION:=@JDK_VERSION@
|
||||||
@ -173,8 +174,8 @@ ifeq ($(MILESTONE),)
|
|||||||
else
|
else
|
||||||
RELEASE=$(JDK_VERSION)-$(MILESTONE)$(BUILD_VARIANT_RELEASE)
|
RELEASE=$(JDK_VERSION)-$(MILESTONE)$(BUILD_VARIANT_RELEASE)
|
||||||
endif
|
endif
|
||||||
ifeq ($(JDK_BUILD_NUMBER),b00)
|
|
||||||
USER_RELEASE_SUFFIX=@USER_RELEASE_SUFFIX@
|
ifneq ($(USER_RELEASE_SUFFIX),)
|
||||||
FULL_VERSION=$(RELEASE)-$(USER_RELEASE_SUFFIX)-$(JDK_BUILD_NUMBER)
|
FULL_VERSION=$(RELEASE)-$(USER_RELEASE_SUFFIX)-$(JDK_BUILD_NUMBER)
|
||||||
else
|
else
|
||||||
FULL_VERSION=$(RELEASE)-$(JDK_BUILD_NUMBER)
|
FULL_VERSION=$(RELEASE)-$(JDK_BUILD_NUMBER)
|
||||||
|
@ -159,7 +159,7 @@ define SetupArchive
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Utility macros, to make the shell script receipt somewhat easier to dechipher.
|
# Utility macros, to make the shell script receipt somewhat easier to decipher.
|
||||||
|
|
||||||
# The capture contents macro finds all files (matching the patterns, typically
|
# The capture contents macro finds all files (matching the patterns, typically
|
||||||
# .class and .prp) that are newer than the jar-file, ie the new content to be put into the jar.
|
# .class and .prp) that are newer than the jar-file, ie the new content to be put into the jar.
|
||||||
@ -520,7 +520,7 @@ define SetupJavaCompilation
|
|||||||
# Using plain javac to batch compile everything.
|
# Using plain javac to batch compile everything.
|
||||||
$1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_BIN)/_the.batch
|
$1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_BIN)/_the.batch
|
||||||
|
|
||||||
# When buliding in batch, put headers in a temp dir to filter out those that actually
|
# When building in batch, put headers in a temp dir to filter out those that actually
|
||||||
# changed before copying them to the real header dir.
|
# changed before copying them to the real header dir.
|
||||||
ifneq (,$$($1_HEADERS))
|
ifneq (,$$($1_HEADERS))
|
||||||
$1_HEADERS_ARG := -h $$($1_HEADERS).tmp
|
$1_HEADERS_ARG := -h $$($1_HEADERS).tmp
|
||||||
|
@ -231,3 +231,4 @@ d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
|
|||||||
23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107
|
23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107
|
||||||
a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108
|
a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108
|
||||||
428428cf5e06163322144cfb5367e1faa86acf20 jdk8-b109
|
428428cf5e06163322144cfb5367e1faa86acf20 jdk8-b109
|
||||||
|
3d2b7ce93c5c2e3db748f29c3d29620a8b3b748a jdk8-b110
|
||||||
|
@ -381,3 +381,5 @@ a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50
|
|||||||
566db1b0e6efca31f181456e54c8911d0192410d hs25-b51
|
566db1b0e6efca31f181456e54c8911d0192410d hs25-b51
|
||||||
c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109
|
c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109
|
||||||
58043478c26d4e8bf48700acea5f97aba8b417d4 hs25-b52
|
58043478c26d4e8bf48700acea5f97aba8b417d4 hs25-b52
|
||||||
|
6209b0ed51c086d4127bac0e086c8f326d1764d7 jdk8-b110
|
||||||
|
562a3d356de67670b4172b82aca2d30743449e04 hs25-b53
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_in
|
|||||||
(JNIEnv *env, jclass cls) {
|
(JNIEnv *env, jclass cls) {
|
||||||
jclass listClass;
|
jclass listClass;
|
||||||
|
|
||||||
if (init_libproc(getenv("LIBSAPROC_DEBUG")) != true) {
|
if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
|
||||||
THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
|
THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <sys/ptrace.h>
|
#include <sys/ptrace.h>
|
||||||
#include "libproc_impl.h"
|
#include "libproc_impl.h"
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "salibelf.h"
|
#include "salibelf.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
extern void print_debug(const char*,...);
|
extern void print_debug(const char*,...);
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note)
|
|||||||
|
|
||||||
unsigned char *bytes
|
unsigned char *bytes
|
||||||
= (unsigned char*)(note+1) + note->n_namesz;
|
= (unsigned char*)(note+1) + note->n_namesz;
|
||||||
unsigned char *filename
|
char *filename
|
||||||
= (build_id_to_debug_filename (note->n_descsz, bytes));
|
= (build_id_to_debug_filename (note->n_descsz, bytes));
|
||||||
|
|
||||||
fd = pathmap_open(filename);
|
fd = pathmap_open(filename);
|
||||||
|
@ -134,15 +134,13 @@ public class VM {
|
|||||||
private String type;
|
private String type;
|
||||||
private String name;
|
private String name;
|
||||||
private Address addr;
|
private Address addr;
|
||||||
private String kind;
|
private int flags;
|
||||||
private int origin;
|
|
||||||
|
|
||||||
private Flag(String type, String name, Address addr, String kind, int origin) {
|
private Flag(String type, String name, Address addr, int flags) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.addr = addr;
|
this.addr = addr;
|
||||||
this.kind = kind;
|
this.flags = flags;
|
||||||
this.origin = origin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
@ -157,12 +155,8 @@ public class VM {
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKind() {
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOrigin() {
|
public int getOrigin() {
|
||||||
return origin;
|
return flags & 0xF; // XXX can we get the mask bits from somewhere?
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBool() {
|
public boolean isBool() {
|
||||||
@ -173,8 +167,7 @@ public class VM {
|
|||||||
if (Assert.ASSERTS_ENABLED) {
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
Assert.that(isBool(), "not a bool flag!");
|
Assert.that(isBool(), "not a bool flag!");
|
||||||
}
|
}
|
||||||
return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned())
|
return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned()) != 0;
|
||||||
!= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isIntx() {
|
public boolean isIntx() {
|
||||||
@ -843,11 +836,10 @@ public class VM {
|
|||||||
|
|
||||||
Address flagAddr = flagType.getAddressField("flags").getValue();
|
Address flagAddr = flagType.getAddressField("flags").getValue();
|
||||||
|
|
||||||
AddressField typeFld = flagType.getAddressField("type");
|
AddressField typeFld = flagType.getAddressField("_type");
|
||||||
AddressField nameFld = flagType.getAddressField("name");
|
AddressField nameFld = flagType.getAddressField("_name");
|
||||||
AddressField addrFld = flagType.getAddressField("addr");
|
AddressField addrFld = flagType.getAddressField("_addr");
|
||||||
AddressField kindFld = flagType.getAddressField("kind");
|
CIntField flagsFld = new CIntField(flagType.getCIntegerField("_flags"), 0);
|
||||||
CIntField originFld = new CIntField(flagType.getCIntegerField("origin"), 0);
|
|
||||||
|
|
||||||
long flagSize = flagType.getSize(); // sizeof(Flag)
|
long flagSize = flagType.getSize(); // sizeof(Flag)
|
||||||
|
|
||||||
@ -856,9 +848,8 @@ public class VM {
|
|||||||
String type = CStringUtilities.getString(typeFld.getValue(flagAddr));
|
String type = CStringUtilities.getString(typeFld.getValue(flagAddr));
|
||||||
String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
|
String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
|
||||||
Address addr = addrFld.getValue(flagAddr);
|
Address addr = addrFld.getValue(flagAddr);
|
||||||
String kind = CStringUtilities.getString(kindFld.getValue(flagAddr));
|
int flags = (int)flagsFld.getValue(flagAddr);
|
||||||
int origin = (int)originFld.getValue(flagAddr);
|
commandLineFlags[f] = new Flag(type, name, addr, flags);
|
||||||
commandLineFlags[f] = new Flag(type, name, addr, kind, origin);
|
|
||||||
flagAddr = flagAddr.addOffsetTo(flagSize);
|
flagAddr = flagAddr.addOffsetTo(flagSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -59,5 +59,5 @@ CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
|
|||||||
MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
|
MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
|
||||||
|
|
||||||
VERSION = fastdebug
|
VERSION = fastdebug
|
||||||
SYSDEFS += -DASSERT
|
SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -247,7 +247,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(USE_CLANG), true)
|
ifeq ($(USE_CLANG), true)
|
||||||
# However we need to clean the code up before we can unrestrictedly enable this option with Clang
|
# However we need to clean the code up before we can unrestrictedly enable this option with Clang
|
||||||
WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
|
WARNINGS_ARE_ERRORS += -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
|
||||||
WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-compare
|
WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-compare
|
||||||
# Not yet supported by clang in Xcode 4.6.2
|
# Not yet supported by clang in Xcode 4.6.2
|
||||||
# WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
|
# WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
|
||||||
@ -262,7 +262,7 @@ ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \&
|
|||||||
# conversions which might affect the values. Only enable it in earlier versions.
|
# conversions which might affect the values. Only enable it in earlier versions.
|
||||||
WARNING_FLAGS = -Wunused-function
|
WARNING_FLAGS = -Wunused-function
|
||||||
ifeq ($(USE_CLANG),)
|
ifeq ($(USE_CLANG),)
|
||||||
WARNINGS_FLAGS += -Wconversion
|
WARNING_FLAGS += -Wconversion
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
|||||||
|
|
||||||
HS_MAJOR_VER=25
|
HS_MAJOR_VER=25
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=52
|
HS_BUILD_NUMBER=53
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=8
|
JDK_MINOR_VER=8
|
||||||
|
@ -59,5 +59,5 @@ CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
|
|||||||
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
|
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
|
||||||
|
|
||||||
VERSION = optimized
|
VERSION = optimized
|
||||||
SYSDEFS += -DASSERT
|
SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
|
||||||
PICFLAGS = DEFAULT
|
PICFLAGS = DEFAULT
|
||||||
|
@ -208,7 +208,7 @@ WARNINGS_ARE_ERRORS = -Werror
|
|||||||
|
|
||||||
ifeq ($(USE_CLANG), true)
|
ifeq ($(USE_CLANG), true)
|
||||||
# However we need to clean the code up before we can unrestrictedly enable this option with Clang
|
# However we need to clean the code up before we can unrestrictedly enable this option with Clang
|
||||||
WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
|
WARNINGS_ARE_ERRORS += -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
|
||||||
WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare
|
WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare
|
||||||
WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
|
WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
|
||||||
WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
|
WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -38,7 +38,7 @@ default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA
|
|||||||
!include ../local.make
|
!include ../local.make
|
||||||
!include compile.make
|
!include compile.make
|
||||||
|
|
||||||
CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION)
|
CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION) /D "CHECK_UNHANDLED_OOPS"
|
||||||
|
|
||||||
!include $(WorkSpace)/make/windows/makefiles/vm.make
|
!include $(WorkSpace)/make/windows/makefiles/vm.make
|
||||||
!include local.make
|
!include local.make
|
||||||
|
@ -764,7 +764,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result)
|
|||||||
#ifdef CC_INTERP
|
#ifdef CC_INTERP
|
||||||
*oop_result = istate->_oop_temp;
|
*oop_result = istate->_oop_temp;
|
||||||
#else
|
#else
|
||||||
oop obj = (oop) at(interpreter_frame_oop_temp_offset);
|
oop obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
|
||||||
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
|
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
|
||||||
*oop_result = obj;
|
*oop_result = obj;
|
||||||
#endif // CC_INTERP
|
#endif // CC_INTERP
|
||||||
@ -788,7 +788,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result)
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
case T_ARRAY: {
|
case T_ARRAY: {
|
||||||
oop obj = (oop)*tos_addr;
|
oop obj = cast_to_oop(*tos_addr);
|
||||||
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
|
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
|
||||||
*oop_result = obj;
|
*oop_result = obj;
|
||||||
break;
|
break;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -121,6 +121,7 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Registe
|
|||||||
|
|
||||||
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp,
|
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp,
|
||||||
bool for_compiler_entry) {
|
bool for_compiler_entry) {
|
||||||
|
Label L_no_such_method;
|
||||||
assert(method == G5_method, "interpreter calling convention");
|
assert(method == G5_method, "interpreter calling convention");
|
||||||
assert_different_registers(method, target, temp);
|
assert_different_registers(method, target, temp);
|
||||||
|
|
||||||
@ -133,6 +134,9 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth
|
|||||||
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
|
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
|
||||||
__ ld(interp_only, temp);
|
__ ld(interp_only, temp);
|
||||||
__ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code);
|
__ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code);
|
||||||
|
// Null method test is replicated below in compiled case,
|
||||||
|
// it might be able to address across the verify_thread()
|
||||||
|
__ br_null_short(G5_method, Assembler::pn, L_no_such_method);
|
||||||
__ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), target);
|
__ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), target);
|
||||||
__ jmp(target, 0);
|
__ jmp(target, 0);
|
||||||
__ delayed()->nop();
|
__ delayed()->nop();
|
||||||
@ -141,11 +145,19 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth
|
|||||||
// it doesn't matter, since this is interpreter code.
|
// it doesn't matter, since this is interpreter code.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compiled case, either static or fall-through from runtime conditional
|
||||||
|
__ br_null_short(G5_method, Assembler::pn, L_no_such_method);
|
||||||
|
|
||||||
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
|
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
|
||||||
Method::from_interpreted_offset();
|
Method::from_interpreted_offset();
|
||||||
__ ld_ptr(G5_method, in_bytes(entry_offset), target);
|
__ ld_ptr(G5_method, in_bytes(entry_offset), target);
|
||||||
__ jmp(target, 0);
|
__ jmp(target, 0);
|
||||||
__ delayed()->nop();
|
__ delayed()->nop();
|
||||||
|
|
||||||
|
__ bind(L_no_such_method);
|
||||||
|
AddressLiteral ame(StubRoutines::throw_AbstractMethodError_entry());
|
||||||
|
__ jump_to(ame, temp);
|
||||||
|
__ delayed()->nop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
|
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -358,7 +358,7 @@ void NativeMovConstReg::set_data(intptr_t x) {
|
|||||||
oop_Relocation *r = iter.oop_reloc();
|
oop_Relocation *r = iter.oop_reloc();
|
||||||
if (oop_addr == NULL) {
|
if (oop_addr == NULL) {
|
||||||
oop_addr = r->oop_addr();
|
oop_addr = r->oop_addr();
|
||||||
*oop_addr = (oop)x;
|
*oop_addr = cast_to_oop(x);
|
||||||
} else {
|
} else {
|
||||||
assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
|
assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
|
||||||
}
|
}
|
||||||
@ -478,7 +478,7 @@ void NativeMovConstRegPatching::set_data(int x) {
|
|||||||
oop_Relocation *r = iter.oop_reloc();
|
oop_Relocation *r = iter.oop_reloc();
|
||||||
if (oop_addr == NULL) {
|
if (oop_addr == NULL) {
|
||||||
oop_addr = r->oop_addr();
|
oop_addr = r->oop_addr();
|
||||||
*oop_addr = (oop)x;
|
*oop_addr = cast_to_oop(x);
|
||||||
} else {
|
} else {
|
||||||
assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
|
assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
|
||||||
}
|
}
|
||||||
|
@ -2018,6 +2018,15 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
|
|||||||
return L7_REGP_mask();
|
return L7_REGP_mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||||
|
return G1_REGI_mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||||
|
return INT_FLAGS_mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
@ -4245,12 +4254,16 @@ operand cmpOp() %{
|
|||||||
greater_equal(0xB);
|
greater_equal(0xB);
|
||||||
less_equal(0x2);
|
less_equal(0x2);
|
||||||
greater(0xA);
|
greater(0xA);
|
||||||
|
overflow(0x7);
|
||||||
|
no_overflow(0xF);
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Comparison Op, unsigned
|
// Comparison Op, unsigned
|
||||||
operand cmpOpU() %{
|
operand cmpOpU() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
|
||||||
|
n->as_Bool()->_test._test != BoolTest::no_overflow);
|
||||||
|
|
||||||
format %{ "u" %}
|
format %{ "u" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
@ -4260,12 +4273,16 @@ operand cmpOpU() %{
|
|||||||
greater_equal(0xD);
|
greater_equal(0xD);
|
||||||
less_equal(0x4);
|
less_equal(0x4);
|
||||||
greater(0xC);
|
greater(0xC);
|
||||||
|
overflow(0x7);
|
||||||
|
no_overflow(0xF);
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Comparison Op, pointer (same as unsigned)
|
// Comparison Op, pointer (same as unsigned)
|
||||||
operand cmpOpP() %{
|
operand cmpOpP() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
|
||||||
|
n->as_Bool()->_test._test != BoolTest::no_overflow);
|
||||||
|
|
||||||
format %{ "p" %}
|
format %{ "p" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
@ -4275,12 +4292,16 @@ operand cmpOpP() %{
|
|||||||
greater_equal(0xD);
|
greater_equal(0xD);
|
||||||
less_equal(0x4);
|
less_equal(0x4);
|
||||||
greater(0xC);
|
greater(0xC);
|
||||||
|
overflow(0x7);
|
||||||
|
no_overflow(0xF);
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Comparison Op, branch-register encoding
|
// Comparison Op, branch-register encoding
|
||||||
operand cmpOp_reg() %{
|
operand cmpOp_reg() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
|
||||||
|
n->as_Bool()->_test._test != BoolTest::no_overflow);
|
||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
@ -4290,12 +4311,16 @@ operand cmpOp_reg() %{
|
|||||||
greater_equal(0x7);
|
greater_equal(0x7);
|
||||||
less_equal (0x2);
|
less_equal (0x2);
|
||||||
greater (0x6);
|
greater (0x6);
|
||||||
|
overflow(0x7); // not supported
|
||||||
|
no_overflow(0xF); // not supported
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Comparison Code, floating, unordered same as less
|
// Comparison Code, floating, unordered same as less
|
||||||
operand cmpOpF() %{
|
operand cmpOpF() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
|
||||||
|
n->as_Bool()->_test._test != BoolTest::no_overflow);
|
||||||
|
|
||||||
format %{ "fl" %}
|
format %{ "fl" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
@ -4305,12 +4330,17 @@ operand cmpOpF() %{
|
|||||||
greater_equal(0xB);
|
greater_equal(0xB);
|
||||||
less_equal(0xE);
|
less_equal(0xE);
|
||||||
greater(0x6);
|
greater(0x6);
|
||||||
|
|
||||||
|
overflow(0x7); // not supported
|
||||||
|
no_overflow(0xF); // not supported
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Used by long compare
|
// Used by long compare
|
||||||
operand cmpOp_commute() %{
|
operand cmpOp_commute() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
|
||||||
|
n->as_Bool()->_test._test != BoolTest::no_overflow);
|
||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
@ -4320,6 +4350,8 @@ operand cmpOp_commute() %{
|
|||||||
greater_equal(0x2);
|
greater_equal(0x2);
|
||||||
less_equal(0xB);
|
less_equal(0xB);
|
||||||
greater(0x3);
|
greater(0x3);
|
||||||
|
overflow(0x7);
|
||||||
|
no_overflow(0xF);
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -4769,7 +4769,7 @@ void Assembler::adcq(Register dst, Address src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::adcq(Register dst, Register src) {
|
void Assembler::adcq(Register dst, Register src) {
|
||||||
(int) prefixq_and_encode(dst->encoding(), src->encoding());
|
(void) prefixq_and_encode(dst->encoding(), src->encoding());
|
||||||
emit_arith(0x13, 0xC0, dst, src);
|
emit_arith(0x13, 0xC0, dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4824,7 +4824,7 @@ void Assembler::andq(Register dst, Address src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::andq(Register dst, Register src) {
|
void Assembler::andq(Register dst, Register src) {
|
||||||
(int) prefixq_and_encode(dst->encoding(), src->encoding());
|
(void) prefixq_and_encode(dst->encoding(), src->encoding());
|
||||||
emit_arith(0x23, 0xC0, dst, src);
|
emit_arith(0x23, 0xC0, dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +639,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result)
|
|||||||
#ifdef CC_INTERP
|
#ifdef CC_INTERP
|
||||||
obj = istate->_oop_temp;
|
obj = istate->_oop_temp;
|
||||||
#else
|
#else
|
||||||
obj = (oop) at(interpreter_frame_oop_temp_offset);
|
obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
|
||||||
#endif // CC_INTERP
|
#endif // CC_INTERP
|
||||||
} else {
|
} else {
|
||||||
oop* obj_p = (oop*)tos_addr;
|
oop* obj_p = (oop*)tos_addr;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -114,6 +114,11 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Registe
|
|||||||
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
|
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
|
||||||
bool for_compiler_entry) {
|
bool for_compiler_entry) {
|
||||||
assert(method == rbx, "interpreter calling convention");
|
assert(method == rbx, "interpreter calling convention");
|
||||||
|
|
||||||
|
Label L_no_such_method;
|
||||||
|
__ testptr(rbx, rbx);
|
||||||
|
__ jcc(Assembler::zero, L_no_such_method);
|
||||||
|
|
||||||
__ verify_method_ptr(method);
|
__ verify_method_ptr(method);
|
||||||
|
|
||||||
if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
|
if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
|
||||||
@ -138,6 +143,9 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth
|
|||||||
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
|
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
|
||||||
Method::from_interpreted_offset();
|
Method::from_interpreted_offset();
|
||||||
__ jmp(Address(method, entry_offset));
|
__ jmp(Address(method, entry_offset));
|
||||||
|
|
||||||
|
__ bind(L_no_such_method);
|
||||||
|
__ jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
|
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
|
||||||
@ -475,7 +483,7 @@ void trace_method_handle_stub(const char* adaptername,
|
|||||||
const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
|
const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
|
||||||
tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT,
|
tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT,
|
||||||
adaptername, mh_reg_name,
|
adaptername, mh_reg_name,
|
||||||
mh, entry_sp);
|
(void *)mh, entry_sp);
|
||||||
|
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
tty->print_cr("Registers:");
|
tty->print_cr("Registers:");
|
||||||
|
@ -351,7 +351,7 @@ void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec,
|
|||||||
int format) {
|
int format) {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
|
if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
|
||||||
assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
assert(cast_to_oop(d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||||
@ -1534,6 +1534,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
|
|||||||
return EBP_REG_mask();
|
return EBP_REG_mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||||
|
return EAX_REG_mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||||
|
return INT_FLAGS_mask();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if the high 32 bits of the value is known to be zero.
|
// Returns true if the high 32 bits of the value is known to be zero.
|
||||||
bool is_operand_hi32_zero(Node* n) {
|
bool is_operand_hi32_zero(Node* n) {
|
||||||
int opc = n->Opcode();
|
int opc = n->Opcode();
|
||||||
@ -4922,6 +4930,8 @@ operand cmpOp() %{
|
|||||||
greater_equal(0xD, "ge");
|
greater_equal(0xD, "ge");
|
||||||
less_equal(0xE, "le");
|
less_equal(0xE, "le");
|
||||||
greater(0xF, "g");
|
greater(0xF, "g");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4939,6 +4949,8 @@ operand cmpOpU() %{
|
|||||||
greater_equal(0x3, "nb");
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6, "be");
|
less_equal(0x6, "be");
|
||||||
greater(0x7, "nbe");
|
greater(0x7, "nbe");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4957,6 +4969,8 @@ operand cmpOpUCF() %{
|
|||||||
greater_equal(0x3, "nb");
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6, "be");
|
less_equal(0x6, "be");
|
||||||
greater(0x7, "nbe");
|
greater(0x7, "nbe");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4974,6 +4988,8 @@ operand cmpOpUCF2() %{
|
|||||||
greater_equal(0x3, "nb");
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6, "be");
|
less_equal(0x6, "be");
|
||||||
greater(0x7, "nbe");
|
greater(0x7, "nbe");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4981,6 +4997,8 @@ operand cmpOpUCF2() %{
|
|||||||
operand cmpOp_fcmov() %{
|
operand cmpOp_fcmov() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
|
||||||
|
predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
|
||||||
|
n->as_Bool()->_test._test != BoolTest::no_overflow);
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
equal (0x0C8);
|
equal (0x0C8);
|
||||||
@ -4989,6 +5007,8 @@ operand cmpOp_fcmov() %{
|
|||||||
greater_equal(0x1C0);
|
greater_equal(0x1C0);
|
||||||
less_equal (0x0D0);
|
less_equal (0x0D0);
|
||||||
greater (0x1D0);
|
greater (0x1D0);
|
||||||
|
overflow(0x0, "o"); // not really supported by the instruction
|
||||||
|
no_overflow(0x1, "no"); // not really supported by the instruction
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5004,6 +5024,8 @@ operand cmpOp_commute() %{
|
|||||||
greater_equal(0xE, "le");
|
greater_equal(0xE, "le");
|
||||||
less_equal(0xD, "ge");
|
less_equal(0xD, "ge");
|
||||||
greater(0xC, "l");
|
greater(0xC, "l");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7496,6 +7518,31 @@ instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
|
|||||||
|
|
||||||
//----------Arithmetic Instructions--------------------------------------------
|
//----------Arithmetic Instructions--------------------------------------------
|
||||||
//----------Addition Instructions----------------------------------------------
|
//----------Addition Instructions----------------------------------------------
|
||||||
|
|
||||||
|
instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "ADD $dst, $src\t# addExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addl($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "ADD $dst, $src\t# addExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addl($dst$$Register, $src$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
// Integer Addition Instructions
|
// Integer Addition Instructions
|
||||||
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
||||||
match(Set dst (AddI dst src));
|
match(Set dst (AddI dst src));
|
||||||
|
@ -529,7 +529,7 @@ void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, in
|
|||||||
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
||||||
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
|
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
|
||||||
assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
|
assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
|
||||||
assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||||
@ -556,7 +556,7 @@ void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec
|
|||||||
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
||||||
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
|
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
|
||||||
assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
|
assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
|
||||||
assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
|
assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()),
|
||||||
"cannot embed scavengable oops in code");
|
"cannot embed scavengable oops in code");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1649,6 +1649,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
|
|||||||
return PTR_RBP_REG_mask();
|
return PTR_RBP_REG_mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||||
|
return INT_RAX_REG_mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||||
|
return INT_FLAGS_mask();
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
//----------ENCODING BLOCK-----------------------------------------------------
|
//----------ENCODING BLOCK-----------------------------------------------------
|
||||||
@ -4133,6 +4141,8 @@ operand cmpOp()
|
|||||||
greater_equal(0xD, "ge");
|
greater_equal(0xD, "ge");
|
||||||
less_equal(0xE, "le");
|
less_equal(0xE, "le");
|
||||||
greater(0xF, "g");
|
greater(0xF, "g");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4151,6 +4161,8 @@ operand cmpOpU()
|
|||||||
greater_equal(0x3, "nb");
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6, "be");
|
less_equal(0x6, "be");
|
||||||
greater(0x7, "nbe");
|
greater(0x7, "nbe");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4170,6 +4182,8 @@ operand cmpOpUCF() %{
|
|||||||
greater_equal(0x3, "nb");
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6, "be");
|
less_equal(0x6, "be");
|
||||||
greater(0x7, "nbe");
|
greater(0x7, "nbe");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -4187,6 +4201,8 @@ operand cmpOpUCF2() %{
|
|||||||
greater_equal(0x3, "nb");
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6, "be");
|
less_equal(0x6, "be");
|
||||||
greater(0x7, "nbe");
|
greater(0x7, "nbe");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6922,6 +6938,30 @@ instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
|
|||||||
//----------Arithmetic Instructions--------------------------------------------
|
//----------Arithmetic Instructions--------------------------------------------
|
||||||
//----------Addition Instructions----------------------------------------------
|
//----------Addition Instructions----------------------------------------------
|
||||||
|
|
||||||
|
instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "addl $dst, $src\t# addExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addl($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "addl $dst, $src\t# addExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addl($dst$$Register, $src$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
match(Set dst (AddI dst src));
|
match(Set dst (AddI dst src));
|
||||||
|
@ -4839,6 +4839,10 @@ jint os::init_2(void)
|
|||||||
|
|
||||||
Linux::capture_initial_stack(JavaThread::stack_size_at_create());
|
Linux::capture_initial_stack(JavaThread::stack_size_at_create());
|
||||||
|
|
||||||
|
#if defined(IA32)
|
||||||
|
workaround_expand_exec_shield_cs_limit();
|
||||||
|
#endif
|
||||||
|
|
||||||
Linux::libpthread_init();
|
Linux::libpthread_init();
|
||||||
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
||||||
tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
|
tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
|
||||||
|
@ -876,3 +876,46 @@ void os::verify_stack_alignment() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit
|
||||||
|
* updates (JDK-8023956).
|
||||||
|
*/
|
||||||
|
void os::workaround_expand_exec_shield_cs_limit() {
|
||||||
|
#if defined(IA32)
|
||||||
|
size_t page_size = os::vm_page_size();
|
||||||
|
/*
|
||||||
|
* Take the highest VA the OS will give us and exec
|
||||||
|
*
|
||||||
|
* Although using -(pagesz) as mmap hint works on newer kernel as you would
|
||||||
|
* think, older variants affected by this work-around don't (search forward only).
|
||||||
|
*
|
||||||
|
* On the affected distributions, we understand the memory layout to be:
|
||||||
|
*
|
||||||
|
* TASK_LIMIT= 3G, main stack base close to TASK_LIMT.
|
||||||
|
*
|
||||||
|
* A few pages south main stack will do it.
|
||||||
|
*
|
||||||
|
* If we are embedded in an app other than launcher (initial != main stack),
|
||||||
|
* we don't have much control or understanding of the address space, just let it slide.
|
||||||
|
*/
|
||||||
|
char* hint = (char*) (Linux::initial_thread_stack_bottom() -
|
||||||
|
((StackYellowPages + StackRedPages + 1) * page_size));
|
||||||
|
char* codebuf = os::reserve_memory(page_size, hint);
|
||||||
|
if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
|
||||||
|
return; // No matter, we tried, best effort.
|
||||||
|
}
|
||||||
|
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
||||||
|
tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some code to exec: the 'ret' instruction
|
||||||
|
codebuf[0] = 0xC3;
|
||||||
|
|
||||||
|
// Call the code in the codebuf
|
||||||
|
__asm__ volatile("call *%0" : : "r"(codebuf));
|
||||||
|
|
||||||
|
// keep the page mapped so CS limit isn't reduced.
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -36,4 +36,17 @@
|
|||||||
// Note: Currently only used in 64 bit Windows implementations
|
// Note: Currently only used in 64 bit Windows implementations
|
||||||
static bool register_code_area(char *low, char *high) { return true; }
|
static bool register_code_area(char *low, char *high) { return true; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield"
|
||||||
|
* (IA32 only).
|
||||||
|
*
|
||||||
|
* Map and execute at a high VA to prevent CS lazy updates race with SMP MM
|
||||||
|
* invalidation.Further code generation by the JVM will no longer cause CS limit
|
||||||
|
* updates.
|
||||||
|
*
|
||||||
|
* Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04.
|
||||||
|
* @see JDK-8023956
|
||||||
|
*/
|
||||||
|
static void workaround_expand_exec_shield_cs_limit();
|
||||||
|
|
||||||
#endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP
|
#endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP
|
||||||
|
@ -3395,12 +3395,16 @@ Interface *ADLParser::cond_interface_parse(void) {
|
|||||||
char *greater_equal;
|
char *greater_equal;
|
||||||
char *less_equal;
|
char *less_equal;
|
||||||
char *greater;
|
char *greater;
|
||||||
|
char *overflow;
|
||||||
|
char *no_overflow;
|
||||||
const char *equal_format = "eq";
|
const char *equal_format = "eq";
|
||||||
const char *not_equal_format = "ne";
|
const char *not_equal_format = "ne";
|
||||||
const char *less_format = "lt";
|
const char *less_format = "lt";
|
||||||
const char *greater_equal_format = "ge";
|
const char *greater_equal_format = "ge";
|
||||||
const char *less_equal_format = "le";
|
const char *less_equal_format = "le";
|
||||||
const char *greater_format = "gt";
|
const char *greater_format = "gt";
|
||||||
|
const char *overflow_format = "o";
|
||||||
|
const char *no_overflow_format = "no";
|
||||||
|
|
||||||
if (_curchar != '%') {
|
if (_curchar != '%') {
|
||||||
parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
|
parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
|
||||||
@ -3437,6 +3441,12 @@ Interface *ADLParser::cond_interface_parse(void) {
|
|||||||
else if ( strcmp(field,"greater") == 0 ) {
|
else if ( strcmp(field,"greater") == 0 ) {
|
||||||
greater = interface_field_parse(&greater_format);
|
greater = interface_field_parse(&greater_format);
|
||||||
}
|
}
|
||||||
|
else if ( strcmp(field,"overflow") == 0 ) {
|
||||||
|
overflow = interface_field_parse(&overflow_format);
|
||||||
|
}
|
||||||
|
else if ( strcmp(field,"no_overflow") == 0 ) {
|
||||||
|
no_overflow = interface_field_parse(&no_overflow_format);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
|
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -3455,7 +3465,9 @@ Interface *ADLParser::cond_interface_parse(void) {
|
|||||||
less, less_format,
|
less, less_format,
|
||||||
greater_equal, greater_equal_format,
|
greater_equal, greater_equal_format,
|
||||||
less_equal, less_equal_format,
|
less_equal, less_equal_format,
|
||||||
greater, greater_format);
|
greater, greater_format,
|
||||||
|
overflow, overflow_format,
|
||||||
|
no_overflow, no_overflow_format);
|
||||||
return inter;
|
return inter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,6 +1192,8 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
|
|||||||
|| strcmp(idealName,"CmpF") == 0
|
|| strcmp(idealName,"CmpF") == 0
|
||||||
|| strcmp(idealName,"FastLock") == 0
|
|| strcmp(idealName,"FastLock") == 0
|
||||||
|| strcmp(idealName,"FastUnlock") == 0
|
|| strcmp(idealName,"FastUnlock") == 0
|
||||||
|
|| strcmp(idealName,"AddExactI") == 0
|
||||||
|
|| strcmp(idealName,"FlagsProj") == 0
|
||||||
|| strcmp(idealName,"Bool") == 0
|
|| strcmp(idealName,"Bool") == 0
|
||||||
|| strcmp(idealName,"Binary") == 0 ) {
|
|| strcmp(idealName,"Binary") == 0 ) {
|
||||||
// Removed ConI from the must_clone list. CPUs that cannot use
|
// Removed ConI from the must_clone list. CPUs that cannot use
|
||||||
|
@ -2757,14 +2757,18 @@ CondInterface::CondInterface(const char* equal, const char* equal_format
|
|||||||
const char* less, const char* less_format,
|
const char* less, const char* less_format,
|
||||||
const char* greater_equal, const char* greater_equal_format,
|
const char* greater_equal, const char* greater_equal_format,
|
||||||
const char* less_equal, const char* less_equal_format,
|
const char* less_equal, const char* less_equal_format,
|
||||||
const char* greater, const char* greater_format)
|
const char* greater, const char* greater_format,
|
||||||
|
const char* overflow, const char* overflow_format,
|
||||||
|
const char* no_overflow, const char* no_overflow_format)
|
||||||
: Interface("COND_INTER"),
|
: Interface("COND_INTER"),
|
||||||
_equal(equal), _equal_format(equal_format),
|
_equal(equal), _equal_format(equal_format),
|
||||||
_not_equal(not_equal), _not_equal_format(not_equal_format),
|
_not_equal(not_equal), _not_equal_format(not_equal_format),
|
||||||
_less(less), _less_format(less_format),
|
_less(less), _less_format(less_format),
|
||||||
_greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
|
_greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
|
||||||
_less_equal(less_equal), _less_equal_format(less_equal_format),
|
_less_equal(less_equal), _less_equal_format(less_equal_format),
|
||||||
_greater(greater), _greater_format(greater_format) {
|
_greater(greater), _greater_format(greater_format),
|
||||||
|
_overflow(overflow), _overflow_format(overflow_format),
|
||||||
|
_no_overflow(no_overflow), _no_overflow_format(no_overflow_format) {
|
||||||
}
|
}
|
||||||
CondInterface::~CondInterface() {
|
CondInterface::~CondInterface() {
|
||||||
// not owner of any character arrays
|
// not owner of any character arrays
|
||||||
@ -2783,6 +2787,8 @@ void CondInterface::output(FILE *fp) {
|
|||||||
if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal);
|
if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal);
|
||||||
if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal);
|
if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal);
|
||||||
if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater);
|
if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater);
|
||||||
|
if ( _overflow != NULL ) fprintf(fp," overflow == %s\n", _overflow);
|
||||||
|
if ( _no_overflow != NULL ) fprintf(fp," no_overflow == %s\n", _no_overflow);
|
||||||
// fprintf(fp,"\n");
|
// fprintf(fp,"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,12 +798,16 @@ public:
|
|||||||
const char *_greater_equal;
|
const char *_greater_equal;
|
||||||
const char *_less_equal;
|
const char *_less_equal;
|
||||||
const char *_greater;
|
const char *_greater;
|
||||||
|
const char *_overflow;
|
||||||
|
const char *_no_overflow;
|
||||||
const char *_equal_format;
|
const char *_equal_format;
|
||||||
const char *_not_equal_format;
|
const char *_not_equal_format;
|
||||||
const char *_less_format;
|
const char *_less_format;
|
||||||
const char *_greater_equal_format;
|
const char *_greater_equal_format;
|
||||||
const char *_less_equal_format;
|
const char *_less_equal_format;
|
||||||
const char *_greater_format;
|
const char *_greater_format;
|
||||||
|
const char *_overflow_format;
|
||||||
|
const char *_no_overflow_format;
|
||||||
|
|
||||||
// Public Methods
|
// Public Methods
|
||||||
CondInterface(const char* equal, const char* equal_format,
|
CondInterface(const char* equal, const char* equal_format,
|
||||||
@ -811,7 +815,9 @@ public:
|
|||||||
const char* less, const char* less_format,
|
const char* less, const char* less_format,
|
||||||
const char* greater_equal, const char* greater_equal_format,
|
const char* greater_equal, const char* greater_equal_format,
|
||||||
const char* less_equal, const char* less_equal_format,
|
const char* less_equal, const char* less_equal_format,
|
||||||
const char* greater, const char* greater_format);
|
const char* greater, const char* greater_format,
|
||||||
|
const char* overflow, const char* overflow_format,
|
||||||
|
const char* no_overflow, const char* no_overflow_format);
|
||||||
~CondInterface();
|
~CondInterface();
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
@ -388,6 +388,8 @@ static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
|
|||||||
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
|
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
|
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
|
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
|
||||||
|
fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print(\"%s\");\n",i,cond->_overflow_format);
|
||||||
|
fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print(\"%s\");\n",i,cond->_no_overflow_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output code that dumps constant values, increment "i" if type is constant
|
// Output code that dumps constant values, increment "i" if type is constant
|
||||||
@ -1208,6 +1210,8 @@ void ArchDesc::declareClasses(FILE *fp) {
|
|||||||
fprintf(fp," case BoolTest::ne : return not_equal();\n");
|
fprintf(fp," case BoolTest::ne : return not_equal();\n");
|
||||||
fprintf(fp," case BoolTest::le : return less_equal();\n");
|
fprintf(fp," case BoolTest::le : return less_equal();\n");
|
||||||
fprintf(fp," case BoolTest::ge : return greater_equal();\n");
|
fprintf(fp," case BoolTest::ge : return greater_equal();\n");
|
||||||
|
fprintf(fp," case BoolTest::overflow : return overflow();\n");
|
||||||
|
fprintf(fp," case BoolTest::no_overflow: return no_overflow();\n");
|
||||||
fprintf(fp," default : ShouldNotReachHere(); return 0;\n");
|
fprintf(fp," default : ShouldNotReachHere(); return 0;\n");
|
||||||
fprintf(fp," }\n");
|
fprintf(fp," }\n");
|
||||||
fprintf(fp," };\n");
|
fprintf(fp," };\n");
|
||||||
@ -1373,6 +1377,14 @@ void ArchDesc::declareClasses(FILE *fp) {
|
|||||||
if( greater != NULL ) {
|
if( greater != NULL ) {
|
||||||
define_oper_interface(fp, *oper, _globalNames, "greater", greater);
|
define_oper_interface(fp, *oper, _globalNames, "greater", greater);
|
||||||
}
|
}
|
||||||
|
const char *overflow = cInterface->_overflow;
|
||||||
|
if( overflow != NULL ) {
|
||||||
|
define_oper_interface(fp, *oper, _globalNames, "overflow", overflow);
|
||||||
|
}
|
||||||
|
const char *no_overflow = cInterface->_no_overflow;
|
||||||
|
if( no_overflow != NULL ) {
|
||||||
|
define_oper_interface(fp, *oper, _globalNames, "no_overflow", no_overflow);
|
||||||
|
}
|
||||||
} // end Conditional Interface
|
} // end Conditional Interface
|
||||||
// Check if it is a Constant Interface
|
// Check if it is a Constant Interface
|
||||||
else if (oper->_interface->is_ConstInterface() != NULL ) {
|
else if (oper->_interface->is_ConstInterface() != NULL ) {
|
||||||
|
@ -1019,7 +1019,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
|||||||
n_copy->set_data((intx) (load_klass()));
|
n_copy->set_data((intx) (load_klass()));
|
||||||
} else {
|
} else {
|
||||||
assert(mirror() != NULL, "klass not set");
|
assert(mirror() != NULL, "klass not set");
|
||||||
n_copy->set_data((intx) (mirror()));
|
n_copy->set_data(cast_from_oop<intx>(mirror()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TracePatching) {
|
if (TracePatching) {
|
||||||
@ -1031,7 +1031,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
|||||||
assert(n_copy->data() == 0 ||
|
assert(n_copy->data() == 0 ||
|
||||||
n_copy->data() == (intptr_t)Universe::non_oop_word(),
|
n_copy->data() == (intptr_t)Universe::non_oop_word(),
|
||||||
"illegal init value");
|
"illegal init value");
|
||||||
n_copy->set_data((intx) (appendix()));
|
n_copy->set_data(cast_from_oop<intx>(appendix()));
|
||||||
|
|
||||||
if (TracePatching) {
|
if (TracePatching) {
|
||||||
Disassembler::decode(copy_buff, copy_buff + *byte_count, tty);
|
Disassembler::decode(copy_buff, copy_buff + *byte_count, tty);
|
||||||
@ -1078,14 +1078,17 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
|||||||
// replace instructions
|
// replace instructions
|
||||||
// first replace the tail, then the call
|
// first replace the tail, then the call
|
||||||
#ifdef ARM
|
#ifdef ARM
|
||||||
if(load_klass_or_mirror_patch_id && !VM_Version::supports_movw()) {
|
if((load_klass_or_mirror_patch_id ||
|
||||||
|
stub_id == Runtime1::load_appendix_patching_id) &&
|
||||||
|
!VM_Version::supports_movw()) {
|
||||||
nmethod* nm = CodeCache::find_nmethod(instr_pc);
|
nmethod* nm = CodeCache::find_nmethod(instr_pc);
|
||||||
address addr = NULL;
|
address addr = NULL;
|
||||||
assert(nm != NULL, "invalid nmethod_pc");
|
assert(nm != NULL, "invalid nmethod_pc");
|
||||||
RelocIterator mds(nm, copy_buff, copy_buff + 1);
|
RelocIterator mds(nm, copy_buff, copy_buff + 1);
|
||||||
while (mds.next()) {
|
while (mds.next()) {
|
||||||
if (mds.type() == relocInfo::oop_type) {
|
if (mds.type() == relocInfo::oop_type) {
|
||||||
assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id");
|
assert(stub_id == Runtime1::load_mirror_patching_id ||
|
||||||
|
stub_id == Runtime1::load_appendix_patching_id, "wrong stub id");
|
||||||
oop_Relocation* r = mds.oop_reloc();
|
oop_Relocation* r = mds.oop_reloc();
|
||||||
addr = (address)r->oop_addr();
|
addr = (address)r->oop_addr();
|
||||||
break;
|
break;
|
||||||
|
@ -1787,7 +1787,7 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d
|
|||||||
if (_location != _in_method) break; // only allow for methods
|
if (_location != _in_method) break; // only allow for methods
|
||||||
if (!privileged) break; // only allow in privileged code
|
if (!privileged) break; // only allow in privileged code
|
||||||
return _method_LambdaForm_Hidden;
|
return _method_LambdaForm_Hidden;
|
||||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature):
|
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature):
|
||||||
if (_location != _in_field) break; // only allow for fields
|
if (_location != _in_field) break; // only allow for fields
|
||||||
if (!privileged) break; // only allow in privileged code
|
if (!privileged) break; // only allow in privileged code
|
||||||
return _field_Stable;
|
return _field_Stable;
|
||||||
@ -2545,7 +2545,9 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
|
|||||||
if (method->is_final()) {
|
if (method->is_final()) {
|
||||||
*has_final_method = true;
|
*has_final_method = true;
|
||||||
}
|
}
|
||||||
if (is_interface && !method->is_abstract() && !method->is_static()) {
|
if (is_interface && !(*has_default_methods)
|
||||||
|
&& !method->is_abstract() && !method->is_static()
|
||||||
|
&& !method->is_private()) {
|
||||||
// default method
|
// default method
|
||||||
*has_default_methods = true;
|
*has_default_methods = true;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ void ClassLoaderData::add_class(Klass* k) {
|
|||||||
k,
|
k,
|
||||||
k->external_name(),
|
k->external_name(),
|
||||||
k->class_loader_data(),
|
k->class_loader_data(),
|
||||||
k->class_loader(),
|
(void *)k->class_loader(),
|
||||||
loader_name());
|
loader_name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ void ClassLoaderData::unload() {
|
|||||||
if (TraceClassLoaderData) {
|
if (TraceClassLoaderData) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this);
|
tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this);
|
||||||
tty->print(" for instance "PTR_FORMAT" of %s", class_loader(),
|
tty->print(" for instance "PTR_FORMAT" of %s", (void *)class_loader(),
|
||||||
loader_name());
|
loader_name());
|
||||||
if (is_anonymous()) {
|
if (is_anonymous()) {
|
||||||
tty->print(" for anonymous class "PTR_FORMAT " ", _klasses);
|
tty->print(" for anonymous class "PTR_FORMAT " ", _klasses);
|
||||||
@ -458,7 +458,7 @@ const char* ClassLoaderData::loader_name() {
|
|||||||
void ClassLoaderData::dump(outputStream * const out) {
|
void ClassLoaderData::dump(outputStream * const out) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {",
|
out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {",
|
||||||
this, class_loader(),
|
this, (void *)class_loader(),
|
||||||
class_loader() != NULL ? class_loader()->klass() : NULL, loader_name());
|
class_loader() != NULL ? class_loader()->klass() : NULL, loader_name());
|
||||||
if (claimed()) out->print(" claimed ");
|
if (claimed()) out->print(" claimed ");
|
||||||
if (is_unloading()) out->print(" unloading ");
|
if (is_unloading()) out->print(" unloading ");
|
||||||
@ -553,7 +553,7 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRA
|
|||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
tty->print("[ClassLoaderData: ");
|
tty->print("[ClassLoaderData: ");
|
||||||
tty->print("create class loader data "PTR_FORMAT, cld);
|
tty->print("create class loader data "PTR_FORMAT, cld);
|
||||||
tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(),
|
tty->print(" for instance "PTR_FORMAT" of %s", (void *)cld->class_loader(),
|
||||||
cld->loader_name());
|
cld->loader_name());
|
||||||
tty->print_cr("]");
|
tty->print_cr("]");
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,7 @@ class MethodFamily : public ResourceObj {
|
|||||||
|
|
||||||
Method* _selected_target; // Filled in later, if a unique target exists
|
Method* _selected_target; // Filled in later, if a unique target exists
|
||||||
Symbol* _exception_message; // If no unique target is found
|
Symbol* _exception_message; // If no unique target is found
|
||||||
|
Symbol* _exception_name; // If no unique target is found
|
||||||
|
|
||||||
bool contains_method(Method* method) {
|
bool contains_method(Method* method) {
|
||||||
int* lookup = _member_index.get(method);
|
int* lookup = _member_index.get(method);
|
||||||
@ -350,7 +351,7 @@ class MethodFamily : public ResourceObj {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
MethodFamily()
|
MethodFamily()
|
||||||
: _selected_target(NULL), _exception_message(NULL) {}
|
: _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {}
|
||||||
|
|
||||||
void set_target_if_empty(Method* m) {
|
void set_target_if_empty(Method* m) {
|
||||||
if (_selected_target == NULL && !m->is_overpass()) {
|
if (_selected_target == NULL && !m->is_overpass()) {
|
||||||
@ -383,6 +384,7 @@ class MethodFamily : public ResourceObj {
|
|||||||
|
|
||||||
Method* get_selected_target() { return _selected_target; }
|
Method* get_selected_target() { return _selected_target; }
|
||||||
Symbol* get_exception_message() { return _exception_message; }
|
Symbol* get_exception_message() { return _exception_message; }
|
||||||
|
Symbol* get_exception_name() { return _exception_name; }
|
||||||
|
|
||||||
// Either sets the target or the exception error message
|
// Either sets the target or the exception error message
|
||||||
void determine_target(InstanceKlass* root, TRAPS) {
|
void determine_target(InstanceKlass* root, TRAPS) {
|
||||||
@ -400,15 +402,18 @@ class MethodFamily : public ResourceObj {
|
|||||||
|
|
||||||
if (qualified_methods.length() == 0) {
|
if (qualified_methods.length() == 0) {
|
||||||
_exception_message = generate_no_defaults_message(CHECK);
|
_exception_message = generate_no_defaults_message(CHECK);
|
||||||
|
_exception_name = vmSymbols::java_lang_AbstractMethodError();
|
||||||
} else if (qualified_methods.length() == 1) {
|
} else if (qualified_methods.length() == 1) {
|
||||||
Method* method = qualified_methods.at(0);
|
Method* method = qualified_methods.at(0);
|
||||||
if (method->is_abstract()) {
|
if (method->is_abstract()) {
|
||||||
_exception_message = generate_abstract_method_message(method, CHECK);
|
_exception_message = generate_abstract_method_message(method, CHECK);
|
||||||
|
_exception_name = vmSymbols::java_lang_AbstractMethodError();
|
||||||
} else {
|
} else {
|
||||||
_selected_target = qualified_methods.at(0);
|
_selected_target = qualified_methods.at(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_exception_message = generate_conflicts_message(&qualified_methods,CHECK);
|
_exception_message = generate_conflicts_message(&qualified_methods,CHECK);
|
||||||
|
_exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((has_target() ^ throws_exception()) == 1,
|
assert((has_target() ^ throws_exception()) == 1,
|
||||||
@ -459,8 +464,9 @@ class MethodFamily : public ResourceObj {
|
|||||||
|
|
||||||
void print_exception(outputStream* str, int indent) {
|
void print_exception(outputStream* str, int indent) {
|
||||||
assert(throws_exception(), "Should be called otherwise");
|
assert(throws_exception(), "Should be called otherwise");
|
||||||
|
assert(_exception_name != NULL, "exception_name should be set");
|
||||||
streamIndentor si(str, indent * 2);
|
streamIndentor si(str, indent * 2);
|
||||||
str->indent().print_cr("%s", _exception_message->as_C_string());
|
str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
|
||||||
}
|
}
|
||||||
#endif // ndef PRODUCT
|
#endif // ndef PRODUCT
|
||||||
};
|
};
|
||||||
@ -670,7 +676,10 @@ class FindMethodsByErasedSig : public HierarchyVisitor<FindMethodsByErasedSig> {
|
|||||||
InstanceKlass* iklass = current_class();
|
InstanceKlass* iklass = current_class();
|
||||||
|
|
||||||
Method* m = iklass->find_method(_method_name, _method_signature);
|
Method* m = iklass->find_method(_method_name, _method_signature);
|
||||||
if (m != NULL) {
|
// private interface methods are not candidates for default methods
|
||||||
|
// invokespecial to private interface methods doesn't use default method logic
|
||||||
|
// future: take access controls into account for superclass methods
|
||||||
|
if (m != NULL && (!iklass->is_interface() || m->is_public())) {
|
||||||
if (_family == NULL) {
|
if (_family == NULL) {
|
||||||
_family = new StatefulMethodFamily();
|
_family = new StatefulMethodFamily();
|
||||||
}
|
}
|
||||||
@ -782,202 +791,9 @@ void DefaultMethods::generate_default_methods(
|
|||||||
#endif // ndef PRODUCT
|
#endif // ndef PRODUCT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface inheritance rules were used to find a unique default method
|
|
||||||
* candidate for the resolved class. This
|
|
||||||
* method is only viable if it would also be in the set of default method
|
|
||||||
* candidates if we ran a full analysis on the current class.
|
|
||||||
*
|
|
||||||
* The only reason that the method would not be in the set of candidates for
|
|
||||||
* the current class is if that there's another matching method
|
|
||||||
* which is "more specific" than the found method -- i.e., one could find a
|
|
||||||
* path in the interface hierarchy in which the matching method appears
|
|
||||||
* before we get to '_target'.
|
|
||||||
*
|
|
||||||
* In order to determine this, we examine all of the implemented
|
|
||||||
* interfaces. If we find path that leads to the '_target' interface, then
|
|
||||||
* we examine that path to see if there are any methods that would shadow
|
|
||||||
* the selected method along that path.
|
|
||||||
*/
|
|
||||||
class ShadowChecker : public HierarchyVisitor<ShadowChecker> {
|
|
||||||
protected:
|
|
||||||
Thread* THREAD;
|
|
||||||
|
|
||||||
InstanceKlass* _target;
|
|
||||||
|
|
||||||
Symbol* _method_name;
|
|
||||||
InstanceKlass* _method_holder;
|
|
||||||
bool _found_shadow;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
#ifdef ASSERT
|
||||||
|
|
||||||
ShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder,
|
|
||||||
InstanceKlass* target)
|
|
||||||
: THREAD(thread), _method_name(name), _method_holder(holder),
|
|
||||||
_target(target), _found_shadow(false) {}
|
|
||||||
|
|
||||||
void* new_node_data(InstanceKlass* cls) { return NULL; }
|
|
||||||
void free_node_data(void* data) { return; }
|
|
||||||
|
|
||||||
bool visit() {
|
|
||||||
InstanceKlass* ik = current_class();
|
|
||||||
if (ik == _target && current_depth() == 1) {
|
|
||||||
return false; // This was the specified super -- no need to search it
|
|
||||||
}
|
|
||||||
if (ik == _method_holder || ik == _target) {
|
|
||||||
// We found a path that should be examined to see if it shadows _method
|
|
||||||
if (path_has_shadow()) {
|
|
||||||
_found_shadow = true;
|
|
||||||
cancel_iteration();
|
|
||||||
}
|
|
||||||
return false; // no need to continue up hierarchy
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool path_has_shadow() = 0;
|
|
||||||
bool found_shadow() { return _found_shadow; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Used for Invokespecial.
|
|
||||||
// Invokespecial is allowed to invoke a concrete interface method
|
|
||||||
// and can be used to disambuiguate among qualified candidates,
|
|
||||||
// which are methods in immediate superinterfaces,
|
|
||||||
// but may not be used to invoke a candidate that would be shadowed
|
|
||||||
// from the perspective of the caller.
|
|
||||||
// Invokespecial is also used in the overpass generation today
|
|
||||||
// We re-run the shadowchecker because we can't distinguish this case,
|
|
||||||
// but it should return the same answer, since the overpass target
|
|
||||||
// is now the invokespecial caller.
|
|
||||||
class ErasedShadowChecker : public ShadowChecker {
|
|
||||||
private:
|
|
||||||
bool path_has_shadow() {
|
|
||||||
|
|
||||||
for (int i = current_depth() - 1; i > 0; --i) {
|
|
||||||
InstanceKlass* ik = class_at_depth(i);
|
|
||||||
|
|
||||||
if (ik->is_interface()) {
|
|
||||||
int end;
|
|
||||||
int start = ik->find_method_by_name(_method_name, &end);
|
|
||||||
if (start != -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
|
|
||||||
ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder,
|
|
||||||
InstanceKlass* target)
|
|
||||||
: ShadowChecker(thread, name, holder, target) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find the unique qualified candidate from the perspective of the super_class
|
|
||||||
// which is the resolved_klass, which must be an immediate superinterface
|
|
||||||
// of klass
|
|
||||||
Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) {
|
|
||||||
|
|
||||||
FindMethodsByErasedSig visitor(method_name, sig);
|
|
||||||
visitor.run(super_class); // find candidates from resolved_klass
|
|
||||||
|
|
||||||
MethodFamily* family;
|
|
||||||
visitor.get_discovered_family(&family);
|
|
||||||
|
|
||||||
if (family != NULL) {
|
|
||||||
family->determine_target(current_class, CHECK_NULL); // get target from current_class
|
|
||||||
|
|
||||||
if (family->has_target()) {
|
|
||||||
Method* target = family->get_selected_target();
|
|
||||||
InstanceKlass* holder = InstanceKlass::cast(target->method_holder());
|
|
||||||
|
|
||||||
// Verify that the identified method is valid from the context of
|
|
||||||
// the current class, which is the caller class for invokespecial
|
|
||||||
// link resolution, i.e. ensure there it is not shadowed.
|
|
||||||
// You can use invokespecial to disambiguate interface methods, but
|
|
||||||
// you can not use it to skip over an interface method that would shadow it.
|
|
||||||
ErasedShadowChecker checker(THREAD, target->name(), holder, super_class);
|
|
||||||
checker.run(current_class);
|
|
||||||
|
|
||||||
if (checker.found_shadow()) {
|
|
||||||
#ifndef PRODUCT
|
|
||||||
if (TraceDefaultMethods) {
|
|
||||||
tty->print_cr(" Only candidate found was shadowed.");
|
|
||||||
}
|
|
||||||
#endif // ndef PRODUCT
|
|
||||||
THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
|
|
||||||
"Accessible default method not found", NULL);
|
|
||||||
} else {
|
|
||||||
#ifndef PRODUCT
|
|
||||||
if (TraceDefaultMethods) {
|
|
||||||
family->print_sig_on(tty, target->signature(), 1);
|
|
||||||
}
|
|
||||||
#endif // ndef PRODUCT
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(family->throws_exception(), "must have target or throw");
|
|
||||||
THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
|
|
||||||
family->get_exception_message()->as_C_string(), NULL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no method found
|
|
||||||
ResourceMark rm(THREAD);
|
|
||||||
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(),
|
|
||||||
Method::name_and_sig_as_C_string(current_class,
|
|
||||||
method_name, sig), NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This is called during linktime when we find an invokespecial call that
|
|
||||||
// refers to a direct superinterface. It indicates that we should find the
|
|
||||||
// default method in the hierarchy of that superinterface, and if that method
|
|
||||||
// would have been a candidate from the point of view of 'this' class, then we
|
|
||||||
// return that method.
|
|
||||||
// This logic assumes that the super is a direct superclass of the caller
|
|
||||||
Method* DefaultMethods::find_super_default(
|
|
||||||
Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) {
|
|
||||||
|
|
||||||
ResourceMark rm(THREAD);
|
|
||||||
|
|
||||||
assert(cls != NULL && super != NULL, "Need real classes");
|
|
||||||
|
|
||||||
InstanceKlass* current_class = InstanceKlass::cast(cls);
|
|
||||||
InstanceKlass* super_class = InstanceKlass::cast(super);
|
|
||||||
|
|
||||||
// Keep entire hierarchy alive for the duration of the computation
|
|
||||||
KeepAliveRegistrar keepAlive(THREAD);
|
|
||||||
KeepAliveVisitor loadKeepAlive(&keepAlive);
|
|
||||||
loadKeepAlive.run(current_class); // get hierarchy from current class
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
if (TraceDefaultMethods) {
|
|
||||||
tty->print_cr("Finding super default method %s.%s%s from %s",
|
|
||||||
super_class->name()->as_C_string(),
|
|
||||||
method_name->as_C_string(), sig->as_C_string(),
|
|
||||||
current_class->name()->as_C_string());
|
|
||||||
}
|
|
||||||
#endif // ndef PRODUCT
|
|
||||||
|
|
||||||
assert(super_class->is_interface(), "only call for default methods");
|
|
||||||
|
|
||||||
Method* target = NULL;
|
|
||||||
target = find_erased_super_default(current_class, super_class,
|
|
||||||
method_name, sig, CHECK_NULL);
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
if (target != NULL) {
|
|
||||||
if (TraceDefaultMethods) {
|
|
||||||
tty->print(" Returning ");
|
|
||||||
print_method(tty, target, true);
|
|
||||||
tty->print_cr("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // ndef PRODUCT
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
// Return true is broad type is a covariant return of narrow type
|
// Return true is broad type is a covariant return of narrow type
|
||||||
static bool covariant_return_type(BasicType narrow, BasicType broad) {
|
static bool covariant_return_type(BasicType narrow, BasicType broad) {
|
||||||
if (narrow == broad) {
|
if (narrow == broad) {
|
||||||
@ -988,7 +804,7 @@ static bool covariant_return_type(BasicType narrow, BasicType broad) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif // ndef PRODUCT
|
#endif
|
||||||
|
|
||||||
static int assemble_redirect(
|
static int assemble_redirect(
|
||||||
BytecodeConstantPool* cp, BytecodeBuffer* buffer,
|
BytecodeConstantPool* cp, BytecodeBuffer* buffer,
|
||||||
@ -1035,10 +851,9 @@ static int assemble_redirect(
|
|||||||
return parameter_count;
|
return parameter_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assemble_abstract_method_error(
|
static int assemble_method_error(
|
||||||
BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* message, TRAPS) {
|
BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) {
|
||||||
|
|
||||||
Symbol* errorName = vmSymbols::java_lang_AbstractMethodError();
|
|
||||||
Symbol* init = vmSymbols::object_initializer_name();
|
Symbol* init = vmSymbols::object_initializer_name();
|
||||||
Symbol* sig = vmSymbols::string_void_signature();
|
Symbol* sig = vmSymbols::string_void_signature();
|
||||||
|
|
||||||
@ -1150,8 +965,7 @@ static void create_overpasses(
|
|||||||
&bpool, &buffer, slot->signature(), selected, CHECK);
|
&bpool, &buffer, slot->signature(), selected, CHECK);
|
||||||
}
|
}
|
||||||
} else if (method->throws_exception()) {
|
} else if (method->throws_exception()) {
|
||||||
max_stack = assemble_abstract_method_error(
|
max_stack = assemble_method_error(&bpool, &buffer, method->get_exception_name(), method->get_exception_message(), CHECK);
|
||||||
&bpool, &buffer, method->get_exception_message(), CHECK);
|
|
||||||
}
|
}
|
||||||
if (max_stack != 0) {
|
if (max_stack != 0) {
|
||||||
AccessFlags flags = accessFlags_from(
|
AccessFlags flags = accessFlags_from(
|
||||||
@ -1281,4 +1095,3 @@ static void merge_in_new_methods(InstanceKlass* klass,
|
|||||||
MetadataFactory::free_array(cld, original_ordering);
|
MetadataFactory::free_array(cld, original_ordering);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -44,15 +44,5 @@ class DefaultMethods : AllStatic {
|
|||||||
// the class.
|
// the class.
|
||||||
static void generate_default_methods(
|
static void generate_default_methods(
|
||||||
InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS);
|
InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS);
|
||||||
|
|
||||||
|
|
||||||
// Called during linking when an invokespecial to an direct interface
|
|
||||||
// method is found. Selects and returns a method if there is a unique
|
|
||||||
// default method in the 'super_iface' part of the hierarchy which is
|
|
||||||
// also a candidate default for 'this_klass'. Otherwise throws an AME.
|
|
||||||
static Method* find_super_default(
|
|
||||||
Klass* this_klass, Klass* super_iface,
|
|
||||||
Symbol* method_name, Symbol* method_sig, TRAPS);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
|
#endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -264,7 +264,7 @@ class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
|
|||||||
}
|
}
|
||||||
if (method_type() != NULL) {
|
if (method_type() != NULL) {
|
||||||
if (printed) st->print(" and ");
|
if (printed) st->print(" and ");
|
||||||
st->print(INTPTR_FORMAT, method_type());
|
st->print(INTPTR_FORMAT, (void *)method_type());
|
||||||
printed = true;
|
printed = true;
|
||||||
}
|
}
|
||||||
st->print_cr(printed ? "" : "(empty)");
|
st->print_cr(printed ? "" : "(empty)");
|
||||||
|
@ -840,7 +840,7 @@ StringTable::VerifyRetTypes StringTable::compare_entries(
|
|||||||
if (str1 == str2) {
|
if (str1 == str2) {
|
||||||
tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
|
tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
|
||||||
"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
|
"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
|
||||||
str1, bkt1, e_cnt1, bkt2, e_cnt2);
|
(void *)str1, bkt1, e_cnt1, bkt2, e_cnt2);
|
||||||
return _verify_fail_continue;
|
return _verify_fail_continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@
|
|||||||
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
|
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
|
||||||
template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \
|
template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \
|
||||||
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
|
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
|
||||||
template(sun_invoke_Stable_signature, "Lsun/invoke/Stable;") \
|
template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \
|
||||||
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
|
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
|
||||||
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
|
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
|
||||||
template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
|
template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
|
||||||
@ -631,6 +631,10 @@
|
|||||||
do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \
|
do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \
|
||||||
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
|
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
|
||||||
\
|
\
|
||||||
|
do_name(addExact_name,"addExact") \
|
||||||
|
do_name(subtractExact_name,"subtractExact") \
|
||||||
|
do_name(multiplyExact_name,"multiplyExact") \
|
||||||
|
\
|
||||||
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
|
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
|
||||||
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
|
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
|
||||||
do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \
|
do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \
|
||||||
@ -643,6 +647,7 @@
|
|||||||
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
|
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
|
||||||
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
|
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
|
||||||
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
|
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
|
||||||
|
do_intrinsic(_addExact, java_lang_Math, addExact_name, int2_int_signature, F_S) \
|
||||||
\
|
\
|
||||||
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
|
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
|
||||||
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
|
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
|
||||||
|
@ -124,7 +124,6 @@ int CodeCache::_number_of_nmethods = 0;
|
|||||||
int CodeCache::_number_of_nmethods_with_dependencies = 0;
|
int CodeCache::_number_of_nmethods_with_dependencies = 0;
|
||||||
bool CodeCache::_needs_cache_clean = false;
|
bool CodeCache::_needs_cache_clean = false;
|
||||||
nmethod* CodeCache::_scavenge_root_nmethods = NULL;
|
nmethod* CodeCache::_scavenge_root_nmethods = NULL;
|
||||||
nmethod* CodeCache::_saved_nmethods = NULL;
|
|
||||||
|
|
||||||
int CodeCache::_codemem_full_count = 0;
|
int CodeCache::_codemem_full_count = 0;
|
||||||
|
|
||||||
@ -464,96 +463,11 @@ void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
|
|||||||
}
|
}
|
||||||
#endif //PRODUCT
|
#endif //PRODUCT
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove and return nmethod from the saved code list in order to reanimate it.
|
|
||||||
*/
|
|
||||||
nmethod* CodeCache::reanimate_saved_code(Method* m) {
|
|
||||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
|
||||||
nmethod* saved = _saved_nmethods;
|
|
||||||
nmethod* prev = NULL;
|
|
||||||
while (saved != NULL) {
|
|
||||||
if (saved->is_in_use() && saved->method() == m) {
|
|
||||||
if (prev != NULL) {
|
|
||||||
prev->set_saved_nmethod_link(saved->saved_nmethod_link());
|
|
||||||
} else {
|
|
||||||
_saved_nmethods = saved->saved_nmethod_link();
|
|
||||||
}
|
|
||||||
assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods");
|
|
||||||
saved->set_speculatively_disconnected(false);
|
|
||||||
saved->set_saved_nmethod_link(NULL);
|
|
||||||
if (PrintMethodFlushing) {
|
|
||||||
saved->print_on(tty, " ### nmethod is reconnected");
|
|
||||||
}
|
|
||||||
if (LogCompilation && (xtty != NULL)) {
|
|
||||||
ttyLocker ttyl;
|
|
||||||
xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id());
|
|
||||||
xtty->method(m);
|
|
||||||
xtty->stamp();
|
|
||||||
xtty->end_elem();
|
|
||||||
}
|
|
||||||
return saved;
|
|
||||||
}
|
|
||||||
prev = saved;
|
|
||||||
saved = saved->saved_nmethod_link();
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove nmethod from the saved code list in order to discard it permanently
|
|
||||||
*/
|
|
||||||
void CodeCache::remove_saved_code(nmethod* nm) {
|
|
||||||
// For conc swpr this will be called with CodeCache_lock taken by caller
|
|
||||||
assert_locked_or_safepoint(CodeCache_lock);
|
|
||||||
assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods");
|
|
||||||
nmethod* saved = _saved_nmethods;
|
|
||||||
nmethod* prev = NULL;
|
|
||||||
while (saved != NULL) {
|
|
||||||
if (saved == nm) {
|
|
||||||
if (prev != NULL) {
|
|
||||||
prev->set_saved_nmethod_link(saved->saved_nmethod_link());
|
|
||||||
} else {
|
|
||||||
_saved_nmethods = saved->saved_nmethod_link();
|
|
||||||
}
|
|
||||||
if (LogCompilation && (xtty != NULL)) {
|
|
||||||
ttyLocker ttyl;
|
|
||||||
xtty->begin_elem("nmethod_removed compile_id='%3d'", nm->compile_id());
|
|
||||||
xtty->stamp();
|
|
||||||
xtty->end_elem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prev = saved;
|
|
||||||
saved = saved->saved_nmethod_link();
|
|
||||||
}
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CodeCache::speculatively_disconnect(nmethod* nm) {
|
|
||||||
assert_locked_or_safepoint(CodeCache_lock);
|
|
||||||
assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods");
|
|
||||||
nm->set_saved_nmethod_link(_saved_nmethods);
|
|
||||||
_saved_nmethods = nm;
|
|
||||||
if (PrintMethodFlushing) {
|
|
||||||
nm->print_on(tty, " ### nmethod is speculatively disconnected");
|
|
||||||
}
|
|
||||||
if (LogCompilation && (xtty != NULL)) {
|
|
||||||
ttyLocker ttyl;
|
|
||||||
xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id());
|
|
||||||
xtty->method(nm->method());
|
|
||||||
xtty->stamp();
|
|
||||||
xtty->end_elem();
|
|
||||||
}
|
|
||||||
nm->method()->clear_code();
|
|
||||||
nm->set_speculatively_disconnected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodeCache::gc_prologue() {
|
void CodeCache::gc_prologue() {
|
||||||
assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
|
assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CodeCache::gc_epilogue() {
|
void CodeCache::gc_epilogue() {
|
||||||
assert_locked_or_safepoint(CodeCache_lock);
|
assert_locked_or_safepoint(CodeCache_lock);
|
||||||
FOR_ALL_ALIVE_BLOBS(cb) {
|
FOR_ALL_ALIVE_BLOBS(cb) {
|
||||||
|
@ -57,7 +57,6 @@ class CodeCache : AllStatic {
|
|||||||
static int _number_of_nmethods_with_dependencies;
|
static int _number_of_nmethods_with_dependencies;
|
||||||
static bool _needs_cache_clean;
|
static bool _needs_cache_clean;
|
||||||
static nmethod* _scavenge_root_nmethods; // linked via nm->scavenge_root_link()
|
static nmethod* _scavenge_root_nmethods; // linked via nm->scavenge_root_link()
|
||||||
static nmethod* _saved_nmethods; // Linked list of speculatively disconnected nmethods.
|
|
||||||
|
|
||||||
static void verify_if_often() PRODUCT_RETURN;
|
static void verify_if_often() PRODUCT_RETURN;
|
||||||
|
|
||||||
@ -167,17 +166,12 @@ class CodeCache : AllStatic {
|
|||||||
static size_t capacity() { return _heap->capacity(); }
|
static size_t capacity() { return _heap->capacity(); }
|
||||||
static size_t max_capacity() { return _heap->max_capacity(); }
|
static size_t max_capacity() { return _heap->max_capacity(); }
|
||||||
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
|
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
|
||||||
static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
|
|
||||||
static double reverse_free_ratio();
|
static double reverse_free_ratio();
|
||||||
|
|
||||||
static bool needs_cache_clean() { return _needs_cache_clean; }
|
static bool needs_cache_clean() { return _needs_cache_clean; }
|
||||||
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
|
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
|
||||||
static void clear_inline_caches(); // clear all inline caches
|
static void clear_inline_caches(); // clear all inline caches
|
||||||
|
|
||||||
static nmethod* reanimate_saved_code(Method* m);
|
|
||||||
static void remove_saved_code(nmethod* nm);
|
|
||||||
static void speculatively_disconnect(nmethod* nm);
|
|
||||||
|
|
||||||
// Deoptimization
|
// Deoptimization
|
||||||
static int mark_for_deoptimization(DepChange& changes);
|
static int mark_for_deoptimization(DepChange& changes);
|
||||||
#ifdef HOTSWAP
|
#ifdef HOTSWAP
|
||||||
|
@ -462,7 +462,6 @@ void nmethod::init_defaults() {
|
|||||||
_state = alive;
|
_state = alive;
|
||||||
_marked_for_reclamation = 0;
|
_marked_for_reclamation = 0;
|
||||||
_has_flushed_dependencies = 0;
|
_has_flushed_dependencies = 0;
|
||||||
_speculatively_disconnected = 0;
|
|
||||||
_has_unsafe_access = 0;
|
_has_unsafe_access = 0;
|
||||||
_has_method_handle_invokes = 0;
|
_has_method_handle_invokes = 0;
|
||||||
_lazy_critical_native = 0;
|
_lazy_critical_native = 0;
|
||||||
@ -481,7 +480,6 @@ void nmethod::init_defaults() {
|
|||||||
_osr_link = NULL;
|
_osr_link = NULL;
|
||||||
_scavenge_root_link = NULL;
|
_scavenge_root_link = NULL;
|
||||||
_scavenge_root_state = 0;
|
_scavenge_root_state = 0;
|
||||||
_saved_nmethod_link = NULL;
|
|
||||||
_compiler = NULL;
|
_compiler = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_DTRACE_H
|
#ifdef HAVE_DTRACE_H
|
||||||
@ -686,6 +684,7 @@ nmethod::nmethod(
|
|||||||
_osr_entry_point = NULL;
|
_osr_entry_point = NULL;
|
||||||
_exception_cache = NULL;
|
_exception_cache = NULL;
|
||||||
_pc_desc_cache.reset_to(NULL);
|
_pc_desc_cache.reset_to(NULL);
|
||||||
|
_hotness_counter = NMethodSweeper::hotness_counter_reset_val();
|
||||||
|
|
||||||
code_buffer->copy_values_to(this);
|
code_buffer->copy_values_to(this);
|
||||||
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
|
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
|
||||||
@ -770,6 +769,7 @@ nmethod::nmethod(
|
|||||||
_osr_entry_point = NULL;
|
_osr_entry_point = NULL;
|
||||||
_exception_cache = NULL;
|
_exception_cache = NULL;
|
||||||
_pc_desc_cache.reset_to(NULL);
|
_pc_desc_cache.reset_to(NULL);
|
||||||
|
_hotness_counter = NMethodSweeper::hotness_counter_reset_val();
|
||||||
|
|
||||||
code_buffer->copy_values_to(this);
|
code_buffer->copy_values_to(this);
|
||||||
debug_only(verify_scavenge_root_oops());
|
debug_only(verify_scavenge_root_oops());
|
||||||
@ -842,6 +842,7 @@ nmethod::nmethod(
|
|||||||
_comp_level = comp_level;
|
_comp_level = comp_level;
|
||||||
_compiler = compiler;
|
_compiler = compiler;
|
||||||
_orig_pc_offset = orig_pc_offset;
|
_orig_pc_offset = orig_pc_offset;
|
||||||
|
_hotness_counter = NMethodSweeper::hotness_counter_reset_val();
|
||||||
|
|
||||||
// Section offsets
|
// Section offsets
|
||||||
_consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts());
|
_consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts());
|
||||||
@ -1176,7 +1177,7 @@ void nmethod::cleanup_inline_caches() {
|
|||||||
|
|
||||||
// This is a private interface with the sweeper.
|
// This is a private interface with the sweeper.
|
||||||
void nmethod::mark_as_seen_on_stack() {
|
void nmethod::mark_as_seen_on_stack() {
|
||||||
assert(is_not_entrant(), "must be a non-entrant method");
|
assert(is_alive(), "Must be an alive method");
|
||||||
// Set the traversal mark to ensure that the sweeper does 2
|
// Set the traversal mark to ensure that the sweeper does 2
|
||||||
// cleaning passes before moving to zombie.
|
// cleaning passes before moving to zombie.
|
||||||
set_stack_traversal_mark(NMethodSweeper::traversal_count());
|
set_stack_traversal_mark(NMethodSweeper::traversal_count());
|
||||||
@ -1261,7 +1262,7 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
|
|||||||
|
|
||||||
set_osr_link(NULL);
|
set_osr_link(NULL);
|
||||||
//set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
|
//set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
|
||||||
NMethodSweeper::notify(this);
|
NMethodSweeper::notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::invalidate_osr_method() {
|
void nmethod::invalidate_osr_method() {
|
||||||
@ -1351,6 +1352,15 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
|
|||||||
nmethod_needs_unregister = true;
|
nmethod_needs_unregister = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must happen before state change. Otherwise we have a race condition in
|
||||||
|
// nmethod::can_not_entrant_be_converted(). I.e., a method can immediately
|
||||||
|
// transition its state from 'not_entrant' to 'zombie' without having to wait
|
||||||
|
// for stack scanning.
|
||||||
|
if (state == not_entrant) {
|
||||||
|
mark_as_seen_on_stack();
|
||||||
|
OrderAccess::storestore();
|
||||||
|
}
|
||||||
|
|
||||||
// Change state
|
// Change state
|
||||||
_state = state;
|
_state = state;
|
||||||
|
|
||||||
@ -1369,11 +1379,6 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
|
|||||||
HandleMark hm;
|
HandleMark hm;
|
||||||
method()->clear_code();
|
method()->clear_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == not_entrant) {
|
|
||||||
mark_as_seen_on_stack();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // leave critical region under Patching_lock
|
} // leave critical region under Patching_lock
|
||||||
|
|
||||||
// When the nmethod becomes zombie it is no longer alive so the
|
// When the nmethod becomes zombie it is no longer alive so the
|
||||||
@ -1416,7 +1421,7 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sweeper aware that there is a zombie method that needs to be removed
|
// Make sweeper aware that there is a zombie method that needs to be removed
|
||||||
NMethodSweeper::notify(this);
|
NMethodSweeper::notify();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1451,10 +1456,6 @@ void nmethod::flush() {
|
|||||||
CodeCache::drop_scavenge_root_nmethod(this);
|
CodeCache::drop_scavenge_root_nmethod(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_speculatively_disconnected()) {
|
|
||||||
CodeCache::remove_saved_code(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SHARK
|
#ifdef SHARK
|
||||||
((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
|
((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
|
||||||
#endif // SHARK
|
#endif // SHARK
|
||||||
@ -1965,7 +1966,7 @@ public:
|
|||||||
if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root");
|
if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root");
|
||||||
tty->print_cr(""PTR_FORMAT"[offset=%d] detected scavengable oop "PTR_FORMAT" (found at "PTR_FORMAT")",
|
tty->print_cr(""PTR_FORMAT"[offset=%d] detected scavengable oop "PTR_FORMAT" (found at "PTR_FORMAT")",
|
||||||
_print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
|
_print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
|
||||||
(intptr_t)(*p), (intptr_t)p);
|
(void *)(*p), (intptr_t)p);
|
||||||
(*p)->print();
|
(*p)->print();
|
||||||
}
|
}
|
||||||
#endif //PRODUCT
|
#endif //PRODUCT
|
||||||
@ -2345,7 +2346,7 @@ public:
|
|||||||
_ok = false;
|
_ok = false;
|
||||||
}
|
}
|
||||||
tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
|
tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
|
||||||
(intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
|
(void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
|
||||||
}
|
}
|
||||||
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
|
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
|
||||||
};
|
};
|
||||||
@ -2466,7 +2467,7 @@ public:
|
|||||||
_ok = false;
|
_ok = false;
|
||||||
}
|
}
|
||||||
tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
|
tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
|
||||||
(intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
|
(void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
|
||||||
(*p)->print();
|
(*p)->print();
|
||||||
}
|
}
|
||||||
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
|
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
|
||||||
|
@ -119,7 +119,6 @@ class nmethod : public CodeBlob {
|
|||||||
// To support simple linked-list chaining of nmethods:
|
// To support simple linked-list chaining of nmethods:
|
||||||
nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head
|
nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head
|
||||||
nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
|
nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
|
||||||
nmethod* _saved_nmethod_link; // from CodeCache::speculatively_disconnect
|
|
||||||
|
|
||||||
static nmethod* volatile _oops_do_mark_nmethods;
|
static nmethod* volatile _oops_do_mark_nmethods;
|
||||||
nmethod* volatile _oops_do_mark_link;
|
nmethod* volatile _oops_do_mark_link;
|
||||||
@ -165,7 +164,6 @@ class nmethod : public CodeBlob {
|
|||||||
|
|
||||||
// protected by CodeCache_lock
|
// protected by CodeCache_lock
|
||||||
bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock)
|
bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock)
|
||||||
bool _speculatively_disconnected; // Marked for potential unload
|
|
||||||
|
|
||||||
bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper)
|
bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper)
|
||||||
bool _marked_for_deoptimization; // Used for stack deoptimization
|
bool _marked_for_deoptimization; // Used for stack deoptimization
|
||||||
@ -180,7 +178,7 @@ class nmethod : public CodeBlob {
|
|||||||
unsigned int _has_wide_vectors:1; // Preserve wide vectors at safepoints
|
unsigned int _has_wide_vectors:1; // Preserve wide vectors at safepoints
|
||||||
|
|
||||||
// Protected by Patching_lock
|
// Protected by Patching_lock
|
||||||
unsigned char _state; // {alive, not_entrant, zombie, unloaded}
|
volatile unsigned char _state; // {alive, not_entrant, zombie, unloaded}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
bool _oops_are_stale; // indicates that it's no longer safe to access oops section
|
bool _oops_are_stale; // indicates that it's no longer safe to access oops section
|
||||||
@ -202,11 +200,18 @@ class nmethod : public CodeBlob {
|
|||||||
|
|
||||||
// not_entrant method removal. Each mark_sweep pass will update
|
// not_entrant method removal. Each mark_sweep pass will update
|
||||||
// this mark to current sweep invocation count if it is seen on the
|
// this mark to current sweep invocation count if it is seen on the
|
||||||
// stack. An not_entrant method can be removed when there is no
|
// stack. An not_entrant method can be removed when there are no
|
||||||
// more activations, i.e., when the _stack_traversal_mark is less than
|
// more activations, i.e., when the _stack_traversal_mark is less than
|
||||||
// current sweep traversal index.
|
// current sweep traversal index.
|
||||||
long _stack_traversal_mark;
|
long _stack_traversal_mark;
|
||||||
|
|
||||||
|
// The _hotness_counter indicates the hotness of a method. The higher
|
||||||
|
// the value the hotter the method. The hotness counter of a nmethod is
|
||||||
|
// set to [(ReservedCodeCacheSize / (1024 * 1024)) * 2] each time the method
|
||||||
|
// is active while stack scanning (mark_active_nmethods()). The hotness
|
||||||
|
// counter is decreased (by 1) while sweeping.
|
||||||
|
int _hotness_counter;
|
||||||
|
|
||||||
ExceptionCache *_exception_cache;
|
ExceptionCache *_exception_cache;
|
||||||
PcDescCache _pc_desc_cache;
|
PcDescCache _pc_desc_cache;
|
||||||
|
|
||||||
@ -382,6 +387,10 @@ class nmethod : public CodeBlob {
|
|||||||
|
|
||||||
int total_size () const;
|
int total_size () const;
|
||||||
|
|
||||||
|
void dec_hotness_counter() { _hotness_counter--; }
|
||||||
|
void set_hotness_counter(int val) { _hotness_counter = val; }
|
||||||
|
int hotness_counter() const { return _hotness_counter; }
|
||||||
|
|
||||||
// Containment
|
// Containment
|
||||||
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
|
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
|
||||||
bool insts_contains (address addr) const { return insts_begin () <= addr && addr < insts_end (); }
|
bool insts_contains (address addr) const { return insts_begin () <= addr && addr < insts_end (); }
|
||||||
@ -437,9 +446,6 @@ class nmethod : public CodeBlob {
|
|||||||
bool has_method_handle_invokes() const { return _has_method_handle_invokes; }
|
bool has_method_handle_invokes() const { return _has_method_handle_invokes; }
|
||||||
void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; }
|
void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; }
|
||||||
|
|
||||||
bool is_speculatively_disconnected() const { return _speculatively_disconnected; }
|
|
||||||
void set_speculatively_disconnected(bool z) { _speculatively_disconnected = z; }
|
|
||||||
|
|
||||||
bool is_lazy_critical_native() const { return _lazy_critical_native; }
|
bool is_lazy_critical_native() const { return _lazy_critical_native; }
|
||||||
void set_lazy_critical_native(bool z) { _lazy_critical_native = z; }
|
void set_lazy_critical_native(bool z) { _lazy_critical_native = z; }
|
||||||
|
|
||||||
@ -499,9 +505,6 @@ public:
|
|||||||
nmethod* scavenge_root_link() const { return _scavenge_root_link; }
|
nmethod* scavenge_root_link() const { return _scavenge_root_link; }
|
||||||
void set_scavenge_root_link(nmethod *n) { _scavenge_root_link = n; }
|
void set_scavenge_root_link(nmethod *n) { _scavenge_root_link = n; }
|
||||||
|
|
||||||
nmethod* saved_nmethod_link() const { return _saved_nmethod_link; }
|
|
||||||
void set_saved_nmethod_link(nmethod *n) { _saved_nmethod_link = n; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Sweeper support
|
// Sweeper support
|
||||||
|
@ -634,19 +634,36 @@ CompileTask* CompileQueue::get() {
|
|||||||
NMethodSweeper::possibly_sweep();
|
NMethodSweeper::possibly_sweep();
|
||||||
|
|
||||||
MutexLocker locker(lock());
|
MutexLocker locker(lock());
|
||||||
// Wait for an available CompileTask.
|
// If _first is NULL we have no more compile jobs. There are two reasons for
|
||||||
|
// having no compile jobs: First, we compiled everything we wanted. Second,
|
||||||
|
// we ran out of code cache so compilation has been disabled. In the latter
|
||||||
|
// case we perform code cache sweeps to free memory such that we can re-enable
|
||||||
|
// compilation.
|
||||||
while (_first == NULL) {
|
while (_first == NULL) {
|
||||||
// There is no work to be done right now. Wait.
|
if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
|
||||||
if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) {
|
// Wait a certain amount of time to possibly do another sweep.
|
||||||
// During the emergency sweeping periods, wake up and sweep occasionally
|
// We must wait until stack scanning has happened so that we can
|
||||||
bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000);
|
// transition a method's state from 'not_entrant' to 'zombie'.
|
||||||
if (timedout) {
|
long wait_time = NmethodSweepCheckInterval * 1000;
|
||||||
|
if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) {
|
||||||
|
// Only one thread at a time can do sweeping. Scale the
|
||||||
|
// wait time according to the number of compiler threads.
|
||||||
|
// As a result, the next sweep is likely to happen every 100ms
|
||||||
|
// with an arbitrary number of threads that do sweeping.
|
||||||
|
wait_time = 100 * CICompilerCount;
|
||||||
|
}
|
||||||
|
bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time);
|
||||||
|
if (timeout) {
|
||||||
MutexUnlocker ul(lock());
|
MutexUnlocker ul(lock());
|
||||||
// When otherwise not busy, run nmethod sweeping
|
|
||||||
NMethodSweeper::possibly_sweep();
|
NMethodSweeper::possibly_sweep();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// During normal operation no need to wake up on timer
|
// If there are no compilation tasks and we can compile new jobs
|
||||||
|
// (i.e., there is enough free space in the code cache) there is
|
||||||
|
// no need to invoke the sweeper. As a result, the hotness of methods
|
||||||
|
// remains unchanged. This behavior is desired, since we want to keep
|
||||||
|
// the stable state, i.e., we do not want to evict methods from the
|
||||||
|
// code cache if it is unnecessary.
|
||||||
lock()->wait();
|
lock()->wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1227,16 +1244,9 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
|
|||||||
return method_code;
|
return method_code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (method->is_not_compilable(comp_level)) return NULL;
|
if (method->is_not_compilable(comp_level)) {
|
||||||
|
return NULL;
|
||||||
if (UseCodeCacheFlushing) {
|
|
||||||
nmethod* saved = CodeCache::reanimate_saved_code(method());
|
|
||||||
if (saved != NULL) {
|
|
||||||
method->set_code(method, saved);
|
|
||||||
return saved;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// osr compilation
|
// osr compilation
|
||||||
#ifndef TIERED
|
#ifndef TIERED
|
||||||
@ -1585,9 +1595,6 @@ void CompileBroker::compiler_thread_loop() {
|
|||||||
if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
|
if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
|
||||||
// the code cache is really full
|
// the code cache is really full
|
||||||
handle_full_code_cache();
|
handle_full_code_cache();
|
||||||
} else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
|
|
||||||
// Attempt to start cleaning the code cache while there is still a little headroom
|
|
||||||
NMethodSweeper::handle_full_code_cache(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CompileTask* task = queue->get();
|
CompileTask* task = queue->get();
|
||||||
@ -1943,7 +1950,11 @@ void CompileBroker::handle_full_code_cache() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (UseCodeCacheFlushing) {
|
if (UseCodeCacheFlushing) {
|
||||||
NMethodSweeper::handle_full_code_cache(true);
|
// Since code cache is full, immediately stop new compiles
|
||||||
|
if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
|
||||||
|
NMethodSweeper::log_sweep("disable_compiler");
|
||||||
|
NMethodSweeper::possibly_sweep();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
UseCompiler = false;
|
UseCompiler = false;
|
||||||
AlwaysCompileLoopMethods = false;
|
AlwaysCompileLoopMethods = false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -628,7 +628,7 @@ void DerivedPointerTable::clear() {
|
|||||||
|
|
||||||
|
|
||||||
// Returns value of location as an int
|
// Returns value of location as an int
|
||||||
intptr_t value_of_loc(oop *pointer) { return (intptr_t)(*pointer); }
|
intptr_t value_of_loc(oop *pointer) { return cast_from_oop<intptr_t>((*pointer)); }
|
||||||
|
|
||||||
|
|
||||||
void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) {
|
void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) {
|
||||||
|
@ -9065,7 +9065,7 @@ bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
|
|||||||
return !stack->isEmpty();
|
return !stack->isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUSY (oop(0x1aff1aff))
|
#define BUSY (cast_to_oop<intptr_t>(0x1aff1aff))
|
||||||
// (MT-safe) Get a prefix of at most "num" from the list.
|
// (MT-safe) Get a prefix of at most "num" from the list.
|
||||||
// The overflow list is chained through the mark word of
|
// The overflow list is chained through the mark word of
|
||||||
// each object in the list. We fetch the entire list,
|
// each object in the list. We fetch the entire list,
|
||||||
@ -9098,7 +9098,7 @@ bool CMSCollector::par_take_from_overflow_list(size_t num,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Grab the entire list; we'll put back a suffix
|
// Grab the entire list; we'll put back a suffix
|
||||||
oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
|
oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
|
||||||
Thread* tid = Thread::current();
|
Thread* tid = Thread::current();
|
||||||
// Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
|
// Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
|
||||||
// set to ParallelGCThreads.
|
// set to ParallelGCThreads.
|
||||||
@ -9113,7 +9113,7 @@ bool CMSCollector::par_take_from_overflow_list(size_t num,
|
|||||||
return false;
|
return false;
|
||||||
} else if (_overflow_list != BUSY) {
|
} else if (_overflow_list != BUSY) {
|
||||||
// Try and grab the prefix
|
// Try and grab the prefix
|
||||||
prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
|
prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the list was found to be empty, or we spun long
|
// If the list was found to be empty, or we spun long
|
||||||
|
@ -2694,7 +2694,7 @@ public:
|
|||||||
|
|
||||||
if (print_it) {
|
if (print_it) {
|
||||||
_out->print_cr(" "PTR_FORMAT"%s",
|
_out->print_cr(" "PTR_FORMAT"%s",
|
||||||
o, (over_tams) ? " >" : (marked) ? " M" : "");
|
(void *)o, (over_tams) ? " >" : (marked) ? " M" : "");
|
||||||
PrintReachableOopClosure oopCl(_out, _vo, _all);
|
PrintReachableOopClosure oopCl(_out, _vo, _all);
|
||||||
o->oop_iterate_no_header(&oopCl);
|
o->oop_iterate_no_header(&oopCl);
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
|
|||||||
size_t* marked_bytes_array,
|
size_t* marked_bytes_array,
|
||||||
BitMap* task_card_bm) {
|
BitMap* task_card_bm) {
|
||||||
G1CollectedHeap* g1h = _g1h;
|
G1CollectedHeap* g1h = _g1h;
|
||||||
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
|
CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
|
||||||
|
|
||||||
HeapWord* start = mr.start();
|
HeapWord* start = mr.start();
|
||||||
HeapWord* end = mr.end();
|
HeapWord* end = mr.end();
|
||||||
|
@ -65,9 +65,7 @@ void G1CardCounts::initialize() {
|
|||||||
// threshold limit is no more than this.
|
// threshold limit is no more than this.
|
||||||
guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
|
guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
|
||||||
|
|
||||||
ModRefBarrierSet* bs = _g1h->mr_bs();
|
_ct_bs = _g1h->g1_barrier_set();
|
||||||
guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
|
|
||||||
_ct_bs = (CardTableModRefBS*)bs;
|
|
||||||
_ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
|
_ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
|
||||||
|
|
||||||
// Allocate/Reserve the counts table
|
// Allocate/Reserve the counts table
|
||||||
|
@ -125,10 +125,8 @@ class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
|
|||||||
int _histo[256];
|
int _histo[256];
|
||||||
public:
|
public:
|
||||||
ClearLoggedCardTableEntryClosure() :
|
ClearLoggedCardTableEntryClosure() :
|
||||||
_calls(0)
|
_calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set())
|
||||||
{
|
{
|
||||||
_g1h = G1CollectedHeap::heap();
|
|
||||||
_ctbs = (CardTableModRefBS*)_g1h->barrier_set();
|
|
||||||
for (int i = 0; i < 256; i++) _histo[i] = 0;
|
for (int i = 0; i < 256; i++) _histo[i] = 0;
|
||||||
}
|
}
|
||||||
bool do_card_ptr(jbyte* card_ptr, int worker_i) {
|
bool do_card_ptr(jbyte* card_ptr, int worker_i) {
|
||||||
@ -158,11 +156,8 @@ class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure {
|
|||||||
CardTableModRefBS* _ctbs;
|
CardTableModRefBS* _ctbs;
|
||||||
public:
|
public:
|
||||||
RedirtyLoggedCardTableEntryClosure() :
|
RedirtyLoggedCardTableEntryClosure() :
|
||||||
_calls(0)
|
_calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {}
|
||||||
{
|
|
||||||
_g1h = G1CollectedHeap::heap();
|
|
||||||
_ctbs = (CardTableModRefBS*)_g1h->barrier_set();
|
|
||||||
}
|
|
||||||
bool do_card_ptr(jbyte* card_ptr, int worker_i) {
|
bool do_card_ptr(jbyte* card_ptr, int worker_i) {
|
||||||
if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
|
if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
|
||||||
_calls++;
|
_calls++;
|
||||||
@ -478,7 +473,7 @@ bool G1CollectedHeap::is_scavengable(const void* p) {
|
|||||||
|
|
||||||
void G1CollectedHeap::check_ct_logs_at_safepoint() {
|
void G1CollectedHeap::check_ct_logs_at_safepoint() {
|
||||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set();
|
CardTableModRefBS* ct_bs = g1_barrier_set();
|
||||||
|
|
||||||
// Count the dirty cards at the start.
|
// Count the dirty cards at the start.
|
||||||
CountNonCleanMemRegionClosure count1(this);
|
CountNonCleanMemRegionClosure count1(this);
|
||||||
@ -1205,7 +1200,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void G1CollectedHeap::clear_rsets_post_compaction() {
|
void G1CollectedHeap::clear_rsets_post_compaction() {
|
||||||
PostMCRemSetClearClosure rs_clear(this, mr_bs());
|
PostMCRemSetClearClosure rs_clear(this, g1_barrier_set());
|
||||||
heap_region_iterate(&rs_clear);
|
heap_region_iterate(&rs_clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1777,7 +1772,6 @@ void G1CollectedHeap::update_committed_space(HeapWord* old_end,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool G1CollectedHeap::expand(size_t expand_bytes) {
|
bool G1CollectedHeap::expand(size_t expand_bytes) {
|
||||||
size_t old_mem_size = _g1_storage.committed_size();
|
|
||||||
size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
|
size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
|
||||||
aligned_expand_bytes = align_size_up(aligned_expand_bytes,
|
aligned_expand_bytes = align_size_up(aligned_expand_bytes,
|
||||||
HeapRegion::GrainBytes);
|
HeapRegion::GrainBytes);
|
||||||
@ -1787,6 +1781,13 @@ bool G1CollectedHeap::expand(size_t expand_bytes) {
|
|||||||
ergo_format_byte("attempted expansion amount"),
|
ergo_format_byte("attempted expansion amount"),
|
||||||
expand_bytes, aligned_expand_bytes);
|
expand_bytes, aligned_expand_bytes);
|
||||||
|
|
||||||
|
if (_g1_storage.uncommitted_size() == 0) {
|
||||||
|
ergo_verbose0(ErgoHeapSizing,
|
||||||
|
"did not expand the heap",
|
||||||
|
ergo_format_reason("heap already fully expanded"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// First commit the memory.
|
// First commit the memory.
|
||||||
HeapWord* old_end = (HeapWord*) _g1_storage.high();
|
HeapWord* old_end = (HeapWord*) _g1_storage.high();
|
||||||
bool successful = _g1_storage.expand_by(aligned_expand_bytes);
|
bool successful = _g1_storage.expand_by(aligned_expand_bytes);
|
||||||
@ -1845,7 +1846,6 @@ bool G1CollectedHeap::expand(size_t expand_bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
|
void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
|
||||||
size_t old_mem_size = _g1_storage.committed_size();
|
|
||||||
size_t aligned_shrink_bytes =
|
size_t aligned_shrink_bytes =
|
||||||
ReservedSpace::page_align_size_down(shrink_bytes);
|
ReservedSpace::page_align_size_down(shrink_bytes);
|
||||||
aligned_shrink_bytes = align_size_down(aligned_shrink_bytes,
|
aligned_shrink_bytes = align_size_down(aligned_shrink_bytes,
|
||||||
@ -2045,20 +2045,13 @@ jint G1CollectedHeap::initialize() {
|
|||||||
// Create the gen rem set (and barrier set) for the entire reserved region.
|
// Create the gen rem set (and barrier set) for the entire reserved region.
|
||||||
_rem_set = collector_policy()->create_rem_set(_reserved, 2);
|
_rem_set = collector_policy()->create_rem_set(_reserved, 2);
|
||||||
set_barrier_set(rem_set()->bs());
|
set_barrier_set(rem_set()->bs());
|
||||||
if (barrier_set()->is_a(BarrierSet::ModRef)) {
|
if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) {
|
||||||
_mr_bs = (ModRefBarrierSet*)_barrier_set;
|
vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS");
|
||||||
} else {
|
|
||||||
vm_exit_during_initialization("G1 requires a mod ref bs.");
|
|
||||||
return JNI_ENOMEM;
|
return JNI_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also create a G1 rem set.
|
// Also create a G1 rem set.
|
||||||
if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
|
_g1_rem_set = new G1RemSet(this, g1_barrier_set());
|
||||||
_g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
|
|
||||||
} else {
|
|
||||||
vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
|
|
||||||
return JNI_ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Carve out the G1 part of the heap.
|
// Carve out the G1 part of the heap.
|
||||||
|
|
||||||
@ -3681,6 +3674,11 @@ void G1CollectedHeap::gc_prologue(bool full /* Ignored */) {
|
|||||||
assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
|
assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
|
||||||
// Fill TLAB's and such
|
// Fill TLAB's and such
|
||||||
ensure_parsability(true);
|
ensure_parsability(true);
|
||||||
|
|
||||||
|
if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) &&
|
||||||
|
(total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
|
||||||
|
g1_rem_set()->print_periodic_summary_info("Before GC RS summary");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
|
void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
|
||||||
@ -3689,7 +3687,7 @@ void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
|
|||||||
(G1SummarizeRSetStatsPeriod > 0) &&
|
(G1SummarizeRSetStatsPeriod > 0) &&
|
||||||
// we are at the end of the GC. Total collections has already been increased.
|
// we are at the end of the GC. Total collections has already been increased.
|
||||||
((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
|
((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
|
||||||
g1_rem_set()->print_periodic_summary_info();
|
g1_rem_set()->print_periodic_summary_info("After GC RS summary");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: what is this about?
|
// FIXME: what is this about?
|
||||||
@ -4550,7 +4548,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num)
|
|||||||
: _g1h(g1h),
|
: _g1h(g1h),
|
||||||
_refs(g1h->task_queue(queue_num)),
|
_refs(g1h->task_queue(queue_num)),
|
||||||
_dcq(&g1h->dirty_card_queue_set()),
|
_dcq(&g1h->dirty_card_queue_set()),
|
||||||
_ct_bs((CardTableModRefBS*)_g1h->barrier_set()),
|
_ct_bs(g1h->g1_barrier_set()),
|
||||||
_g1_rem(g1h->g1_rem_set()),
|
_g1_rem(g1h->g1_rem_set()),
|
||||||
_hash_seed(17), _queue_num(queue_num),
|
_hash_seed(17), _queue_num(queue_num),
|
||||||
_term_attempts(0),
|
_term_attempts(0),
|
||||||
@ -4617,7 +4615,7 @@ bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
|
|||||||
assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref));
|
assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref));
|
||||||
oop p = oopDesc::load_decode_heap_oop(ref);
|
oop p = oopDesc::load_decode_heap_oop(ref);
|
||||||
assert(_g1h->is_in_g1_reserved(p),
|
assert(_g1h->is_in_g1_reserved(p),
|
||||||
err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
|
err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4627,11 +4625,11 @@ bool G1ParScanThreadState::verify_ref(oop* ref) const {
|
|||||||
// Must be in the collection set--it's already been copied.
|
// Must be in the collection set--it's already been copied.
|
||||||
oop p = clear_partial_array_mask(ref);
|
oop p = clear_partial_array_mask(ref);
|
||||||
assert(_g1h->obj_in_cs(p),
|
assert(_g1h->obj_in_cs(p),
|
||||||
err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
|
err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p));
|
||||||
} else {
|
} else {
|
||||||
oop p = oopDesc::load_decode_heap_oop(ref);
|
oop p = oopDesc::load_decode_heap_oop(ref);
|
||||||
assert(_g1h->is_in_g1_reserved(p),
|
assert(_g1h->is_in_g1_reserved(p),
|
||||||
err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p)));
|
err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5979,11 +5977,11 @@ void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used,
|
|||||||
}
|
}
|
||||||
|
|
||||||
class G1ParCleanupCTTask : public AbstractGangTask {
|
class G1ParCleanupCTTask : public AbstractGangTask {
|
||||||
CardTableModRefBS* _ct_bs;
|
G1SATBCardTableModRefBS* _ct_bs;
|
||||||
G1CollectedHeap* _g1h;
|
G1CollectedHeap* _g1h;
|
||||||
HeapRegion* volatile _su_head;
|
HeapRegion* volatile _su_head;
|
||||||
public:
|
public:
|
||||||
G1ParCleanupCTTask(CardTableModRefBS* ct_bs,
|
G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs,
|
||||||
G1CollectedHeap* g1h) :
|
G1CollectedHeap* g1h) :
|
||||||
AbstractGangTask("G1 Par Cleanup CT Task"),
|
AbstractGangTask("G1 Par Cleanup CT Task"),
|
||||||
_ct_bs(ct_bs), _g1h(g1h) { }
|
_ct_bs(ct_bs), _g1h(g1h) { }
|
||||||
@ -6006,9 +6004,9 @@ public:
|
|||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
class G1VerifyCardTableCleanup: public HeapRegionClosure {
|
class G1VerifyCardTableCleanup: public HeapRegionClosure {
|
||||||
G1CollectedHeap* _g1h;
|
G1CollectedHeap* _g1h;
|
||||||
CardTableModRefBS* _ct_bs;
|
G1SATBCardTableModRefBS* _ct_bs;
|
||||||
public:
|
public:
|
||||||
G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs)
|
G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs)
|
||||||
: _g1h(g1h), _ct_bs(ct_bs) { }
|
: _g1h(g1h), _ct_bs(ct_bs) { }
|
||||||
virtual bool doHeapRegion(HeapRegion* r) {
|
virtual bool doHeapRegion(HeapRegion* r) {
|
||||||
if (r->is_survivor()) {
|
if (r->is_survivor()) {
|
||||||
@ -6022,7 +6020,7 @@ public:
|
|||||||
|
|
||||||
void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) {
|
void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) {
|
||||||
// All of the region should be clean.
|
// All of the region should be clean.
|
||||||
CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set();
|
G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
|
||||||
MemRegion mr(hr->bottom(), hr->end());
|
MemRegion mr(hr->bottom(), hr->end());
|
||||||
ct_bs->verify_not_dirty_region(mr);
|
ct_bs->verify_not_dirty_region(mr);
|
||||||
}
|
}
|
||||||
@ -6035,13 +6033,13 @@ void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) {
|
|||||||
// not dirty that area (one less thing to have to do while holding
|
// not dirty that area (one less thing to have to do while holding
|
||||||
// a lock). So we can only verify that [bottom(),pre_dummy_top()]
|
// a lock). So we can only verify that [bottom(),pre_dummy_top()]
|
||||||
// is dirty.
|
// is dirty.
|
||||||
CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set();
|
G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
|
||||||
MemRegion mr(hr->bottom(), hr->pre_dummy_top());
|
MemRegion mr(hr->bottom(), hr->pre_dummy_top());
|
||||||
ct_bs->verify_dirty_region(mr);
|
ct_bs->verify_dirty_region(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
|
void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
|
||||||
CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set();
|
G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
|
||||||
for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
|
for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
|
||||||
verify_dirty_region(hr);
|
verify_dirty_region(hr);
|
||||||
}
|
}
|
||||||
@ -6053,7 +6051,7 @@ void G1CollectedHeap::verify_dirty_young_regions() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void G1CollectedHeap::cleanUpCardTable() {
|
void G1CollectedHeap::cleanUpCardTable() {
|
||||||
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
|
G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
|
||||||
double start = os::elapsedTime();
|
double start = os::elapsedTime();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "gc_implementation/g1/g1HRPrinter.hpp"
|
#include "gc_implementation/g1/g1HRPrinter.hpp"
|
||||||
#include "gc_implementation/g1/g1MonitoringSupport.hpp"
|
#include "gc_implementation/g1/g1MonitoringSupport.hpp"
|
||||||
#include "gc_implementation/g1/g1RemSet.hpp"
|
#include "gc_implementation/g1/g1RemSet.hpp"
|
||||||
|
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
|
||||||
#include "gc_implementation/g1/g1YCTypes.hpp"
|
#include "gc_implementation/g1/g1YCTypes.hpp"
|
||||||
#include "gc_implementation/g1/heapRegionSeq.hpp"
|
#include "gc_implementation/g1/heapRegionSeq.hpp"
|
||||||
#include "gc_implementation/g1/heapRegionSets.hpp"
|
#include "gc_implementation/g1/heapRegionSets.hpp"
|
||||||
@ -703,7 +704,7 @@ public:
|
|||||||
if (_g1_committed.contains((HeapWord*) obj)) {
|
if (_g1_committed.contains((HeapWord*) obj)) {
|
||||||
// no need to subtract the bottom of the heap from obj,
|
// no need to subtract the bottom of the heap from obj,
|
||||||
// _in_cset_fast_test is biased
|
// _in_cset_fast_test is biased
|
||||||
uintx index = (uintx) obj >> HeapRegion::LogOfHRGrainBytes;
|
uintx index = cast_from_oop<uintx>(obj) >> HeapRegion::LogOfHRGrainBytes;
|
||||||
bool ret = _in_cset_fast_test[index];
|
bool ret = _in_cset_fast_test[index];
|
||||||
// let's make sure the result is consistent with what the slower
|
// let's make sure the result is consistent with what the slower
|
||||||
// test returns
|
// test returns
|
||||||
@ -791,8 +792,6 @@ protected:
|
|||||||
|
|
||||||
// The g1 remembered set of the heap.
|
// The g1 remembered set of the heap.
|
||||||
G1RemSet* _g1_rem_set;
|
G1RemSet* _g1_rem_set;
|
||||||
// And it's mod ref barrier set, used to track updates for the above.
|
|
||||||
ModRefBarrierSet* _mr_bs;
|
|
||||||
|
|
||||||
// A set of cards that cover the objects for which the Rsets should be updated
|
// A set of cards that cover the objects for which the Rsets should be updated
|
||||||
// concurrently after the collection.
|
// concurrently after the collection.
|
||||||
@ -1127,7 +1126,6 @@ public:
|
|||||||
|
|
||||||
// The rem set and barrier set.
|
// The rem set and barrier set.
|
||||||
G1RemSet* g1_rem_set() const { return _g1_rem_set; }
|
G1RemSet* g1_rem_set() const { return _g1_rem_set; }
|
||||||
ModRefBarrierSet* mr_bs() const { return _mr_bs; }
|
|
||||||
|
|
||||||
unsigned get_gc_time_stamp() {
|
unsigned get_gc_time_stamp() {
|
||||||
return _gc_time_stamp;
|
return _gc_time_stamp;
|
||||||
@ -1346,6 +1344,10 @@ public:
|
|||||||
|
|
||||||
virtual bool is_in_closed_subset(const void* p) const;
|
virtual bool is_in_closed_subset(const void* p) const;
|
||||||
|
|
||||||
|
G1SATBCardTableModRefBS* g1_barrier_set() {
|
||||||
|
return (G1SATBCardTableModRefBS*) barrier_set();
|
||||||
|
}
|
||||||
|
|
||||||
// This resets the card table to all zeros. It is used after
|
// This resets the card table to all zeros. It is used after
|
||||||
// a collection pause which used the card table to claim cards.
|
// a collection pause which used the card table to claim cards.
|
||||||
void cleanUpCardTable();
|
void cleanUpCardTable();
|
||||||
@ -1875,7 +1877,7 @@ protected:
|
|||||||
G1CollectedHeap* _g1h;
|
G1CollectedHeap* _g1h;
|
||||||
RefToScanQueue* _refs;
|
RefToScanQueue* _refs;
|
||||||
DirtyCardQueue _dcq;
|
DirtyCardQueue _dcq;
|
||||||
CardTableModRefBS* _ct_bs;
|
G1SATBCardTableModRefBS* _ct_bs;
|
||||||
G1RemSet* _g1_rem;
|
G1RemSet* _g1_rem;
|
||||||
|
|
||||||
G1ParGCAllocBufferContainer _surviving_alloc_buffer;
|
G1ParGCAllocBufferContainer _surviving_alloc_buffer;
|
||||||
@ -1914,7 +1916,7 @@ protected:
|
|||||||
void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
|
void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
|
||||||
|
|
||||||
DirtyCardQueue& dirty_card_queue() { return _dcq; }
|
DirtyCardQueue& dirty_card_queue() { return _dcq; }
|
||||||
CardTableModRefBS* ctbs() { return _ct_bs; }
|
G1SATBCardTableModRefBS* ctbs() { return _ct_bs; }
|
||||||
|
|
||||||
template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) {
|
template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) {
|
||||||
if (!from->is_survivor()) {
|
if (!from->is_survivor()) {
|
||||||
|
@ -134,7 +134,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) {
|
|||||||
assert(containing_hr->is_in(end - 1), "it should also contain end - 1");
|
assert(containing_hr->is_in(end - 1), "it should also contain end - 1");
|
||||||
|
|
||||||
MemRegion mr(start, end);
|
MemRegion mr(start, end);
|
||||||
((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr);
|
g1_barrier_set()->dirty(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const {
|
inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const {
|
||||||
|
@ -41,11 +41,11 @@ class UpdateRSetDeferred : public OopsInHeapRegionClosure {
|
|||||||
private:
|
private:
|
||||||
G1CollectedHeap* _g1;
|
G1CollectedHeap* _g1;
|
||||||
DirtyCardQueue *_dcq;
|
DirtyCardQueue *_dcq;
|
||||||
CardTableModRefBS* _ct_bs;
|
G1SATBCardTableModRefBS* _ct_bs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
|
UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
|
||||||
_g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {}
|
_g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
|
||||||
|
|
||||||
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
|
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
|
||||||
virtual void do_oop( oop* p) { do_oop_work(p); }
|
virtual void do_oop( oop* p) { do_oop_work(p); }
|
||||||
|
@ -220,7 +220,7 @@ class G1PrepareCompactClosure: public HeapRegionClosure {
|
|||||||
public:
|
public:
|
||||||
G1PrepareCompactClosure(CompactibleSpace* cs)
|
G1PrepareCompactClosure(CompactibleSpace* cs)
|
||||||
: _g1h(G1CollectedHeap::heap()),
|
: _g1h(G1CollectedHeap::heap()),
|
||||||
_mrbs(G1CollectedHeap::heap()->mr_bs()),
|
_mrbs(_g1h->g1_barrier_set()),
|
||||||
_cp(NULL, cs, cs->initialize_threshold()),
|
_cp(NULL, cs, cs->initialize_threshold()),
|
||||||
_humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
|
_humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -91,12 +91,12 @@ template <class T> inline bool has_partial_array_mask(T* ref) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T> inline T* set_partial_array_mask(T obj) {
|
template <class T> inline T* set_partial_array_mask(T obj) {
|
||||||
assert(((uintptr_t)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
|
assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
|
||||||
return (T*) ((uintptr_t)obj | G1_PARTIAL_ARRAY_MASK);
|
return (T*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> inline oop clear_partial_array_mask(T* ref) {
|
template <class T> inline oop clear_partial_array_mask(T* ref) {
|
||||||
return oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK);
|
return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
class G1ParScanPartialArrayClosure : public G1ParClosureSuper {
|
class G1ParScanPartialArrayClosure : public G1ParClosureSuper {
|
||||||
|
@ -83,7 +83,9 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
|
|||||||
for (uint i = 0; i < n_workers(); i++) {
|
for (uint i = 0; i < n_workers(); i++) {
|
||||||
_cset_rs_update_cl[i] = NULL;
|
_cset_rs_update_cl[i] = NULL;
|
||||||
}
|
}
|
||||||
_prev_period_summary.initialize(this, n_workers());
|
if (G1SummarizeRSetStats) {
|
||||||
|
_prev_period_summary.initialize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
G1RemSet::~G1RemSet() {
|
G1RemSet::~G1RemSet() {
|
||||||
@ -109,7 +111,7 @@ class ScanRSClosure : public HeapRegionClosure {
|
|||||||
CodeBlobToOopClosure* _code_root_cl;
|
CodeBlobToOopClosure* _code_root_cl;
|
||||||
|
|
||||||
G1BlockOffsetSharedArray* _bot_shared;
|
G1BlockOffsetSharedArray* _bot_shared;
|
||||||
CardTableModRefBS *_ct_bs;
|
G1SATBCardTableModRefBS *_ct_bs;
|
||||||
|
|
||||||
double _strong_code_root_scan_time_sec;
|
double _strong_code_root_scan_time_sec;
|
||||||
int _worker_i;
|
int _worker_i;
|
||||||
@ -130,7 +132,7 @@ public:
|
|||||||
{
|
{
|
||||||
_g1h = G1CollectedHeap::heap();
|
_g1h = G1CollectedHeap::heap();
|
||||||
_bot_shared = _g1h->bot_shared();
|
_bot_shared = _g1h->bot_shared();
|
||||||
_ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
|
_ct_bs = _g1h->g1_barrier_set();
|
||||||
_block_size = MAX2<int>(G1RSetScanBlockSize, 1);
|
_block_size = MAX2<int>(G1RSetScanBlockSize, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,12 +507,7 @@ public:
|
|||||||
ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
|
ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
|
||||||
_g1h(G1CollectedHeap::heap()),
|
_g1h(G1CollectedHeap::heap()),
|
||||||
_region_bm(region_bm), _card_bm(card_bm),
|
_region_bm(region_bm), _card_bm(card_bm),
|
||||||
_ctbs(NULL)
|
_ctbs(_g1h->g1_barrier_set()) {}
|
||||||
{
|
|
||||||
ModRefBarrierSet* bs = _g1h->mr_bs();
|
|
||||||
guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
|
|
||||||
_ctbs = (CardTableModRefBS*)bs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doHeapRegion(HeapRegion* r) {
|
bool doHeapRegion(HeapRegion* r) {
|
||||||
if (!r->continuesHumongous()) {
|
if (!r->continuesHumongous()) {
|
||||||
@ -731,19 +728,19 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i,
|
|||||||
return has_refs_into_cset;
|
return has_refs_into_cset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1RemSet::print_periodic_summary_info() {
|
void G1RemSet::print_periodic_summary_info(const char* header) {
|
||||||
G1RemSetSummary current;
|
G1RemSetSummary current;
|
||||||
current.initialize(this, n_workers());
|
current.initialize(this);
|
||||||
|
|
||||||
_prev_period_summary.subtract_from(¤t);
|
_prev_period_summary.subtract_from(¤t);
|
||||||
print_summary_info(&_prev_period_summary);
|
print_summary_info(&_prev_period_summary, header);
|
||||||
|
|
||||||
_prev_period_summary.set(¤t);
|
_prev_period_summary.set(¤t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1RemSet::print_summary_info() {
|
void G1RemSet::print_summary_info() {
|
||||||
G1RemSetSummary current;
|
G1RemSetSummary current;
|
||||||
current.initialize(this, n_workers());
|
current.initialize(this);
|
||||||
|
|
||||||
print_summary_info(¤t, " Cumulative RS summary");
|
print_summary_info(¤t, " Cumulative RS summary");
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ public:
|
|||||||
virtual void print_summary_info();
|
virtual void print_summary_info();
|
||||||
|
|
||||||
// Print accumulated summary info from the last time called.
|
// Print accumulated summary info from the last time called.
|
||||||
virtual void print_periodic_summary_info();
|
virtual void print_periodic_summary_info(const char* header);
|
||||||
|
|
||||||
// Prepare remembered set for verification.
|
// Prepare remembered set for verification.
|
||||||
virtual void prepare_for_verify();
|
virtual void prepare_for_verify();
|
||||||
|
@ -77,12 +77,12 @@ double G1RemSetSummary::rs_thread_vtime(uint thread) const {
|
|||||||
return _rs_threads_vtimes[thread];
|
return _rs_threads_vtimes[thread];
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1RemSetSummary::initialize(G1RemSet* remset, uint num_workers) {
|
void G1RemSetSummary::initialize(G1RemSet* remset) {
|
||||||
assert(_rs_threads_vtimes == NULL, "just checking");
|
assert(_rs_threads_vtimes == NULL, "just checking");
|
||||||
assert(remset != NULL, "just checking");
|
assert(remset != NULL, "just checking");
|
||||||
|
|
||||||
_remset = remset;
|
_remset = remset;
|
||||||
_num_vtimes = num_workers;
|
_num_vtimes = ConcurrentG1Refine::thread_num();
|
||||||
_rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC);
|
_rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC);
|
||||||
memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
|
memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
|
||||||
|
|
||||||
@ -125,25 +125,115 @@ void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
|
|||||||
_sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
|
_sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HRRSStatsIter: public HeapRegionClosure {
|
static double percent_of(size_t numerator, size_t denominator) {
|
||||||
size_t _occupied;
|
if (denominator != 0) {
|
||||||
|
return (double)numerator / denominator * 100.0f;
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t round_to_K(size_t value) {
|
||||||
|
return value / K;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegionTypeCounter VALUE_OBJ_CLASS_SPEC {
|
||||||
|
private:
|
||||||
|
const char* _name;
|
||||||
|
|
||||||
|
size_t _rs_mem_size;
|
||||||
|
size_t _cards_occupied;
|
||||||
|
size_t _amount;
|
||||||
|
|
||||||
|
size_t _code_root_mem_size;
|
||||||
|
size_t _code_root_elems;
|
||||||
|
|
||||||
|
double rs_mem_size_percent_of(size_t total) {
|
||||||
|
return percent_of(_rs_mem_size, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
double cards_occupied_percent_of(size_t total) {
|
||||||
|
return percent_of(_cards_occupied, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
double code_root_mem_size_percent_of(size_t total) {
|
||||||
|
return percent_of(_code_root_mem_size, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
double code_root_elems_percent_of(size_t total) {
|
||||||
|
return percent_of(_code_root_elems, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t amount() const { return _amount; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0),
|
||||||
|
_amount(0), _code_root_mem_size(0), _code_root_elems(0) { }
|
||||||
|
|
||||||
|
void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size,
|
||||||
|
size_t code_root_elems) {
|
||||||
|
_rs_mem_size += rs_mem_size;
|
||||||
|
_cards_occupied += cards_occupied;
|
||||||
|
_code_root_mem_size += code_root_mem_size;
|
||||||
|
_code_root_elems += code_root_elems;
|
||||||
|
_amount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t rs_mem_size() const { return _rs_mem_size; }
|
||||||
|
size_t cards_occupied() const { return _cards_occupied; }
|
||||||
|
|
||||||
|
size_t code_root_mem_size() const { return _code_root_mem_size; }
|
||||||
|
size_t code_root_elems() const { return _code_root_elems; }
|
||||||
|
|
||||||
|
void print_rs_mem_info_on(outputStream * out, size_t total) {
|
||||||
|
out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_cards_occupied_info_on(outputStream * out, size_t total) {
|
||||||
|
out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_code_root_mem_info_on(outputStream * out, size_t total) {
|
||||||
|
out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_code_root_elems_info_on(outputStream * out, size_t total) {
|
||||||
|
out->print_cr(" %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class HRRSStatsIter: public HeapRegionClosure {
|
||||||
|
private:
|
||||||
|
RegionTypeCounter _young;
|
||||||
|
RegionTypeCounter _humonguous;
|
||||||
|
RegionTypeCounter _free;
|
||||||
|
RegionTypeCounter _old;
|
||||||
|
RegionTypeCounter _all;
|
||||||
|
|
||||||
size_t _total_rs_mem_sz;
|
|
||||||
size_t _max_rs_mem_sz;
|
size_t _max_rs_mem_sz;
|
||||||
HeapRegion* _max_rs_mem_sz_region;
|
HeapRegion* _max_rs_mem_sz_region;
|
||||||
|
|
||||||
size_t _total_code_root_mem_sz;
|
size_t total_rs_mem_sz() const { return _all.rs_mem_size(); }
|
||||||
|
size_t total_cards_occupied() const { return _all.cards_occupied(); }
|
||||||
|
|
||||||
|
size_t max_rs_mem_sz() const { return _max_rs_mem_sz; }
|
||||||
|
HeapRegion* max_rs_mem_sz_region() const { return _max_rs_mem_sz_region; }
|
||||||
|
|
||||||
size_t _max_code_root_mem_sz;
|
size_t _max_code_root_mem_sz;
|
||||||
HeapRegion* _max_code_root_mem_sz_region;
|
HeapRegion* _max_code_root_mem_sz_region;
|
||||||
|
|
||||||
|
size_t total_code_root_mem_sz() const { return _all.code_root_mem_size(); }
|
||||||
|
size_t total_code_root_elems() const { return _all.code_root_elems(); }
|
||||||
|
|
||||||
|
size_t max_code_root_mem_sz() const { return _max_code_root_mem_sz; }
|
||||||
|
HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HRRSStatsIter() :
|
HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"),
|
||||||
_occupied(0),
|
_free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL),
|
||||||
_total_rs_mem_sz(0),
|
_max_rs_mem_sz(0), _max_code_root_mem_sz(0)
|
||||||
_max_rs_mem_sz(0),
|
|
||||||
_max_rs_mem_sz_region(NULL),
|
|
||||||
_total_code_root_mem_sz(0),
|
|
||||||
_max_code_root_mem_sz(0),
|
|
||||||
_max_code_root_mem_sz_region(NULL)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool doHeapRegion(HeapRegion* r) {
|
bool doHeapRegion(HeapRegion* r) {
|
||||||
@ -156,46 +246,95 @@ public:
|
|||||||
_max_rs_mem_sz = rs_mem_sz;
|
_max_rs_mem_sz = rs_mem_sz;
|
||||||
_max_rs_mem_sz_region = r;
|
_max_rs_mem_sz_region = r;
|
||||||
}
|
}
|
||||||
_total_rs_mem_sz += rs_mem_sz;
|
size_t occupied_cards = hrrs->occupied();
|
||||||
|
|
||||||
size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
|
size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
|
||||||
if (code_root_mem_sz > _max_code_root_mem_sz) {
|
if (code_root_mem_sz > max_code_root_mem_sz()) {
|
||||||
_max_code_root_mem_sz = code_root_mem_sz;
|
|
||||||
_max_code_root_mem_sz_region = r;
|
_max_code_root_mem_sz_region = r;
|
||||||
}
|
}
|
||||||
_total_code_root_mem_sz += code_root_mem_sz;
|
size_t code_root_elems = hrrs->strong_code_roots_list_length();
|
||||||
|
|
||||||
|
RegionTypeCounter* current = NULL;
|
||||||
|
if (r->is_young()) {
|
||||||
|
current = &_young;
|
||||||
|
} else if (r->isHumongous()) {
|
||||||
|
current = &_humonguous;
|
||||||
|
} else if (r->is_empty()) {
|
||||||
|
current = &_free;
|
||||||
|
} else {
|
||||||
|
current = &_old;
|
||||||
|
}
|
||||||
|
current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
|
||||||
|
_all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
|
||||||
|
|
||||||
size_t occ = hrrs->occupied();
|
|
||||||
_occupied += occ;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t total_rs_mem_sz() { return _total_rs_mem_sz; }
|
|
||||||
size_t max_rs_mem_sz() { return _max_rs_mem_sz; }
|
void print_summary_on(outputStream* out) {
|
||||||
HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; }
|
RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
|
||||||
size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; }
|
|
||||||
size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; }
|
out->print_cr("\n Current rem set statistics");
|
||||||
HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; }
|
out->print_cr(" Total per region rem sets sizes = "SIZE_FORMAT"K."
|
||||||
size_t occupied() { return _occupied; }
|
" Max = "SIZE_FORMAT"K.",
|
||||||
|
round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
|
||||||
|
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
|
||||||
|
(*current)->print_rs_mem_info_on(out, total_rs_mem_sz());
|
||||||
|
}
|
||||||
|
|
||||||
|
out->print_cr(" Static structures = "SIZE_FORMAT"K,"
|
||||||
|
" free_lists = "SIZE_FORMAT"K.",
|
||||||
|
round_to_K(HeapRegionRemSet::static_mem_size()),
|
||||||
|
round_to_K(HeapRegionRemSet::fl_mem_size()));
|
||||||
|
|
||||||
|
out->print_cr(" "SIZE_FORMAT" occupied cards represented.",
|
||||||
|
total_cards_occupied());
|
||||||
|
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
|
||||||
|
(*current)->print_cards_occupied_info_on(out, total_cards_occupied());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Largest sized rem set region statistics
|
||||||
|
HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set();
|
||||||
|
out->print_cr(" Region with largest rem set = "HR_FORMAT", "
|
||||||
|
"size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
|
||||||
|
HR_FORMAT_PARAMS(max_rs_mem_sz_region()),
|
||||||
|
round_to_K(rem_set->mem_size()),
|
||||||
|
round_to_K(rem_set->occupied()));
|
||||||
|
|
||||||
|
// Strong code root statistics
|
||||||
|
HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set();
|
||||||
|
out->print_cr(" Total heap region code root sets sizes = "SIZE_FORMAT"K."
|
||||||
|
" Max = "SIZE_FORMAT"K.",
|
||||||
|
round_to_K(total_code_root_mem_sz()),
|
||||||
|
round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()));
|
||||||
|
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
|
||||||
|
(*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz());
|
||||||
|
}
|
||||||
|
|
||||||
|
out->print_cr(" "SIZE_FORMAT" code roots represented.",
|
||||||
|
total_code_root_elems());
|
||||||
|
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
|
||||||
|
(*current)->print_code_root_elems_info_on(out, total_code_root_elems());
|
||||||
|
}
|
||||||
|
|
||||||
|
out->print_cr(" Region with largest amount of code roots = "HR_FORMAT", "
|
||||||
|
"size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
|
||||||
|
HR_FORMAT_PARAMS(max_code_root_mem_sz_region()),
|
||||||
|
round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()),
|
||||||
|
round_to_K(max_code_root_rem_set->strong_code_roots_list_length()));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
double calc_percentage(size_t numerator, size_t denominator) {
|
|
||||||
if (denominator != 0) {
|
|
||||||
return (double)numerator / denominator * 100.0;
|
|
||||||
} else {
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void G1RemSetSummary::print_on(outputStream* out) {
|
void G1RemSetSummary::print_on(outputStream* out) {
|
||||||
out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards",
|
out->print_cr("\n Recent concurrent refinement statistics");
|
||||||
|
out->print_cr(" Processed "SIZE_FORMAT" cards",
|
||||||
num_concurrent_refined_cards());
|
num_concurrent_refined_cards());
|
||||||
out->print_cr(" Of %d completed buffers:", num_processed_buf_total());
|
out->print_cr(" Of %d completed buffers:", num_processed_buf_total());
|
||||||
out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.",
|
out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.",
|
||||||
num_processed_buf_total(),
|
num_processed_buf_total(),
|
||||||
calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total()));
|
percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
|
||||||
out->print_cr(" %8d (%5.1f%%) by mutator threads.",
|
out->print_cr(" %8d (%5.1f%%) by mutator threads.",
|
||||||
num_processed_buf_mutator(),
|
num_processed_buf_mutator(),
|
||||||
calc_percentage(num_processed_buf_mutator(), num_processed_buf_total()));
|
percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
|
||||||
|
out->print_cr(" Did %d coarsenings.", num_coarsenings());
|
||||||
out->print_cr(" Concurrent RS threads times (s)");
|
out->print_cr(" Concurrent RS threads times (s)");
|
||||||
out->print(" ");
|
out->print(" ");
|
||||||
for (uint i = 0; i < _num_vtimes; i++) {
|
for (uint i = 0; i < _num_vtimes; i++) {
|
||||||
@ -207,33 +346,5 @@ void G1RemSetSummary::print_on(outputStream* out) {
|
|||||||
|
|
||||||
HRRSStatsIter blk;
|
HRRSStatsIter blk;
|
||||||
G1CollectedHeap::heap()->heap_region_iterate(&blk);
|
G1CollectedHeap::heap()->heap_region_iterate(&blk);
|
||||||
// RemSet stats
|
blk.print_summary_on(out);
|
||||||
out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K."
|
|
||||||
" Max = "SIZE_FORMAT"K.",
|
|
||||||
blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K);
|
|
||||||
out->print_cr(" Static structures = "SIZE_FORMAT"K,"
|
|
||||||
" free_lists = "SIZE_FORMAT"K.",
|
|
||||||
HeapRegionRemSet::static_mem_size() / K,
|
|
||||||
HeapRegionRemSet::fl_mem_size() / K);
|
|
||||||
out->print_cr(" "SIZE_FORMAT" occupied cards represented.",
|
|
||||||
blk.occupied());
|
|
||||||
HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region();
|
|
||||||
HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set();
|
|
||||||
out->print_cr(" Max size region = "HR_FORMAT", "
|
|
||||||
"size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
|
|
||||||
HR_FORMAT_PARAMS(max_rs_mem_sz_region),
|
|
||||||
(max_rs_rem_set->mem_size() + K - 1)/K,
|
|
||||||
(max_rs_rem_set->occupied() + K - 1)/K);
|
|
||||||
out->print_cr(" Did %d coarsenings.", num_coarsenings());
|
|
||||||
// Strong code root stats
|
|
||||||
out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K."
|
|
||||||
" Max = "SIZE_FORMAT"K.",
|
|
||||||
blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K);
|
|
||||||
HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region();
|
|
||||||
HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set();
|
|
||||||
out->print_cr(" Max size region = "HR_FORMAT", "
|
|
||||||
"size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
|
|
||||||
HR_FORMAT_PARAMS(max_code_root_mem_sz_region),
|
|
||||||
(max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K,
|
|
||||||
(max_code_root_rem_set->strong_code_roots_list_length()));
|
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ public:
|
|||||||
void subtract_from(G1RemSetSummary* other);
|
void subtract_from(G1RemSetSummary* other);
|
||||||
|
|
||||||
// initialize and get the first sampling
|
// initialize and get the first sampling
|
||||||
void initialize(G1RemSet* remset, uint num_workers);
|
void initialize(G1RemSet* remset);
|
||||||
|
|
||||||
void print_on(outputStream* out);
|
void print_on(outputStream* out);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -64,6 +64,27 @@ G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) {
|
||||||
|
jbyte val = _byte_map[card_index];
|
||||||
|
// It's already processed
|
||||||
|
if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Cached bit can be installed either on a clean card or on a claimed card.
|
||||||
|
jbyte new_val = val;
|
||||||
|
if (val == clean_card_val()) {
|
||||||
|
new_val = (jbyte)deferred_card_val();
|
||||||
|
} else {
|
||||||
|
if (val & claimed_card_val()) {
|
||||||
|
new_val = val | (jbyte)deferred_card_val();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (new_val != val) {
|
||||||
|
Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
G1SATBCardTableLoggingModRefBS::
|
G1SATBCardTableLoggingModRefBS::
|
||||||
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
|
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
|
||||||
int max_covered_regions) :
|
int max_covered_regions) :
|
||||||
@ -95,7 +116,7 @@ void
|
|||||||
G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field,
|
G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field,
|
||||||
oop new_val) {
|
oop new_val) {
|
||||||
uintptr_t field_uint = (uintptr_t)field;
|
uintptr_t field_uint = (uintptr_t)field;
|
||||||
uintptr_t new_val_uint = (uintptr_t)new_val;
|
uintptr_t new_val_uint = cast_from_oop<uintptr_t>(new_val);
|
||||||
uintptr_t comb = field_uint ^ new_val_uint;
|
uintptr_t comb = field_uint ^ new_val_uint;
|
||||||
comb = comb >> HeapRegion::LogOfHRGrainBytes;
|
comb = comb >> HeapRegion::LogOfHRGrainBytes;
|
||||||
if (comb == 0) return;
|
if (comb == 0) return;
|
||||||
|
@ -89,6 +89,42 @@ public:
|
|||||||
write_ref_array_pre_work(dst, count);
|
write_ref_array_pre_work(dst, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Claimed and deferred bits are used together in G1 during the evacuation
|
||||||
|
pause. These bits can have the following state transitions:
|
||||||
|
1. The claimed bit can be put over any other card state. Except that
|
||||||
|
the "dirty -> dirty and claimed" transition is checked for in
|
||||||
|
G1 code and is not used.
|
||||||
|
2. Deferred bit can be set only if the previous state of the card
|
||||||
|
was either clean or claimed. mark_card_deferred() is wait-free.
|
||||||
|
We do not care if the operation is be successful because if
|
||||||
|
it does not it will only result in duplicate entry in the update
|
||||||
|
buffer because of the "cache-miss". So it's not worth spinning.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool is_card_claimed(size_t card_index) {
|
||||||
|
jbyte val = _byte_map[card_index];
|
||||||
|
return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_card_claimed(size_t card_index) {
|
||||||
|
jbyte val = _byte_map[card_index];
|
||||||
|
if (val == clean_card_val()) {
|
||||||
|
val = (jbyte)claimed_card_val();
|
||||||
|
} else {
|
||||||
|
val |= (jbyte)claimed_card_val();
|
||||||
|
}
|
||||||
|
_byte_map[card_index] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mark_card_deferred(size_t card_index);
|
||||||
|
|
||||||
|
bool is_card_deferred(size_t card_index) {
|
||||||
|
jbyte val = _byte_map[card_index];
|
||||||
|
return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Adds card-table logging to the post-barrier.
|
// Adds card-table logging to the post-barrier.
|
||||||
|
@ -637,7 +637,7 @@ class VerifyStrongCodeRootOopClosure: public OopClosure {
|
|||||||
gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
|
gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
|
||||||
"["PTR_FORMAT", "PTR_FORMAT") is above "
|
"["PTR_FORMAT", "PTR_FORMAT") is above "
|
||||||
"top "PTR_FORMAT,
|
"top "PTR_FORMAT,
|
||||||
obj, _hr->bottom(), _hr->end(), _hr->top());
|
(void *)obj, _hr->bottom(), _hr->end(), _hr->top());
|
||||||
_failures = true;
|
_failures = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -951,12 +951,12 @@ void HeapRegion::verify(VerifyOption vo,
|
|||||||
Klass* klass = obj->klass();
|
Klass* klass = obj->klass();
|
||||||
if (!klass->is_metaspace_object()) {
|
if (!klass->is_metaspace_object()) {
|
||||||
gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
|
gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
|
||||||
"not metadata", klass, obj);
|
"not metadata", klass, (void *)obj);
|
||||||
*failures = true;
|
*failures = true;
|
||||||
return;
|
return;
|
||||||
} else if (!klass->is_klass()) {
|
} else if (!klass->is_klass()) {
|
||||||
gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
|
gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
|
||||||
"not a klass", klass, obj);
|
"not a klass", klass, (void *)obj);
|
||||||
*failures = true;
|
*failures = true;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -971,7 +971,7 @@ void HeapRegion::verify(VerifyOption vo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj);
|
gclog_or_tty->print_cr(PTR_FORMAT" no an oop", (void *)obj);
|
||||||
*failures = true;
|
*failures = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,8 @@ protected:
|
|||||||
gclog_or_tty->print_cr(" PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").",
|
gclog_or_tty->print_cr(" PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").",
|
||||||
from,
|
from,
|
||||||
UseCompressedOops
|
UseCompressedOops
|
||||||
? oopDesc::load_decode_heap_oop((narrowOop*)from)
|
? (void *)oopDesc::load_decode_heap_oop((narrowOop*)from)
|
||||||
: oopDesc::load_decode_heap_oop((oop*)from));
|
: (void *)oopDesc::load_decode_heap_oop((oop*)from));
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapRegion* loc_hr = hr();
|
HeapRegion* loc_hr = hr();
|
||||||
@ -403,8 +403,8 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
|
|||||||
gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
|
gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
|
||||||
from,
|
from,
|
||||||
UseCompressedOops
|
UseCompressedOops
|
||||||
? oopDesc::load_decode_heap_oop((narrowOop*)from)
|
? (void *)oopDesc::load_decode_heap_oop((narrowOop*)from)
|
||||||
: oopDesc::load_decode_heap_oop((oop*)from));
|
: (void *)oopDesc::load_decode_heap_oop((oop*)from));
|
||||||
}
|
}
|
||||||
|
|
||||||
int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
|
int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
|
||||||
|
@ -1103,7 +1103,7 @@ void ParNewGeneration::waste_some_time() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const oop ClaimedForwardPtr = oop(0x4);
|
static const oop ClaimedForwardPtr = cast_to_oop<intptr_t>(0x4);
|
||||||
|
|
||||||
// Because of concurrency, there are times where an object for which
|
// Because of concurrency, there are times where an object for which
|
||||||
// "is_forwarded()" is true contains an "interim" forwarding pointer
|
// "is_forwarded()" is true contains an "interim" forwarding pointer
|
||||||
@ -1226,7 +1226,7 @@ oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
|
|||||||
if (TraceScavenge) {
|
if (TraceScavenge) {
|
||||||
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
||||||
is_in_reserved(new_obj) ? "copying" : "tenuring",
|
is_in_reserved(new_obj) ? "copying" : "tenuring",
|
||||||
new_obj->klass()->internal_name(), old, new_obj, new_obj->size());
|
new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1347,7 +1347,7 @@ oop ParNewGeneration::copy_to_survivor_space_with_undo(
|
|||||||
if (TraceScavenge) {
|
if (TraceScavenge) {
|
||||||
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
||||||
is_in_reserved(new_obj) ? "copying" : "tenuring",
|
is_in_reserved(new_obj) ? "copying" : "tenuring",
|
||||||
new_obj->klass()->internal_name(), old, new_obj, new_obj->size());
|
new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1436,7 +1436,7 @@ bool ParNewGeneration::should_simulate_overflow() {
|
|||||||
// (although some performance comparisons would be useful since
|
// (although some performance comparisons would be useful since
|
||||||
// single global lists have their own performance disadvantages
|
// single global lists have their own performance disadvantages
|
||||||
// as we were made painfully aware not long ago, see 6786503).
|
// as we were made painfully aware not long ago, see 6786503).
|
||||||
#define BUSY (oop(0x1aff1aff))
|
#define BUSY (cast_to_oop<intptr_t>(0x1aff1aff))
|
||||||
void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) {
|
void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) {
|
||||||
assert(is_in_reserved(from_space_obj), "Should be from this generation");
|
assert(is_in_reserved(from_space_obj), "Should be from this generation");
|
||||||
if (ParGCUseLocalOverflow) {
|
if (ParGCUseLocalOverflow) {
|
||||||
@ -1512,7 +1512,7 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan
|
|||||||
if (_overflow_list == NULL) return false;
|
if (_overflow_list == NULL) return false;
|
||||||
|
|
||||||
// Otherwise, there was something there; try claiming the list.
|
// Otherwise, there was something there; try claiming the list.
|
||||||
oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
|
oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
|
||||||
// Trim off a prefix of at most objsFromOverflow items
|
// Trim off a prefix of at most objsFromOverflow items
|
||||||
Thread* tid = Thread::current();
|
Thread* tid = Thread::current();
|
||||||
size_t spin_count = (size_t)ParallelGCThreads;
|
size_t spin_count = (size_t)ParallelGCThreads;
|
||||||
@ -1526,7 +1526,7 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan
|
|||||||
return false;
|
return false;
|
||||||
} else if (_overflow_list != BUSY) {
|
} else if (_overflow_list != BUSY) {
|
||||||
// try and grab the prefix
|
// try and grab the prefix
|
||||||
prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
|
prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (prefix == NULL || prefix == BUSY) {
|
if (prefix == NULL || prefix == BUSY) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -84,7 +84,7 @@ inline void ParScanClosure::do_oop_work(T* p,
|
|||||||
Space* sp = gch->space_containing(p);
|
Space* sp = gch->space_containing(p);
|
||||||
oop obj = oop(sp->block_start(p));
|
oop obj = oop(sp->block_start(p));
|
||||||
assert((HeapWord*)obj < (HeapWord*)p, "Error");
|
assert((HeapWord*)obj < (HeapWord*)p, "Error");
|
||||||
tty->print_cr("Object: " PTR_FORMAT, obj);
|
tty->print_cr("Object: " PTR_FORMAT, (void *)obj);
|
||||||
tty->print_cr("-------");
|
tty->print_cr("-------");
|
||||||
obj->print();
|
obj->print();
|
||||||
tty->print_cr("-----");
|
tty->print_cr("-----");
|
||||||
@ -110,7 +110,7 @@ inline void ParScanClosure::do_oop_work(T* p,
|
|||||||
if (TraceScavenge) {
|
if (TraceScavenge) {
|
||||||
gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
||||||
"forwarded ",
|
"forwarded ",
|
||||||
new_obj->klass()->internal_name(), p, obj, new_obj, new_obj->size());
|
new_obj->klass()->internal_name(), p, (void *)obj, (void *)new_obj, new_obj->size());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -40,10 +40,8 @@ class GenerationSizer : public TwoGenerationCollectorPolicy {
|
|||||||
|
|
||||||
void initialize_flags() {
|
void initialize_flags() {
|
||||||
// Do basic sizing work
|
// Do basic sizing work
|
||||||
this->TwoGenerationCollectorPolicy::initialize_flags();
|
TwoGenerationCollectorPolicy::initialize_flags();
|
||||||
|
|
||||||
// If the user hasn't explicitly set the number of worker
|
|
||||||
// threads, set the count.
|
|
||||||
assert(UseSerialGC ||
|
assert(UseSerialGC ||
|
||||||
!FLAG_IS_DEFAULT(ParallelGCThreads) ||
|
!FLAG_IS_DEFAULT(ParallelGCThreads) ||
|
||||||
(ParallelGCThreads > 0),
|
(ParallelGCThreads > 0),
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
|
||||||
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
|
#include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
|
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
|
|
||||||
// Forward decls
|
// Forward decls
|
||||||
class elapsedTimer;
|
class elapsedTimer;
|
||||||
class GenerationSizer;
|
|
||||||
|
|
||||||
class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
||||||
friend class PSGCAdaptivePolicyCounters;
|
friend class PSGCAdaptivePolicyCounters;
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "classfile/symbolTable.hpp"
|
#include "classfile/symbolTable.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "code/codeCache.hpp"
|
#include "code/codeCache.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
|
||||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
|
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "code/codeCache.hpp"
|
#include "code/codeCache.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
|
||||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
|
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/pcTasks.hpp"
|
#include "gc_implementation/parallelScavenge/pcTasks.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
||||||
|
@ -333,7 +333,7 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
|
|||||||
gclog_or_tty->print_cr("{%s %s 0x%x (%d)}",
|
gclog_or_tty->print_cr("{%s %s 0x%x (%d)}",
|
||||||
"promotion-failure",
|
"promotion-failure",
|
||||||
obj->klass()->internal_name(),
|
obj->klass()->internal_name(),
|
||||||
obj, obj->size());
|
(void *)obj, obj->size());
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,7 +126,7 @@ class PSPromotionManager VALUE_OBJ_CLASS_SPEC {
|
|||||||
|
|
||||||
oop* mask_chunked_array_oop(oop obj) {
|
oop* mask_chunked_array_oop(oop obj) {
|
||||||
assert(!is_oop_masked((oop*) obj), "invariant");
|
assert(!is_oop_masked((oop*) obj), "invariant");
|
||||||
oop* ret = (oop*) ((uintptr_t)obj | PS_CHUNKED_ARRAY_OOP_MASK);
|
oop* ret = (oop*) (cast_from_oop<uintptr_t>(obj) | PS_CHUNKED_ARRAY_OOP_MASK);
|
||||||
assert(is_oop_masked(ret), "invariant");
|
assert(is_oop_masked(ret), "invariant");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) {
|
|||||||
if (TraceScavenge) {
|
if (TraceScavenge) {
|
||||||
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
||||||
PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
|
PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
|
||||||
new_obj->klass()->internal_name(), o, new_obj, new_obj->size());
|
new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "code/codeCache.hpp"
|
#include "code/codeCache.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
|
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
|
||||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
|
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -81,7 +81,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
|
|||||||
if (TraceScavenge && o->is_forwarded()) {
|
if (TraceScavenge && o->is_forwarded()) {
|
||||||
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
|
||||||
"forwarding",
|
"forwarding",
|
||||||
new_obj->klass()->internal_name(), o, new_obj, new_obj->size());
|
new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ void print_oop(oop value, outputStream* st) {
|
|||||||
st->print_cr(" %s", buf);
|
st->print_cr(" %s", buf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
st->print_cr(" " PTR_FORMAT, (intptr_t) value);
|
st->print_cr(" " PTR_FORMAT, (void *)value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -573,6 +572,16 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (check_access) {
|
if (check_access) {
|
||||||
|
// JDK8 adds non-public interface methods, and accessability check requirement
|
||||||
|
assert(current_klass.not_null() , "current_klass should not be null");
|
||||||
|
|
||||||
|
// check if method can be accessed by the referring class
|
||||||
|
check_method_accessability(current_klass,
|
||||||
|
resolved_klass,
|
||||||
|
KlassHandle(THREAD, resolved_method->method_holder()),
|
||||||
|
resolved_method,
|
||||||
|
CHECK);
|
||||||
|
|
||||||
HandleMark hm(THREAD);
|
HandleMark hm(THREAD);
|
||||||
Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
|
Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
|
||||||
Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
|
Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
|
||||||
@ -604,6 +613,20 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TraceItables && Verbose) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||||
|
(current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
|
||||||
|
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()),
|
||||||
|
resolved_method->method_holder()->internal_name()
|
||||||
|
);
|
||||||
|
resolved_method->access_flags().print_on(tty);
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -795,26 +818,12 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
|
|||||||
Symbol* method_name, Symbol* method_signature,
|
Symbol* method_name, Symbol* method_signature,
|
||||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
|
|
||||||
if (resolved_klass->is_interface() && current_klass() != NULL) {
|
// Invokespecial is called for multiple special reasons:
|
||||||
// If the target class is a direct interface, treat this as a "super"
|
// <init>
|
||||||
// default call.
|
// local private method invocation, for classes and interfaces
|
||||||
//
|
// superclass.method, which can also resolve to a default method
|
||||||
// If the current method is an overpass that happens to call a direct
|
// and the selected method is recalculated relative to the direct superclass
|
||||||
// super-interface's method, then we'll end up rerunning the default method
|
// superinterface.method, which explicitly does not check shadowing
|
||||||
// analysis even though we don't need to, but that's ok since it will end
|
|
||||||
// up with the same answer.
|
|
||||||
InstanceKlass* ik = InstanceKlass::cast(current_klass());
|
|
||||||
Array<Klass*>* interfaces = ik->local_interfaces();
|
|
||||||
int num_interfaces = interfaces->length();
|
|
||||||
for (int index = 0; index < num_interfaces; index++) {
|
|
||||||
if (interfaces->at(index) == resolved_klass()) {
|
|
||||||
Method* method = DefaultMethods::find_super_default(current_klass(),
|
|
||||||
resolved_klass(), method_name, method_signature, CHECK);
|
|
||||||
resolved_method = methodHandle(THREAD, method);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
|
|
||||||
@ -844,6 +853,26 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
|
|||||||
resolved_method->signature()));
|
resolved_method->signature()));
|
||||||
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||||
}
|
}
|
||||||
|
if (TraceItables && Verbose) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||||
|
(current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
|
||||||
|
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()),
|
||||||
|
resolved_method->method_holder()->internal_name()
|
||||||
|
);
|
||||||
|
resolved_method->access_flags().print_on(tty);
|
||||||
|
if (resolved_method->method_holder()->is_interface() &&
|
||||||
|
!resolved_method->is_abstract()) {
|
||||||
|
tty->print("default");
|
||||||
|
}
|
||||||
|
if (resolved_method->is_overpass()) {
|
||||||
|
tty->print("overpass");
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// throws runtime exceptions
|
// throws runtime exceptions
|
||||||
@ -851,23 +880,24 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
|
|||||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
|
|
||||||
// resolved method is selected method unless we have an old-style lookup
|
// resolved method is selected method unless we have an old-style lookup
|
||||||
|
// for a superclass method
|
||||||
|
// Invokespecial for a superinterface, resolved method is selected method,
|
||||||
|
// no checks for shadowing
|
||||||
methodHandle sel_method(THREAD, resolved_method());
|
methodHandle sel_method(THREAD, resolved_method());
|
||||||
|
|
||||||
// check if this is an old-style super call and do a new lookup if so
|
// check if this is an old-style super call and do a new lookup if so
|
||||||
{ KlassHandle method_klass = KlassHandle(THREAD,
|
{ KlassHandle method_klass = KlassHandle(THREAD,
|
||||||
resolved_method->method_holder());
|
resolved_method->method_holder());
|
||||||
|
|
||||||
const bool direct_calling_default_method =
|
if (check_access &&
|
||||||
resolved_klass() != NULL && resolved_method() != NULL &&
|
|
||||||
resolved_klass->is_interface() && !resolved_method->is_abstract();
|
|
||||||
|
|
||||||
if (!direct_calling_default_method &&
|
|
||||||
check_access &&
|
|
||||||
// a) check if ACC_SUPER flag is set for the current class
|
// a) check if ACC_SUPER flag is set for the current class
|
||||||
(current_klass->is_super() || !AllowNonVirtualCalls) &&
|
(current_klass->is_super() || !AllowNonVirtualCalls) &&
|
||||||
// b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
|
// b) check if the class of the resolved_klass is a superclass
|
||||||
current_klass->is_subtype_of(method_klass()) &&
|
// (not supertype in order to exclude interface classes) of the current class.
|
||||||
current_klass() != method_klass() &&
|
// This check is not performed for super.invoke for interface methods
|
||||||
|
// in super interfaces.
|
||||||
|
current_klass->is_subclass_of(resolved_klass()) &&
|
||||||
|
current_klass() != resolved_klass() &&
|
||||||
// c) check if the method is not <init>
|
// c) check if the method is not <init>
|
||||||
resolved_method->name() != vmSymbols::object_initializer_name()) {
|
resolved_method->name() != vmSymbols::object_initializer_name()) {
|
||||||
// Lookup super method
|
// Lookup super method
|
||||||
@ -905,6 +935,23 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
|
|||||||
sel_method->signature()));
|
sel_method->signature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TraceItables && Verbose) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||||
|
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
sel_method->name(),
|
||||||
|
sel_method->signature()),
|
||||||
|
sel_method->method_holder()->internal_name()
|
||||||
|
);
|
||||||
|
sel_method->access_flags().print_on(tty);
|
||||||
|
if (sel_method->method_holder()->is_interface() &&
|
||||||
|
!sel_method->is_abstract()) {
|
||||||
|
tty->print("default");
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
|
|
||||||
// setup result
|
// setup result
|
||||||
result.set_static(resolved_klass, sel_method, CHECK);
|
result.set_static(resolved_klass, sel_method, CHECK);
|
||||||
}
|
}
|
||||||
@ -927,6 +974,18 @@ void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method
|
|||||||
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
|
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
|
||||||
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
|
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
|
||||||
|
|
||||||
|
// check if private interface method
|
||||||
|
if (resolved_klass->is_interface() && resolved_method->is_private()) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
char buf[200];
|
||||||
|
jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()),
|
||||||
|
(current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
|
||||||
|
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||||
|
}
|
||||||
|
|
||||||
// check if not static
|
// check if not static
|
||||||
if (resolved_method->is_static()) {
|
if (resolved_method->is_static()) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -936,6 +995,27 @@ void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method
|
|||||||
resolved_method->signature()));
|
resolved_method->signature()));
|
||||||
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PrintVtables && Verbose) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||||
|
(current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
|
||||||
|
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()),
|
||||||
|
resolved_method->method_holder()->internal_name()
|
||||||
|
);
|
||||||
|
resolved_method->access_flags().print_on(tty);
|
||||||
|
if (resolved_method->method_holder()->is_interface() &&
|
||||||
|
!resolved_method->is_abstract()) {
|
||||||
|
tty->print("default");
|
||||||
|
}
|
||||||
|
if (resolved_method->is_overpass()) {
|
||||||
|
tty->print("overpass");
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// throws runtime exceptions
|
// throws runtime exceptions
|
||||||
@ -1012,6 +1092,27 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
|||||||
selected_method->signature()));
|
selected_method->signature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PrintVtables && Verbose) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ",
|
||||||
|
(recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
|
||||||
|
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()),
|
||||||
|
selected_method->method_holder()->internal_name(),
|
||||||
|
vtable_index
|
||||||
|
);
|
||||||
|
selected_method->access_flags().print_on(tty);
|
||||||
|
if (selected_method->method_holder()->is_interface() &&
|
||||||
|
!selected_method->is_abstract()) {
|
||||||
|
tty->print("default");
|
||||||
|
}
|
||||||
|
if (resolved_method->is_overpass()) {
|
||||||
|
tty->print("overpass");
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
// setup result
|
// setup result
|
||||||
result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
|
result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
|
||||||
}
|
}
|
||||||
@ -1042,6 +1143,17 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||||||
THROW(vmSymbols::java_lang_NullPointerException());
|
THROW(vmSymbols::java_lang_NullPointerException());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if private interface method
|
||||||
|
if (resolved_klass->is_interface() && resolved_method->is_private()) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
char buf[200];
|
||||||
|
jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()));
|
||||||
|
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||||
|
}
|
||||||
|
|
||||||
// check if receiver klass implements the resolved interface
|
// check if receiver klass implements the resolved interface
|
||||||
if (!recv_klass->is_subtype_of(resolved_klass())) {
|
if (!recv_klass->is_subtype_of(resolved_klass())) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -1071,20 +1183,7 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||||||
resolved_method->signature()));
|
resolved_method->signature()));
|
||||||
}
|
}
|
||||||
// check access
|
// check access
|
||||||
if (sel_method->method_holder()->is_interface()) {
|
// Throw Illegal Access Error if sel_method is not public.
|
||||||
// Method holder is an interface. Throw Illegal Access Error if sel_method
|
|
||||||
// is neither public nor private.
|
|
||||||
if (!(sel_method->is_public() || sel_method->is_private())) {
|
|
||||||
ResourceMark rm(THREAD);
|
|
||||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
|
||||||
Method::name_and_sig_as_C_string(recv_klass(),
|
|
||||||
sel_method->name(),
|
|
||||||
sel_method->signature()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Method holder is a class. Throw Illegal Access Error if sel_method
|
|
||||||
// is not public.
|
|
||||||
if (!sel_method->is_public()) {
|
if (!sel_method->is_public()) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
||||||
@ -1092,7 +1191,7 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||||||
sel_method->name(),
|
sel_method->name(),
|
||||||
sel_method->signature()));
|
sel_method->signature()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// check if abstract
|
// check if abstract
|
||||||
if (check_null_and_abstract && sel_method->is_abstract()) {
|
if (check_null_and_abstract && sel_method->is_abstract()) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -1109,6 +1208,27 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int itable_index = resolved_method()->itable_index();
|
int itable_index = resolved_method()->itable_index();
|
||||||
|
|
||||||
|
if (TraceItables && Verbose) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||||
|
(recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
|
||||||
|
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||||
|
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||||
|
resolved_method->name(),
|
||||||
|
resolved_method->signature()),
|
||||||
|
sel_method->method_holder()->internal_name()
|
||||||
|
);
|
||||||
|
sel_method->access_flags().print_on(tty);
|
||||||
|
if (sel_method->method_holder()->is_interface() &&
|
||||||
|
!sel_method->is_abstract()) {
|
||||||
|
tty->print("default");
|
||||||
|
}
|
||||||
|
if (resolved_method->is_overpass()) {
|
||||||
|
tty->print("overpass");
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
|
result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1384,7 +1504,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
|||||||
THREAD);
|
THREAD);
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION);
|
tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION);
|
||||||
PENDING_EXCEPTION->print();
|
PENDING_EXCEPTION->print();
|
||||||
}
|
}
|
||||||
if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
|
if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
|
||||||
|
@ -423,60 +423,6 @@ void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) {
|
|||||||
inline_write_ref_field(field, newVal);
|
inline_write_ref_field(field, newVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Claimed and deferred bits are used together in G1 during the evacuation
|
|
||||||
pause. These bits can have the following state transitions:
|
|
||||||
1. The claimed bit can be put over any other card state. Except that
|
|
||||||
the "dirty -> dirty and claimed" transition is checked for in
|
|
||||||
G1 code and is not used.
|
|
||||||
2. Deferred bit can be set only if the previous state of the card
|
|
||||||
was either clean or claimed. mark_card_deferred() is wait-free.
|
|
||||||
We do not care if the operation is be successful because if
|
|
||||||
it does not it will only result in duplicate entry in the update
|
|
||||||
buffer because of the "cache-miss". So it's not worth spinning.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
bool CardTableModRefBS::claim_card(size_t card_index) {
|
|
||||||
jbyte val = _byte_map[card_index];
|
|
||||||
assert(val != dirty_card_val(), "Shouldn't claim a dirty card");
|
|
||||||
while (val == clean_card_val() ||
|
|
||||||
(val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) {
|
|
||||||
jbyte new_val = val;
|
|
||||||
if (val == clean_card_val()) {
|
|
||||||
new_val = (jbyte)claimed_card_val();
|
|
||||||
} else {
|
|
||||||
new_val = val | (jbyte)claimed_card_val();
|
|
||||||
}
|
|
||||||
jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
|
|
||||||
if (res == val) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
val = res;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CardTableModRefBS::mark_card_deferred(size_t card_index) {
|
|
||||||
jbyte val = _byte_map[card_index];
|
|
||||||
// It's already processed
|
|
||||||
if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Cached bit can be installed either on a clean card or on a claimed card.
|
|
||||||
jbyte new_val = val;
|
|
||||||
if (val == clean_card_val()) {
|
|
||||||
new_val = (jbyte)deferred_card_val();
|
|
||||||
} else {
|
|
||||||
if (val & claimed_card_val()) {
|
|
||||||
new_val = val | (jbyte)deferred_card_val();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (new_val != val) {
|
|
||||||
Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp,
|
void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp,
|
||||||
MemRegion mr,
|
MemRegion mr,
|
||||||
|
@ -339,34 +339,10 @@ public:
|
|||||||
_byte_map[card_index] = dirty_card_val();
|
_byte_map[card_index] = dirty_card_val();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_card_claimed(size_t card_index) {
|
|
||||||
jbyte val = _byte_map[card_index];
|
|
||||||
return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_card_claimed(size_t card_index) {
|
|
||||||
jbyte val = _byte_map[card_index];
|
|
||||||
if (val == clean_card_val()) {
|
|
||||||
val = (jbyte)claimed_card_val();
|
|
||||||
} else {
|
|
||||||
val |= (jbyte)claimed_card_val();
|
|
||||||
}
|
|
||||||
_byte_map[card_index] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool claim_card(size_t card_index);
|
|
||||||
|
|
||||||
bool is_card_clean(size_t card_index) {
|
bool is_card_clean(size_t card_index) {
|
||||||
return _byte_map[card_index] == clean_card_val();
|
return _byte_map[card_index] == clean_card_val();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_card_deferred(size_t card_index) {
|
|
||||||
jbyte val = _byte_map[card_index];
|
|
||||||
return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mark_card_deferred(size_t card_index);
|
|
||||||
|
|
||||||
// Card marking array base (adjusted for heap low boundary)
|
// Card marking array base (adjusted for heap low boundary)
|
||||||
// This would be the 0th element of _byte_map, if the heap started at 0x0.
|
// This would be the 0th element of _byte_map, if the heap started at 0x0.
|
||||||
// But since the heap starts at some higher address, this points to somewhere
|
// But since the heap starts at some higher address, this points to somewhere
|
||||||
|
@ -64,19 +64,21 @@ void CollectorPolicy::initialize_flags() {
|
|||||||
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
|
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) {
|
// Do not use FLAG_SET_ERGO to update MaxMetaspaceSize, since this will
|
||||||
FLAG_SET_ERGO(uintx, MaxMetaspaceSize,
|
// override if MaxMetaspaceSize was set on the command line or not.
|
||||||
restricted_align_down(MaxMetaspaceSize, max_alignment()));
|
// This information is needed later to conform to the specification of the
|
||||||
}
|
// java.lang.management.MemoryUsage API.
|
||||||
|
//
|
||||||
|
// Ideally, we would be able to set the default value of MaxMetaspaceSize in
|
||||||
|
// globals.hpp to the aligned value, but this is not possible, since the
|
||||||
|
// alignment depends on other flags being parsed.
|
||||||
|
MaxMetaspaceSize = restricted_align_down(MaxMetaspaceSize, max_alignment());
|
||||||
|
|
||||||
if (MetaspaceSize > MaxMetaspaceSize) {
|
if (MetaspaceSize > MaxMetaspaceSize) {
|
||||||
FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize);
|
MetaspaceSize = MaxMetaspaceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_size_aligned(MetaspaceSize, min_alignment())) {
|
MetaspaceSize = restricted_align_down(MetaspaceSize, min_alignment());
|
||||||
FLAG_SET_ERGO(uintx, MetaspaceSize,
|
|
||||||
restricted_align_down(MetaspaceSize, min_alignment()));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(MetaspaceSize <= MaxMetaspaceSize, "Must be");
|
assert(MetaspaceSize <= MaxMetaspaceSize, "Must be");
|
||||||
|
|
||||||
@ -135,15 +137,8 @@ bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
|
|||||||
|
|
||||||
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
|
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
|
||||||
int max_covered_regions) {
|
int max_covered_regions) {
|
||||||
switch (rem_set_name()) {
|
assert(rem_set_name() == GenRemSet::CardTable, "unrecognized GenRemSet::Name");
|
||||||
case GenRemSet::CardTable: {
|
return new CardTableRS(whole_heap, max_covered_regions);
|
||||||
CardTableRS* res = new CardTableRS(whole_heap, max_covered_regions);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
guarantee(false, "unrecognized GenRemSet::Name");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectorPolicy::cleared_all_soft_refs() {
|
void CollectorPolicy::cleared_all_soft_refs() {
|
||||||
|
@ -32,13 +32,8 @@
|
|||||||
// enumeration.)
|
// enumeration.)
|
||||||
|
|
||||||
uintx GenRemSet::max_alignment_constraint(Name nm) {
|
uintx GenRemSet::max_alignment_constraint(Name nm) {
|
||||||
switch (nm) {
|
assert(nm == GenRemSet::CardTable, "Unrecognized GenRemSet type.");
|
||||||
case GenRemSet::CardTable:
|
|
||||||
return CardTableRS::ct_max_alignment_constraint();
|
return CardTableRS::ct_max_alignment_constraint();
|
||||||
default:
|
|
||||||
guarantee(false, "Unrecognized GenRemSet type.");
|
|
||||||
return (0); // Make Windows compiler happy
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HasAccumulatedModifiedOopsClosure : public KlassClosure {
|
class HasAccumulatedModifiedOopsClosure : public KlassClosure {
|
||||||
|
@ -150,11 +150,11 @@ public:
|
|||||||
HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD)
|
HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD)
|
||||||
|
|
||||||
static int count(oop x) {
|
static int count(oop x) {
|
||||||
return (HeapWordSize * ((x) ? (x)->size() : 0));
|
return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count_array(objArrayOop x) {
|
static int count_array(objArrayOop x) {
|
||||||
return (HeapWordSize * ((x) ? (x)->size() : 0));
|
return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> static int count(T* x) {
|
template <class T> static int count(T* x) {
|
||||||
|
@ -3104,7 +3104,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) {
|
|||||||
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
|
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
|
||||||
// DumpSharedSpaces doesn't use class metadata area (yet)
|
// DumpSharedSpaces doesn't use class metadata area (yet)
|
||||||
// Also, don't use class_vsm() unless UseCompressedClassPointers is true.
|
// Also, don't use class_vsm() unless UseCompressedClassPointers is true.
|
||||||
if (mdtype == ClassType && using_class_space()) {
|
if (is_class_space_allocation(mdtype)) {
|
||||||
return class_vsm()->allocate(word_size);
|
return class_vsm()->allocate(word_size);
|
||||||
} else {
|
} else {
|
||||||
return vsm()->allocate(word_size);
|
return vsm()->allocate(word_size);
|
||||||
@ -3252,7 +3252,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
|
|||||||
MetaspaceAux::dump(gclog_or_tty);
|
MetaspaceAux::dump(gclog_or_tty);
|
||||||
}
|
}
|
||||||
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
|
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
|
||||||
const char* space_string = (mdtype == ClassType) ? "Compressed class space" :
|
const char* space_string = is_class_space_allocation(mdtype) ? "Compressed class space" :
|
||||||
"Metadata space";
|
"Metadata space";
|
||||||
report_java_out_of_memory(space_string);
|
report_java_out_of_memory(space_string);
|
||||||
|
|
||||||
@ -3261,7 +3261,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
|
|||||||
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
|
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
|
||||||
space_string);
|
space_string);
|
||||||
}
|
}
|
||||||
if (mdtype == ClassType) {
|
if (is_class_space_allocation(mdtype)) {
|
||||||
THROW_OOP_0(Universe::out_of_memory_error_class_metaspace());
|
THROW_OOP_0(Universe::out_of_memory_error_class_metaspace());
|
||||||
} else {
|
} else {
|
||||||
THROW_OOP_0(Universe::out_of_memory_error_metaspace());
|
THROW_OOP_0(Universe::out_of_memory_error_metaspace());
|
||||||
|
@ -235,6 +235,9 @@ class Metaspace : public CHeapObj<mtClass> {
|
|||||||
return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
|
return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_class_space_allocation(MetadataType mdType) {
|
||||||
|
return mdType == ClassType && using_class_space();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MetaspaceAux : AllStatic {
|
class MetaspaceAux : AllStatic {
|
||||||
|
@ -367,7 +367,7 @@ void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
|
|||||||
next_d = java_lang_ref_Reference::discovered(obj);
|
next_d = java_lang_ref_Reference::discovered(obj);
|
||||||
if (TraceReferenceGC && PrintGCDetails) {
|
if (TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
|
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
|
||||||
obj, next_d);
|
(void *)obj, (void *)next_d);
|
||||||
}
|
}
|
||||||
assert(java_lang_ref_Reference::next(obj) == NULL,
|
assert(java_lang_ref_Reference::next(obj) == NULL,
|
||||||
"Reference not active; should not be discovered");
|
"Reference not active; should not be discovered");
|
||||||
@ -392,7 +392,7 @@ void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
|
|||||||
next_d = java_lang_ref_Reference::discovered(obj);
|
next_d = java_lang_ref_Reference::discovered(obj);
|
||||||
if (TraceReferenceGC && PrintGCDetails) {
|
if (TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
|
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
|
||||||
obj, next_d);
|
(void *)obj, (void *)next_d);
|
||||||
}
|
}
|
||||||
assert(java_lang_ref_Reference::next(obj) == NULL,
|
assert(java_lang_ref_Reference::next(obj) == NULL,
|
||||||
"The reference should not be enqueued");
|
"The reference should not be enqueued");
|
||||||
@ -562,7 +562,7 @@ ReferenceProcessor::process_phase1(DiscoveredList& refs_list,
|
|||||||
!policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
|
!policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy",
|
gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy",
|
||||||
iter.obj(), iter.obj()->klass()->internal_name());
|
(void *)iter.obj(), iter.obj()->klass()->internal_name());
|
||||||
}
|
}
|
||||||
// Remove Reference object from list
|
// Remove Reference object from list
|
||||||
iter.remove();
|
iter.remove();
|
||||||
@ -601,7 +601,7 @@ ReferenceProcessor::pp2_work(DiscoveredList& refs_list,
|
|||||||
if (iter.is_referent_alive()) {
|
if (iter.is_referent_alive()) {
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
|
gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
|
||||||
iter.obj(), iter.obj()->klass()->internal_name());
|
(void *)iter.obj(), iter.obj()->klass()->internal_name());
|
||||||
}
|
}
|
||||||
// The referent is reachable after all.
|
// The referent is reachable after all.
|
||||||
// Remove Reference object from list.
|
// Remove Reference object from list.
|
||||||
@ -687,7 +687,7 @@ ReferenceProcessor::process_phase3(DiscoveredList& refs_list,
|
|||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
|
gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
|
||||||
clear_referent ? "cleared " : "",
|
clear_referent ? "cleared " : "",
|
||||||
iter.obj(), iter.obj()->klass()->internal_name());
|
(void *)iter.obj(), iter.obj()->klass()->internal_name());
|
||||||
}
|
}
|
||||||
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
|
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
|
||||||
iter.next();
|
iter.next();
|
||||||
@ -1003,7 +1003,7 @@ void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list)
|
|||||||
gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
|
gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
|
||||||
INTPTR_FORMAT " with next field: " INTPTR_FORMAT
|
INTPTR_FORMAT " with next field: " INTPTR_FORMAT
|
||||||
" and referent: " INTPTR_FORMAT,
|
" and referent: " INTPTR_FORMAT,
|
||||||
iter.obj(), next, iter.referent());
|
(void *)iter.obj(), (void *)next, (void *)iter.referent());
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// Remove Reference object from list
|
// Remove Reference object from list
|
||||||
@ -1103,14 +1103,14 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
|
|||||||
|
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
|
gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
|
||||||
obj, obj->klass()->internal_name());
|
(void *)obj, obj->klass()->internal_name());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If retest was non NULL, another thread beat us to it:
|
// If retest was non NULL, another thread beat us to it:
|
||||||
// The reference has already been discovered...
|
// The reference has already been discovered...
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
|
gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
|
||||||
obj, obj->klass()->internal_name());
|
(void *)obj, obj->klass()->internal_name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1125,7 +1125,7 @@ void ReferenceProcessor::verify_referent(oop obj) {
|
|||||||
assert(da ? referent->is_oop() : referent->is_oop_or_null(),
|
assert(da ? referent->is_oop() : referent->is_oop_or_null(),
|
||||||
err_msg("Bad referent " INTPTR_FORMAT " found in Reference "
|
err_msg("Bad referent " INTPTR_FORMAT " found in Reference "
|
||||||
INTPTR_FORMAT " during %satomic discovery ",
|
INTPTR_FORMAT " during %satomic discovery ",
|
||||||
(intptr_t)referent, (intptr_t)obj, da ? "" : "non-"));
|
(void *)referent, (void *)obj, da ? "" : "non-"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1205,7 +1205,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
|||||||
// The reference has already been discovered...
|
// The reference has already been discovered...
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
|
gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
|
||||||
obj, obj->klass()->internal_name());
|
(void *)obj, obj->klass()->internal_name());
|
||||||
}
|
}
|
||||||
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
|
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
|
||||||
// assumes that an object is not processed twice;
|
// assumes that an object is not processed twice;
|
||||||
@ -1273,7 +1273,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
|||||||
|
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
|
gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
|
||||||
obj, obj->klass()->internal_name());
|
(void *)obj, obj->klass()->internal_name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(obj->is_oop(), "Discovered a bad reference");
|
assert(obj->is_oop(), "Discovered a bad reference");
|
||||||
@ -1372,7 +1372,7 @@ ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list,
|
|||||||
// active; we need to trace and mark its cohort.
|
// active; we need to trace and mark its cohort.
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)",
|
gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)",
|
||||||
iter.obj(), iter.obj()->klass()->internal_name());
|
(void *)iter.obj(), iter.obj()->klass()->internal_name());
|
||||||
}
|
}
|
||||||
// Remove Reference object from list
|
// Remove Reference object from list
|
||||||
iter.remove();
|
iter.remove();
|
||||||
|
@ -1918,7 +1918,7 @@ void ConstantPool::print_on(outputStream* st) const {
|
|||||||
st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder());
|
st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder());
|
||||||
}
|
}
|
||||||
st->print_cr(" - cache: " INTPTR_FORMAT, cache());
|
st->print_cr(" - cache: " INTPTR_FORMAT, cache());
|
||||||
st->print_cr(" - resolved_references: " INTPTR_FORMAT, resolved_references());
|
st->print_cr(" - resolved_references: " INTPTR_FORMAT, (void *)resolved_references());
|
||||||
st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map());
|
st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map());
|
||||||
|
|
||||||
for (int index = 1; index < length(); index++) { // Index 0 is unused
|
for (int index = 1; index < length(); index++) { // Index 0 is unused
|
||||||
|
@ -306,8 +306,8 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
|
|||||||
if (TraceInvokeDynamic) {
|
if (TraceInvokeDynamic) {
|
||||||
tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
|
tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
|
||||||
invoke_code,
|
invoke_code,
|
||||||
(intptr_t)appendix(), (has_appendix ? "" : " (unused)"),
|
(void *)appendix(), (has_appendix ? "" : " (unused)"),
|
||||||
(intptr_t)method_type(), (has_method_type ? "" : " (unused)"),
|
(void *)method_type(), (has_method_type ? "" : " (unused)"),
|
||||||
(intptr_t)adapter());
|
(intptr_t)adapter());
|
||||||
adapter->print();
|
adapter->print();
|
||||||
if (has_appendix) appendix()->print();
|
if (has_appendix) appendix()->print();
|
||||||
|
@ -106,7 +106,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
|
|||||||
len = name->utf8_length(); \
|
len = name->utf8_length(); \
|
||||||
} \
|
} \
|
||||||
HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \
|
HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \
|
||||||
data, len, (clss)->class_loader(), thread_type); \
|
data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
|
#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
|
||||||
@ -119,7 +119,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
|
|||||||
len = name->utf8_length(); \
|
len = name->utf8_length(); \
|
||||||
} \
|
} \
|
||||||
HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \
|
HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \
|
||||||
data, len, (clss)->class_loader(), thread_type, wait); \
|
data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type, wait); \
|
||||||
}
|
}
|
||||||
#else /* USDT2 */
|
#else /* USDT2 */
|
||||||
|
|
||||||
@ -1419,6 +1419,8 @@ Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lookup a method in all the interfaces that this class implements
|
// lookup a method in all the interfaces that this class implements
|
||||||
|
// Do NOT return private or static methods, new in JDK8 which are not externally visible
|
||||||
|
// They should only be found in the initial InterfaceMethodRef
|
||||||
Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
||||||
Symbol* signature) const {
|
Symbol* signature) const {
|
||||||
Array<Klass*>* all_ifs = transitive_interfaces();
|
Array<Klass*>* all_ifs = transitive_interfaces();
|
||||||
@ -1427,7 +1429,7 @@ Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
|||||||
for (int i = 0; i < num_ifs; i++) {
|
for (int i = 0; i < num_ifs; i++) {
|
||||||
ik = InstanceKlass::cast(all_ifs->at(i));
|
ik = InstanceKlass::cast(all_ifs->at(i));
|
||||||
Method* m = ik->lookup_method(name, signature);
|
Method* m = ik->lookup_method(name, signature);
|
||||||
if (m != NULL) {
|
if (m != NULL && m->is_public() && !m->is_static()) {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2303,7 +2305,7 @@ void InstanceKlass::set_source_debug_extension(char* array, int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
address InstanceKlass::static_field_addr(int offset) {
|
address InstanceKlass::static_field_addr(int offset) {
|
||||||
return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + (intptr_t)java_mirror());
|
return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + cast_from_oop<intptr_t>(java_mirror()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -66,7 +66,7 @@ class InstanceMirrorKlass: public InstanceKlass {
|
|||||||
// Static field offset is an offset into the Heap, should be converted by
|
// Static field offset is an offset into the Heap, should be converted by
|
||||||
// based on UseCompressedOop for traversal
|
// based on UseCompressedOop for traversal
|
||||||
static HeapWord* start_of_static_fields(oop obj) {
|
static HeapWord* start_of_static_fields(oop obj) {
|
||||||
return (HeapWord*)((intptr_t)obj + offset_of_static_fields());
|
return (HeapWord*)(cast_from_oop<intptr_t>(obj) + offset_of_static_fields());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_offset_of_static_fields() {
|
static void init_offset_of_static_fields() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -51,7 +51,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
|
|||||||
T heap_oop = oopDesc::load_heap_oop(referent_addr);
|
T heap_oop = oopDesc::load_heap_oop(referent_addr);
|
||||||
debug_only(
|
debug_only(
|
||||||
if(TraceReferenceGC && PrintGCDetails) {
|
if(TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj);
|
gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (!oopDesc::is_null(heap_oop)) {
|
if (!oopDesc::is_null(heap_oop)) {
|
||||||
@ -62,7 +62,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
|
|||||||
ref->InstanceKlass::oop_follow_contents(obj);
|
ref->InstanceKlass::oop_follow_contents(obj);
|
||||||
debug_only(
|
debug_only(
|
||||||
if(TraceReferenceGC && PrintGCDetails) {
|
if(TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj);
|
gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
@ -70,7 +70,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
|
|||||||
// treat referent as normal oop
|
// treat referent as normal oop
|
||||||
debug_only(
|
debug_only(
|
||||||
if(TraceReferenceGC && PrintGCDetails) {
|
if(TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, obj);
|
gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, (void *)obj);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
MarkSweep::mark_and_push(referent_addr);
|
MarkSweep::mark_and_push(referent_addr);
|
||||||
@ -130,7 +130,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref,
|
|||||||
T heap_oop = oopDesc::load_heap_oop(referent_addr);
|
T heap_oop = oopDesc::load_heap_oop(referent_addr);
|
||||||
debug_only(
|
debug_only(
|
||||||
if(TraceReferenceGC && PrintGCDetails) {
|
if(TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj);
|
gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (!oopDesc::is_null(heap_oop)) {
|
if (!oopDesc::is_null(heap_oop)) {
|
||||||
@ -142,7 +142,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref,
|
|||||||
ref->InstanceKlass::oop_follow_contents(cm, obj);
|
ref->InstanceKlass::oop_follow_contents(cm, obj);
|
||||||
debug_only(
|
debug_only(
|
||||||
if(TraceReferenceGC && PrintGCDetails) {
|
if(TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj);
|
gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
@ -150,7 +150,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref,
|
|||||||
// treat referent as normal oop
|
// treat referent as normal oop
|
||||||
debug_only(
|
debug_only(
|
||||||
if(TraceReferenceGC && PrintGCDetails) {
|
if(TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, obj);
|
gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, (void *)obj);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
PSParallelCompact::mark_and_push(cm, referent_addr);
|
PSParallelCompact::mark_and_push(cm, referent_addr);
|
||||||
|
@ -292,9 +292,10 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
|
|||||||
return allocate_new;
|
return allocate_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private methods always have a new entry in the vtable
|
// private methods in classes always have a new entry in the vtable
|
||||||
// specification interpretation since classic has
|
// specification interpretation since classic has
|
||||||
// private methods not overriding
|
// private methods not overriding
|
||||||
|
// JDK8 adds private methods in interfaces which require invokespecial
|
||||||
if (target_method()->is_private()) {
|
if (target_method()->is_private()) {
|
||||||
return allocate_new;
|
return allocate_new;
|
||||||
}
|
}
|
||||||
@ -442,9 +443,10 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private methods always have a new entry in the vtable
|
// private methods in classes always have a new entry in the vtable
|
||||||
// specification interpretation since classic has
|
// specification interpretation since classic has
|
||||||
// private methods not overriding
|
// private methods not overriding
|
||||||
|
// JDK8 adds private methods in interfaces which require invokespecial
|
||||||
if (target_method()->is_private()) {
|
if (target_method()->is_private()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -520,7 +522,7 @@ bool klassVtable::is_miranda_entry_at(int i) {
|
|||||||
Klass* method_holder = m->method_holder();
|
Klass* method_holder = m->method_holder();
|
||||||
InstanceKlass *mhk = InstanceKlass::cast(method_holder);
|
InstanceKlass *mhk = InstanceKlass::cast(method_holder);
|
||||||
|
|
||||||
// miranda methods are interface methods in a class's vtable
|
// miranda methods are public abstract instance interface methods in a class's vtable
|
||||||
if (mhk->is_interface()) {
|
if (mhk->is_interface()) {
|
||||||
assert(m->is_public(), "should be public");
|
assert(m->is_public(), "should be public");
|
||||||
assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
|
assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
|
||||||
@ -534,6 +536,8 @@ bool klassVtable::is_miranda_entry_at(int i) {
|
|||||||
// "miranda" means not static, not defined by this class, and not defined
|
// "miranda" means not static, not defined by this class, and not defined
|
||||||
// in super unless it is private and therefore inaccessible to this class.
|
// in super unless it is private and therefore inaccessible to this class.
|
||||||
// the caller must make sure that the method belongs to an interface implemented by the class
|
// the caller must make sure that the method belongs to an interface implemented by the class
|
||||||
|
// Miranda methods only include public interface instance methods
|
||||||
|
// Not private methods, not static methods, not default = concrete abstract
|
||||||
bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
|
bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
|
||||||
if (m->is_static()) {
|
if (m->is_static()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -901,16 +901,6 @@ address Method::make_adapters(methodHandle mh, TRAPS) {
|
|||||||
// This function must not hit a safepoint!
|
// This function must not hit a safepoint!
|
||||||
address Method::verified_code_entry() {
|
address Method::verified_code_entry() {
|
||||||
debug_only(No_Safepoint_Verifier nsv;)
|
debug_only(No_Safepoint_Verifier nsv;)
|
||||||
nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
|
|
||||||
if (code == NULL && UseCodeCacheFlushing) {
|
|
||||||
nmethod *saved_code = CodeCache::reanimate_saved_code(this);
|
|
||||||
if (saved_code != NULL) {
|
|
||||||
methodHandle method(this);
|
|
||||||
assert( ! saved_code->is_osr_method(), "should not get here for osr" );
|
|
||||||
set_code( method, saved_code );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(_from_compiled_entry != NULL, "must be set");
|
assert(_from_compiled_entry != NULL, "must be set");
|
||||||
return _from_compiled_entry;
|
return _from_compiled_entry;
|
||||||
}
|
}
|
||||||
|
@ -333,10 +333,10 @@ protected:
|
|||||||
return (int)data()->cell_at(index);
|
return (int)data()->cell_at(index);
|
||||||
}
|
}
|
||||||
void set_oop_at(int index, oop value) {
|
void set_oop_at(int index, oop value) {
|
||||||
set_intptr_at(index, (intptr_t) value);
|
set_intptr_at(index, cast_from_oop<intptr_t>(value));
|
||||||
}
|
}
|
||||||
oop oop_at(int index) {
|
oop oop_at(int index) {
|
||||||
return (oop)intptr_at(index);
|
return cast_to_oop(intptr_at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_flag_at(int flag_number) {
|
void set_flag_at(int flag_number) {
|
||||||
|
@ -183,7 +183,7 @@ inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
|
|||||||
// in inner GC loops so these are separated.
|
// in inner GC loops so these are separated.
|
||||||
|
|
||||||
inline bool check_obj_alignment(oop obj) {
|
inline bool check_obj_alignment(oop obj) {
|
||||||
return (intptr_t)obj % MinObjAlignmentInBytes == 0;
|
return cast_from_oop<intptr_t>(obj) % MinObjAlignmentInBytes == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
|
inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
|
||||||
|
@ -55,11 +55,16 @@ typedef class typeArrayOopDesc* typeArrayOop;
|
|||||||
// to and from the underlying oopDesc pointer type.
|
// to and from the underlying oopDesc pointer type.
|
||||||
//
|
//
|
||||||
// Because oop and its subclasses <type>Oop are class types, arbitrary
|
// Because oop and its subclasses <type>Oop are class types, arbitrary
|
||||||
// conversions are not accepted by the compiler, and you may get a message
|
// conversions are not accepted by the compiler. Applying a cast to
|
||||||
// about overloading ambiguity (between long and int is common when converting
|
// an oop will cause the best matched conversion operator to be
|
||||||
// from a constant in 64 bit mode), or unable to convert from type to 'oop'.
|
// invoked returning the underlying oopDesc* type if appropriate.
|
||||||
// Applying a cast to one of these conversion operators first will get to the
|
// No copy constructors, explicit user conversions or operators of
|
||||||
// underlying oopDesc* type if appropriate.
|
// numerical type should be defined within the oop class. Most C++
|
||||||
|
// compilers will issue a compile time error concerning the overloading
|
||||||
|
// ambiguity between operators of numerical and pointer types. If
|
||||||
|
// a conversion to or from an oop to a numerical type is needed,
|
||||||
|
// use the inline template methods, cast_*_oop, defined below.
|
||||||
|
//
|
||||||
// Converting NULL to oop to Handle implicit is no longer accepted by the
|
// Converting NULL to oop to Handle implicit is no longer accepted by the
|
||||||
// compiler because there are too many steps in the conversion. Use Handle()
|
// compiler because there are too many steps in the conversion. Use Handle()
|
||||||
// instead, which generates less code anyway.
|
// instead, which generates less code anyway.
|
||||||
@ -83,12 +88,9 @@ public:
|
|||||||
void raw_set_obj(const void* p) { _o = (oopDesc*)p; }
|
void raw_set_obj(const void* p) { _o = (oopDesc*)p; }
|
||||||
|
|
||||||
oop() { set_obj(NULL); }
|
oop() { set_obj(NULL); }
|
||||||
|
oop(const oop& o) { set_obj(o.obj()); }
|
||||||
oop(const volatile oop& o) { set_obj(o.obj()); }
|
oop(const volatile oop& o) { set_obj(o.obj()); }
|
||||||
oop(const void* p) { set_obj(p); }
|
oop(const void* p) { set_obj(p); }
|
||||||
oop(intptr_t i) { set_obj((void *)i); }
|
|
||||||
#ifdef _LP64
|
|
||||||
oop(int i) { set_obj((void *)i); }
|
|
||||||
#endif
|
|
||||||
~oop() {
|
~oop() {
|
||||||
if (CheckUnhandledOops) unregister_oop();
|
if (CheckUnhandledOops) unregister_oop();
|
||||||
}
|
}
|
||||||
@ -101,8 +103,6 @@ public:
|
|||||||
bool operator==(void *p) const { return obj() == p; }
|
bool operator==(void *p) const { return obj() == p; }
|
||||||
bool operator!=(const volatile oop o) const { return obj() != o.obj(); }
|
bool operator!=(const volatile oop o) const { return obj() != o.obj(); }
|
||||||
bool operator!=(void *p) const { return obj() != p; }
|
bool operator!=(void *p) const { return obj() != p; }
|
||||||
bool operator==(intptr_t p) const { return obj() == (oopDesc*)p; }
|
|
||||||
bool operator!=(intptr_t p) const { return obj() != (oopDesc*)p; }
|
|
||||||
|
|
||||||
bool operator<(oop o) const { return obj() < o.obj(); }
|
bool operator<(oop o) const { return obj() < o.obj(); }
|
||||||
bool operator>(oop o) const { return obj() > o.obj(); }
|
bool operator>(oop o) const { return obj() > o.obj(); }
|
||||||
@ -110,8 +110,18 @@ public:
|
|||||||
bool operator>=(oop o) const { return obj() >= o.obj(); }
|
bool operator>=(oop o) const { return obj() >= o.obj(); }
|
||||||
bool operator!() const { return !obj(); }
|
bool operator!() const { return !obj(); }
|
||||||
|
|
||||||
// Cast
|
// Assignment
|
||||||
|
oop& operator=(const oop& o) { _o = o.obj(); return *this; }
|
||||||
|
#ifndef SOLARIS
|
||||||
|
volatile oop& operator=(const oop& o) volatile { _o = o.obj(); return *this; }
|
||||||
|
#endif
|
||||||
|
volatile oop& operator=(const volatile oop& o) volatile { _o = o.obj(); return *this; }
|
||||||
|
|
||||||
|
// Explict user conversions
|
||||||
operator void* () const { return (void *)obj(); }
|
operator void* () const { return (void *)obj(); }
|
||||||
|
#ifndef SOLARIS
|
||||||
|
operator void* () const volatile { return (void *)obj(); }
|
||||||
|
#endif
|
||||||
operator HeapWord* () const { return (HeapWord*)obj(); }
|
operator HeapWord* () const { return (HeapWord*)obj(); }
|
||||||
operator oopDesc* () const { return obj(); }
|
operator oopDesc* () const { return obj(); }
|
||||||
operator intptr_t* () const { return (intptr_t*)obj(); }
|
operator intptr_t* () const { return (intptr_t*)obj(); }
|
||||||
@ -119,7 +129,6 @@ public:
|
|||||||
operator markOop () const { return markOop(obj()); }
|
operator markOop () const { return markOop(obj()); }
|
||||||
|
|
||||||
operator address () const { return (address)obj(); }
|
operator address () const { return (address)obj(); }
|
||||||
operator intptr_t () const volatile { return (intptr_t)obj(); }
|
|
||||||
|
|
||||||
// from javaCalls.cpp
|
// from javaCalls.cpp
|
||||||
operator jobject () const { return (jobject)obj(); }
|
operator jobject () const { return (jobject)obj(); }
|
||||||
@ -141,12 +150,26 @@ public:
|
|||||||
class type##Oop : public oop { \
|
class type##Oop : public oop { \
|
||||||
public: \
|
public: \
|
||||||
type##Oop() : oop() {} \
|
type##Oop() : oop() {} \
|
||||||
|
type##Oop(const oop& o) : oop(o) {} \
|
||||||
type##Oop(const volatile oop& o) : oop(o) {} \
|
type##Oop(const volatile oop& o) : oop(o) {} \
|
||||||
type##Oop(const void* p) : oop(p) {} \
|
type##Oop(const void* p) : oop(p) {} \
|
||||||
operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \
|
operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \
|
||||||
type##OopDesc* operator->() const { \
|
type##OopDesc* operator->() const { \
|
||||||
return (type##OopDesc*)obj(); \
|
return (type##OopDesc*)obj(); \
|
||||||
} \
|
} \
|
||||||
|
type##Oop& operator=(const type##Oop& o) { \
|
||||||
|
oop::operator=(o); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
NOT_SOLARIS( \
|
||||||
|
volatile type##Oop& operator=(const type##Oop& o) volatile { \
|
||||||
|
(void)const_cast<oop&>(oop::operator=(o)); \
|
||||||
|
return *this; \
|
||||||
|
}) \
|
||||||
|
volatile type##Oop& operator=(const volatile type##Oop& o) volatile {\
|
||||||
|
(void)const_cast<oop&>(oop::operator=(o)); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
};
|
};
|
||||||
|
|
||||||
DEF_OOP(instance);
|
DEF_OOP(instance);
|
||||||
@ -156,6 +179,16 @@ DEF_OOP(typeArray);
|
|||||||
|
|
||||||
#endif // CHECK_UNHANDLED_OOPS
|
#endif // CHECK_UNHANDLED_OOPS
|
||||||
|
|
||||||
|
// For CHECK_UNHANDLED_OOPS, it is ambiguous C++ behavior to have the oop
|
||||||
|
// structure contain explicit user defined conversions of both numerical
|
||||||
|
// and pointer type. Define inline methods to provide the numerical conversions.
|
||||||
|
template <class T> inline oop cast_to_oop(T value) {
|
||||||
|
return (oop)(CHECK_UNHANDLED_OOPS_ONLY((void *))(value));
|
||||||
|
}
|
||||||
|
template <class T> inline T cast_from_oop(oop o) {
|
||||||
|
return (T)(CHECK_UNHANDLED_OOPS_ONLY((void*))o);
|
||||||
|
}
|
||||||
|
|
||||||
// The metadata hierarchy is separate from the oop hierarchy
|
// The metadata hierarchy is separate from the oop hierarchy
|
||||||
|
|
||||||
// class MetaspaceObj
|
// class MetaspaceObj
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user