--- a/hotspot/agent/src/os/linux/ps_proc.c Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/agent/src/os/linux/ps_proc.c Fri Jun 13 19:07:11 2014 -0700
@@ -263,7 +263,7 @@
static bool read_lib_info(struct ps_prochandle* ph) {
char fname[32];
- char buf[256];
+ char buf[PATH_MAX];
FILE *fp = NULL;
sprintf(fname, "/proc/%d/maps", ph->pid);
@@ -273,10 +273,41 @@
return false;
}
- while(fgets_no_cr(buf, 256, fp)){
- char * word[6];
- int nwords = split_n_str(buf, 6, word, ' ', '\0');
- if (nwords > 5 && find_lib(ph, word[5]) == false) {
+ while(fgets_no_cr(buf, PATH_MAX, fp)){
+ char * word[7];
+ int nwords = split_n_str(buf, 7, word, ' ', '\0');
+
+ if (nwords < 6) {
+ // not a shared library entry. ignore.
+ continue;
+ }
+
+ // SA does not handle the lines with patterns:
+ // "[stack]", "[heap]", "[vdso]", "[vsyscall]", etc.
+ if (word[5][0] == '[') {
+ // not a shared library entry. ignore.
+ continue;
+ }
+
+ if (nwords > 6) {
+ // prelink altered mapfile when the program is running.
+ // Entries like one below have to be skipped
+ // /lib64/libc-2.15.so (deleted)
+ // SO name in entries like one below have to be stripped.
+ // /lib64/libpthread-2.15.so.#prelink#.EECVts
+ char *s = strstr(word[5],".#prelink#");
+ if (s == NULL) {
+ // No prelink keyword. skip deleted library
+ print_debug("skip shared object %s deleted by prelink\n", word[5]);
+ continue;
+ }
+
+ // Fall through
+ print_debug("rectifying shared object name %s changed by prelink\n", word[5]);
+ *s = 0;
+ }
+
+ if (find_lib(ph, word[5]) == false) {
intptr_t base;
lib_info* lib;
#ifdef _LP64
--- a/hotspot/make/bsd/makefiles/vm.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/bsd/makefiles/vm.make Fri Jun 13 19:07:11 2014 -0700
@@ -295,6 +295,7 @@
$(PRECOMPILED_HEADER):
$(QUIETLY) echo Generating precompiled header $@
$(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR)
+ $(QUIETLY) rm -f $@
$(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE)
# making the library:
--- a/hotspot/make/linux/makefiles/vm.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/linux/makefiles/vm.make Fri Jun 13 19:07:11 2014 -0700
@@ -290,6 +290,7 @@
$(PRECOMPILED_HEADER):
$(QUIETLY) echo Generating precompiled header $@
$(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR)
+ $(QUIETLY) rm -f $@
$(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE)
# making the library:
--- a/hotspot/make/windows/create.bat Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/create.bat Fri Jun 13 19:07:11 2014 -0700
@@ -1,6 +1,6 @@
@echo off
REM
-REM Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+REM Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
REM
REM This code is free software; you can redistribute it and/or modify it
@@ -81,33 +81,8 @@
for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
echo **************************************************************
-set ProjectFile=%HotSpotBuildSpace%\jvm.vcproj
echo MSC_VER = "%MSC_VER%"
-if "%MSC_VER%" == "1200" (
-set ProjectFile=%HotSpotBuildSpace%\jvm.dsp
-echo Will generate VC6 project {unsupported}
-) else (
-if "%MSC_VER%" == "1400" (
-echo Will generate VC8 {Visual Studio 2005}
-) else (
-if "%MSC_VER%" == "1500" (
-echo Will generate VC9 {Visual Studio 2008}
-) else (
-if "%MSC_VER%" == "1600" (
-echo Will generate VC10 {Visual Studio 2010}
set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
-) else (
-if "%MSC_VER%" == "1700" (
-echo Will generate VC10 {compatible with Visual Studio 2012}
-echo After opening in VS 2012, click "Update" when prompted.
-set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
-) else (
-echo Will generate VC7 project {Visual Studio 2003 .NET}
-)
-)
-)
-)
-)
echo %ProjectFile%
echo **************************************************************
--- a/hotspot/make/windows/makefiles/compile.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/makefiles/compile.make Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -63,28 +63,20 @@
# Based on BUILDARCH we add some flags and select the default compiler name
!if "$(BUILDARCH)" == "ia64"
MACHINE=IA64
-DEFAULT_COMPILER_NAME=VS2003
CXX_FLAGS=$(CXX_FLAGS) /D "CC_INTERP" /D "_LP64" /D "IA64"
!endif
!if "$(BUILDARCH)" == "amd64"
MACHINE=AMD64
-DEFAULT_COMPILER_NAME=VS2005
CXX_FLAGS=$(CXX_FLAGS) /D "_LP64" /D "AMD64"
LP64=1
!endif
!if "$(BUILDARCH)" == "i486"
MACHINE=I386
-DEFAULT_COMPILER_NAME=VS2003
CXX_FLAGS=$(CXX_FLAGS) /D "IA32"
!endif
-# Sanity check, this is the default if not amd64, ia64, or i486
-!ifndef DEFAULT_COMPILER_NAME
-CXX=ARCH_ERROR
-!endif
-
CXX_FLAGS=$(CXX_FLAGS) /D "WIN32" /D "_WINDOWS"
# Must specify this for sharedRuntimeTrig.cpp
CXX_FLAGS=$(CXX_FLAGS) /D "VM_LITTLE_ENDIAN"
@@ -112,6 +104,7 @@
# 1500 is for VS2008
# 1600 is for VS2010
# 1700 is for VS2012
+# 1800 is for VS2013
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
# Normally they are the same, but a pre-release of the VS2005 compilers
@@ -119,35 +112,6 @@
# closer to VS2003 in terms of option spellings, so we use 1399 for that
# 1400 version that really isn't 1400.
# See the file get_msc_ver.sh for more info.
-!if "x$(MSC_VER)" == "x"
-COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
-!else
-!if "$(MSC_VER)" == "1200"
-COMPILER_NAME=VC6
-!endif
-!if "$(MSC_VER)" == "1300"
-COMPILER_NAME=VS2003
-!endif
-!if "$(MSC_VER)" == "1310"
-COMPILER_NAME=VS2003
-!endif
-!if "$(MSC_VER)" == "1399"
-# Compiler might say 1400, but if it's 14.00.30701, it isn't really VS2005
-COMPILER_NAME=VS2003
-!endif
-!if "$(MSC_VER)" == "1400"
-COMPILER_NAME=VS2005
-!endif
-!if "$(MSC_VER)" == "1500"
-COMPILER_NAME=VS2008
-!endif
-!if "$(MSC_VER)" == "1600"
-COMPILER_NAME=VS2010
-!endif
-!if "$(MSC_VER)" == "1700"
-COMPILER_NAME=VS2012
-!endif
-!endif
# By default, we do not want to use the debug version of the msvcrt.dll file
# but if MFC_DEBUG is defined in the environment it will be used.
@@ -165,60 +129,6 @@
!endif
CXX_FLAGS=$(CXX_FLAGS) $(MS_RUNTIME_OPTION)
-# How /GX option is spelled
-GX_OPTION = /GX
-
-# Optimization settings for various versions of the compilers and types of
-# builds. Three basic sets of settings: product, fastdebug, and debug.
-# These get added into CXX_FLAGS as needed by other makefiles.
-!if "$(COMPILER_NAME)" == "VC6"
-PRODUCT_OPT_OPTION = /Ox /Os /Gy /GF
-FASTDEBUG_OPT_OPTION = /Ox /Os /Gy /GF
-DEBUG_OPT_OPTION = /Od
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2003"
-PRODUCT_OPT_OPTION = /O2 /Oy-
-FASTDEBUG_OPT_OPTION = /O2 /Oy-
-DEBUG_OPT_OPTION = /Od
-SAFESEH_FLAG = /SAFESEH
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2005"
-PRODUCT_OPT_OPTION = /O2 /Oy-
-FASTDEBUG_OPT_OPTION = /O2 /Oy-
-DEBUG_OPT_OPTION = /Od
-GX_OPTION = /EHsc
-# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
-# on the link command line, otherwise we get missing __security_check_cookie
-# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
-# NOTE: Currently we decided to not use /GS-
-BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB)
-# Manifest Tool - used in VS2005 and later to adjust manifests stored
-# as resources inside build artifacts.
-!if "x$(MT)" == "x"
-MT=mt.exe
-!endif
-SAFESEH_FLAG = /SAFESEH
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2008"
-PRODUCT_OPT_OPTION = /O2 /Oy-
-FASTDEBUG_OPT_OPTION = /O2 /Oy-
-DEBUG_OPT_OPTION = /Od
-GX_OPTION = /EHsc
-LD_FLAGS = /manifest $(LD_FLAGS)
-MP_FLAG = /MP
-# Manifest Tool - used in VS2005 and later to adjust manifests stored
-# as resources inside build artifacts.
-!if "x$(MT)" == "x"
-MT=mt.exe
-!endif
-SAFESEH_FLAG = /SAFESEH
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2010"
PRODUCT_OPT_OPTION = /O2 /Oy-
FASTDEBUG_OPT_OPTION = /O2 /Oy-
DEBUG_OPT_OPTION = /Od
@@ -233,26 +143,6 @@
!if "$(BUILDARCH)" == "i486"
LD_FLAGS = /SAFESEH $(LD_FLAGS)
!endif
-!endif
-
-!if "$(COMPILER_NAME)" == "VS2012"
-PRODUCT_OPT_OPTION = /O2 /Oy-
-FASTDEBUG_OPT_OPTION = /O2 /Oy-
-DEBUG_OPT_OPTION = /Od
-GX_OPTION = /EHsc
-LD_FLAGS = /manifest $(LD_FLAGS)
-MP_FLAG = /MP
-# Manifest Tool - used in VS2005 and later to adjust manifests stored
-# as resources inside build artifacts.
-!if "x$(MT)" == "x"
-MT=mt.exe
-!endif
-SAFESEH_FLAG = /SAFESEH
-!endif
-
-!if "$(BUILDARCH)" == "i486"
-LD_FLAGS = $(SAFESEH_FLAG) $(LD_FLAGS)
-!endif
CXX_FLAGS = $(CXX_FLAGS) $(MP_FLAG)
--- a/hotspot/make/windows/makefiles/rules.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/makefiles/rules.make Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -49,35 +49,8 @@
JAVAC_FLAGS=-g -encoding ascii
BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
-ProjectFile=jvm.vcproj
-
-!if "$(MSC_VER)" == "1200"
-
-VcVersion=VC6
-ProjectFile=jvm.dsp
-
-!elseif "$(MSC_VER)" == "1400"
-
-VcVersion=VC8
-
-!elseif "$(MSC_VER)" == "1500"
-
-VcVersion=VC9
-
-!elseif "$(MSC_VER)" == "1600"
-
+# VS2012 and VS2013 loads VS10 projects just fine (and will
+# upgrade them automatically to VS2012 format).
VcVersion=VC10
ProjectFile=jvm.vcxproj
-!elseif "$(MSC_VER)" == "1700"
-# This is VS2012, but it loads VS10 projects just fine (and will
-# upgrade them automatically to VS2012 format).
-
-VcVersion=VC10
-ProjectFile=jvm.vcxproj
-
-!else
-
-VcVersion=VC7
-
-!endif
--- a/hotspot/make/windows/makefiles/sa.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/makefiles/sa.make Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -85,14 +85,9 @@
# will be useful to have the assertion checks in place
!if "$(BUILDARCH)" == "ia64"
-SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c
+SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -FD -c
!elseif "$(BUILDARCH)" == "amd64"
-SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c
-!if "$(COMPILER_NAME)" == "VS2005"
-# On amd64, VS2005 compiler requires bufferoverflowU.lib on the link command line,
-# otherwise we get missing __security_check_cookie externals at link time.
-SA_LD_FLAGS = bufferoverflowU.lib
-!endif
+SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -FD -c
!else
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -FD -RTC1 -c
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
--- a/hotspot/make/windows/makefiles/sanity.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/makefiles/sanity.make Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,9 @@
all: checkCL checkLink
checkCL:
- @ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" if "$(MSC_VER)" NEQ "1600" if "$(MSC_VER)" NEQ "1700" \
- echo *** WARNING *** unrecognized cl.exe version $(MSC_VER) ($(RAW_MSC_VER)). Use FORCE_MSC_VER to override automatic detection.
+ @ if "$(MSC_VER)" NEQ "1600" if "$(MSC_VER)" NEQ "1700" if "$(MSC_VER)" NEQ "1800" \
+ echo *** WARNING *** Unsupported cl.exe version detected: $(MSC_VER) ($(RAW_MSC_VER)), only 1600/1700/1800 (Visual Studio 2010/2012/2013) are supported.
checkLink:
- @ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" if "$(LD_VER)" NEQ "1100" \
- echo *** WARNING *** unrecognized link.exe version $(LD_VER) ($(RAW_LD_VER)). Use FORCE_LD_VER to override automatic detection.
+ @ if "$(LD_VER)" NEQ "1000" if "$(LD_VER)" NEQ "1100" if "$(LD_VER)" NEQ "1200" \
+ echo *** WARNING *** Unsupported link.exe version detected: $(LD_VER) ($(RAW_LD_VER)), only 1000/1100/1200 (Visual Studio 2010/2012/2013) are supported.
--- a/hotspot/make/windows/makefiles/vm.make Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/makefiles/vm.make Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -132,7 +132,7 @@
!if "$(USE_PRECOMPILED_HEADER)" != "0"
CXX_USE_PCH=/Fp"vm.pch" /Yu"precompiled.hpp"
-!if "$(COMPILER_NAME)" == "VS2012"
+!if "$(MSC_VER)" > "1600"
# VS2012 requires this object file to be listed:
LD_FLAGS=$(LD_FLAGS) _build_pch_file.obj
!endif
--- a/hotspot/make/windows/projectfiles/common/Makefile Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/make/windows/projectfiles/common/Makefile Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,6 @@
ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions)
$(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
- @if "$(MSC_VER)"=="1500" echo Make sure you have VS2008 SP1 or later, or you may see 'expanded command line too long'
@$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
clean:
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -2984,9 +2984,12 @@
} else if (tag == vmSymbols::tag_enclosing_method()) {
if (parsed_enclosingmethod_attribute) {
classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK);
- } else {
+ } else {
parsed_enclosingmethod_attribute = true;
}
+ guarantee_property(attribute_length == 4,
+ "Wrong EnclosingMethod attribute length %u in class file %s",
+ attribute_length, CHECK);
cfs->guarantee_more(4, CHECK); // class_index, method_index
enclosing_method_class_index = cfs->get_u2_fast();
enclosing_method_method_index = cfs->get_u2_fast();
@@ -4664,9 +4667,7 @@
}
bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
- u2 max_version =
- JDK_Version::is_gte_jdk17x_version() ? JAVA_MAX_SUPPORTED_VERSION :
- (JDK_Version::is_gte_jdk16x_version() ? JAVA_6_VERSION : JAVA_1_5_VERSION);
+ u2 max_version = JAVA_MAX_SUPPORTED_VERSION;
return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
(major <= max_version) &&
((major != max_version) ||
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1126,7 +1126,7 @@
// JDK 1.3 version
-typedef struct real_jzentry13 { /* Zip file entry */
+typedef struct real_jzentry { /* Zip file entry */
char *name; /* entry name */
jint time; /* modification time */
jint size; /* size of uncompressed data */
@@ -1135,9 +1135,9 @@
char *comment; /* optional zip file comment */
jbyte *extra; /* optional extra data */
jint pos; /* position of LOC header (if negative) or data */
-} real_jzentry13;
+} real_jzentry;
-typedef struct real_jzfile13 { /* Zip file */
+typedef struct real_jzfile { /* Zip file */
char *name; /* zip file name */
jint refs; /* number of active references */
jint fd; /* open file descriptor */
@@ -1148,42 +1148,14 @@
jint total; /* total number of entries */
unsigned short *table; /* Hash chain heads: indexes into entries */
jint tablelen; /* number of hash eads */
- real_jzfile13 *next; /* next zip file in search list */
+ real_jzfile *next; /* next zip file in search list */
jzentry *cache; /* we cache the most recently freed jzentry */
/* Information on metadata names in META-INF directory */
char **metanames; /* array of meta names (may have null names) */
jint metacount; /* number of slots in metanames array */
/* If there are any per-entry comments, they are in the comments array */
char **comments;
-} real_jzfile13;
-
-// JDK 1.2 version
-typedef struct real_jzentry12 { /* Zip file entry */
- char *name; /* entry name */
- jint time; /* modification time */
- jint size; /* size of uncompressed data */
- jint csize; /* size of compressed data (zero if uncompressed) */
- jint crc; /* crc of uncompressed data */
- char *comment; /* optional zip file comment */
- jbyte *extra; /* optional extra data */
- jint pos; /* position of LOC header (if negative) or data */
- struct real_jzentry12 *next; /* next entry in hash table */
-} real_jzentry12;
-
-typedef struct real_jzfile12 { /* Zip file */
- char *name; /* zip file name */
- jint refs; /* number of active references */
- jint fd; /* open file descriptor */
- void *lock; /* read lock */
- char *comment; /* zip file comment */
- char *msg; /* zip error message */
- real_jzentry12 *entries; /* array of zip entries */
- jint total; /* total number of entries */
- real_jzentry12 **table; /* hash table of entries */
- jint tablelen; /* number of buckets */
- jzfile *next; /* next zip file in search list */
-} real_jzfile12;
-
+} real_jzfile;
void ClassPathDirEntry::compile_the_world(Handle loader, TRAPS) {
// For now we only compile all methods in all classes in zip/jar files
@@ -1197,10 +1169,14 @@
}
void ClassPathZipEntry::compile_the_world(Handle loader, TRAPS) {
- if (JDK_Version::is_jdk12x_version()) {
- compile_the_world12(loader, THREAD);
- } else {
- compile_the_world13(loader, THREAD);
+ real_jzfile* zip = (real_jzfile*) _zip;
+ tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name);
+ tty->cr();
+ // Iterate over all entries in zip file
+ for (int n = 0; ; n++) {
+ real_jzentry * ze = (real_jzentry *)((*GetNextEntry)(_zip, n));
+ if (ze == NULL) break;
+ ClassLoader::compile_the_world_in(ze->name, loader, CHECK);
}
if (HAS_PENDING_EXCEPTION) {
if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) {
@@ -1213,54 +1189,8 @@
}
}
-// Version that works for JDK 1.3.x
-void ClassPathZipEntry::compile_the_world13(Handle loader, TRAPS) {
- real_jzfile13* zip = (real_jzfile13*) _zip;
- tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name);
- tty->cr();
- // Iterate over all entries in zip file
- for (int n = 0; ; n++) {
- real_jzentry13 * ze = (real_jzentry13 *)((*GetNextEntry)(_zip, n));
- if (ze == NULL) break;
- ClassLoader::compile_the_world_in(ze->name, loader, CHECK);
- }
-}
-
-
-// Version that works for JDK 1.2.x
-void ClassPathZipEntry::compile_the_world12(Handle loader, TRAPS) {
- real_jzfile12* zip = (real_jzfile12*) _zip;
- tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name);
- tty->cr();
- // Iterate over all entries in zip file
- for (int n = 0; ; n++) {
- real_jzentry12 * ze = (real_jzentry12 *)((*GetNextEntry)(_zip, n));
- if (ze == NULL) break;
- ClassLoader::compile_the_world_in(ze->name, loader, CHECK);
- }
-}
-
bool ClassPathZipEntry::is_rt_jar() {
- if (JDK_Version::is_jdk12x_version()) {
- return is_rt_jar12();
- } else {
- return is_rt_jar13();
- }
-}
-
-// JDK 1.3 version
-bool ClassPathZipEntry::is_rt_jar13() {
- real_jzfile13* zip = (real_jzfile13*) _zip;
- int len = (int)strlen(zip->name);
- // Check whether zip name ends in "rt.jar"
- // This will match other archives named rt.jar as well, but this is
- // only used for debugging.
- return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0);
-}
-
-// JDK 1.2 version
-bool ClassPathZipEntry::is_rt_jar12() {
- real_jzfile12* zip = (real_jzfile12*) _zip;
+ real_jzfile* zip = (real_jzfile*) _zip;
int len = (int)strlen(zip->name);
// Check whether zip name ends in "rt.jar"
// This will match other archives named rt.jar as well, but this is
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -111,11 +111,7 @@
void contents_do(void f(const char* name, void* context), void* context);
// Debugging
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
- NOT_PRODUCT(void compile_the_world12(Handle loader, TRAPS);) // JDK 1.2 version
- NOT_PRODUCT(void compile_the_world13(Handle loader, TRAPS);) // JDK 1.3 version
NOT_PRODUCT(bool is_rt_jar();)
- NOT_PRODUCT(bool is_rt_jar12();)
- NOT_PRODUCT(bool is_rt_jar13();)
};
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -624,6 +624,12 @@
}
}
+void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
+ for (ClassLoaderData* cld = _head; cl != NULL && cld != NULL; cld = cld->next()) {
+ cl->do_cld(cld);
+ }
+}
+
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
cld->classes_do(klass_closure);
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -77,6 +77,7 @@
static void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
+ static void cld_do(CLDClosure* cl);
static void classes_do(KlassClosure* klass_closure);
static void classes_do(void f(Klass* const));
static void methods_do(void f(Method*));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderStats.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/classLoaderStats.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+
+class ClassStatsClosure : public KlassClosure {
+public:
+ int _num_classes;
+
+ ClassStatsClosure() :
+ _num_classes(0) {
+ }
+
+ virtual void do_klass(Klass* k) {
+ _num_classes++;
+ }
+};
+
+
+void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
+ oop cl = cld->class_loader();
+ ClassLoaderStats* cls;
+
+ // The hashtable key is the ClassLoader oop since we want to account
+ // for "real" classes and anonymous classes together
+ ClassLoaderStats** cls_ptr = _stats->get(cl);
+ if (cls_ptr == NULL) {
+ cls = new ClassLoaderStats();
+ _stats->put(cl, cls);
+ _total_loaders++;
+ } else {
+ cls = *cls_ptr;
+ }
+
+ if (!cld->is_anonymous()) {
+ cls->_cld = cld;
+ }
+
+ cls->_class_loader = cl;
+ if (cl != NULL) {
+ cls->_parent = java_lang_ClassLoader::parent(cl);
+ addEmptyParents(cls->_parent);
+ }
+
+ ClassStatsClosure csc;
+ cld->classes_do(&csc);
+ if(cld->is_anonymous()) {
+ cls->_anon_classes_count += csc._num_classes;
+ } else {
+ cls->_classes_count = csc._num_classes;
+ }
+ _total_classes += csc._num_classes;
+
+ Metaspace* ms = cld->metaspace_or_null();
+ if (ms != NULL) {
+ if(cld->is_anonymous()) {
+ cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
+ cls->_anon_block_sz += ms->allocated_blocks_bytes();
+ } else {
+ cls->_chunk_sz = ms->allocated_chunks_bytes();
+ cls->_block_sz = ms->allocated_blocks_bytes();
+ }
+ _total_chunk_sz += ms->allocated_chunks_bytes();
+ _total_block_sz += ms->allocated_blocks_bytes();
+ }
+}
+
+
+// Handles the difference in pointer width on 32 and 64 bit platforms
+#ifdef _LP64
+ #define SPACE "%8s"
+#else
+ #define SPACE "%s"
+#endif
+
+
+bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) {
+ Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass());
+ Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass());
+
+ _out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ",
+ p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld),
+ cls->_classes_count,
+ cls->_chunk_sz, cls->_block_sz);
+ if (class_loader_klass != NULL) {
+ _out->print("%s", class_loader_klass->external_name());
+ } else {
+ _out->print("<boot class loader>");
+ }
+ _out->cr();
+ if (cls->_anon_classes_count > 0) {
+ _out->print_cr(SPACE SPACE SPACE " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " + unsafe anonymous classes",
+ "", "", "",
+ cls->_anon_classes_count,
+ cls->_anon_chunk_sz, cls->_anon_block_sz);
+ }
+ return true;
+}
+
+
+void ClassLoaderStatsClosure::print() {
+ _out->print_cr("ClassLoader" SPACE " Parent" SPACE " CLD*" SPACE " Classes ChunkSz BlockSz Type", "", "", "");
+ _stats->iterate(this);
+ _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders);
+ _out->print(SPACE SPACE SPACE " ", "", "", "");
+ _out->print_cr(UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ",
+ _total_classes,
+ _total_chunk_sz,
+ _total_block_sz);
+ _out->print_cr("ChunkSz: Total size of all allocated metaspace chunks");
+ _out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)");
+}
+
+
+void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
+ while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
+ // This classloader has not loaded any classes
+ ClassLoaderStats** cls_ptr = _stats->get(cl);
+ if (cls_ptr == NULL) {
+ // It does not exist in our table - add it
+ ClassLoaderStats* cls = new ClassLoaderStats();
+ cls->_class_loader = cl;
+ cls->_parent = java_lang_ClassLoader::parent(cl);
+ _stats->put(cl, cls);
+ _total_loaders++;
+ }
+
+ cl = java_lang_ClassLoader::parent(cl);
+ }
+}
+
+
+void ClassLoaderStatsVMOperation::doit() {
+ ClassLoaderStatsClosure clsc (_out);
+ ClassLoaderDataGraph::cld_do(&clsc);
+ clsc.print();
+}
+
+
+void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) {
+ ClassLoaderStatsVMOperation op(output());
+ VMThread::execute(&op);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderStats.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
+#define SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
+
+
+#include "classfile/classLoaderData.hpp"
+#include "oops/klass.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "runtime/vm_operations.hpp"
+#include "services/diagnosticCommand.hpp"
+#include "utilities/resourceHash.hpp"
+
+
+class ClassLoaderStatsDCmd : public DCmd {
+public:
+ ClassLoaderStatsDCmd(outputStream* output, bool heap) :
+ DCmd(output, heap) {
+ }
+
+ static const char* name() {
+ return "VM.classloader_stats";
+ }
+
+ static const char* description() {
+ return "Print statistics about all ClassLoaders.";
+ }
+
+ static const char* impact() {
+ return "Low";
+ }
+
+ virtual void execute(DCmdSource source, TRAPS);
+
+ static int num_arguments() {
+ return 0;
+ }
+
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
+};
+
+
+class ClassLoaderStats : public ResourceObj {
+public:
+ ClassLoaderData* _cld;
+ oop _class_loader;
+ oop _parent;
+
+ size_t _chunk_sz;
+ size_t _block_sz;
+ uintx _classes_count;
+
+ size_t _anon_chunk_sz;
+ size_t _anon_block_sz;
+ uintx _anon_classes_count;
+
+ ClassLoaderStats() :
+ _cld(0),
+ _class_loader(0),
+ _parent(0),
+ _chunk_sz(0),
+ _block_sz(0),
+ _classes_count(0),
+ _anon_block_sz(0),
+ _anon_chunk_sz(0),
+ _anon_classes_count(0) {
+ }
+};
+
+
+class ClassLoaderStatsClosure : public CLDClosure {
+protected:
+ static bool oop_equals(oop const& s1, oop const& s2) {
+ return s1 == s2;
+ }
+
+ static unsigned oop_hash(oop const& s1) {
+ unsigned hash = (unsigned)((uintptr_t)&s1);
+ return hash ^ (hash >> LogMinObjAlignment);
+ }
+
+ typedef ResourceHashtable<oop, ClassLoaderStats*,
+ ClassLoaderStatsClosure::oop_hash, ClassLoaderStatsClosure::oop_equals> StatsTable;
+
+ outputStream* _out;
+ StatsTable* _stats;
+ uintx _total_loaders;
+ uintx _total_classes;
+ size_t _total_chunk_sz;
+ size_t _total_block_sz;
+
+public:
+ ClassLoaderStatsClosure(outputStream* out) :
+ _out(out),
+ _total_loaders(0),
+ _total_block_sz(0),
+ _total_chunk_sz(0),
+ _total_classes(0),
+ _stats(new StatsTable()) {
+ }
+
+ virtual void do_cld(ClassLoaderData* cld);
+ virtual bool do_entry(oop const& key, ClassLoaderStats* const& cls);
+ void print();
+
+private:
+ void addEmptyParents(oop cl);
+};
+
+
+class ClassLoaderStatsVMOperation : public VM_Operation {
+ outputStream* _out;
+
+public:
+ ClassLoaderStatsVMOperation(outputStream* out) :
+ _out(out) {
+ }
+
+ VMOp_Type type() const {
+ return VMOp_ClassLoaderStatsOperation;
+ }
+
+ void doit();
+};
+
+#endif // SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -857,9 +857,7 @@
}
int java_lang_Class::classRedefinedCount(oop the_class_mirror) {
- if (!JDK_Version::is_gte_jdk15x_version()
- || classRedefinedCount_offset == -1) {
- // The classRedefinedCount field is only present starting in 1.5.
+ if (classRedefinedCount_offset == -1) {
// If we don't have an offset for it then just return -1 as a marker.
return -1;
}
@@ -868,9 +866,7 @@
}
void java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) {
- if (!JDK_Version::is_gte_jdk15x_version()
- || classRedefinedCount_offset == -1) {
- // The classRedefinedCount field is only present starting in 1.5.
+ if (classRedefinedCount_offset == -1) {
// If we don't have an offset for it then nothing to set.
return;
}
@@ -1000,9 +996,7 @@
jlong java_lang_Thread::stackSize(oop java_thread) {
- // The stackSize field is only present starting in 1.4
if (_stackSize_offset > 0) {
- assert(JDK_Version::is_gte_jdk14x_version(), "sanity check");
return java_thread->long_field(_stackSize_offset);
} else {
return 0;
@@ -1078,7 +1072,7 @@
const char* java_lang_Thread::thread_status_name(oop java_thread) {
- assert(JDK_Version::is_gte_jdk15x_version() && _thread_status_offset != 0, "Must have thread status");
+ assert(_thread_status_offset != 0, "Must have thread status");
ThreadStatus status = (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset);
switch (status) {
case NEW : return "NEW";
@@ -1217,7 +1211,6 @@
}
void java_lang_Throwable::clear_stacktrace(oop throwable) {
- assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4");
set_stacktrace(throwable, NULL);
}
@@ -1548,12 +1541,9 @@
// Start out by clearing the backtrace for this object, in case the VM
// runs out of memory while allocating the stack trace
set_backtrace(throwable(), NULL);
- if (JDK_Version::is_gte_jdk14x_version()) {
- // New since 1.4, clear lazily constructed Java level stacktrace if
- // refilling occurs
- // This is unnecessary in 1.7+ but harmless
- clear_stacktrace(throwable());
- }
+ // Clear lazily constructed Java level stacktrace if refilling occurs
+ // This is unnecessary in 1.7+ but harmless
+ clear_stacktrace(throwable());
int max_depth = MaxJavaStackTraceDepth;
JavaThread* thread = (JavaThread*)THREAD;
@@ -1739,13 +1729,9 @@
if (chunk_count >= max_chunks) break;
}
- // For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support
- // was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround
- // can be removed in a JDK using this JVM version
- if (JDK_Version::is_gte_jdk17x_version()) {
- java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
- assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
- }
+ // We support the Throwable immutability protocol defined for Java 7.
+ java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
+ assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
}
@@ -3022,8 +3008,7 @@
// based on non-null field
// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it
bool java_lang_ClassLoader::parallelCapable(oop class_loader) {
- if (!JDK_Version::is_gte_jdk17x_version()
- || parallelCapable_offset == -1) {
+ if (parallelCapable_offset == -1) {
// Default for backward compatibility is false
return false;
}
@@ -3219,7 +3204,6 @@
void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
if (_owner_offset != 0) return;
- assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later");
SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK);
Klass* k = SystemDictionary::abstract_ownable_synchronizer_klass();
compute_offset(_owner_offset, k,
@@ -3309,15 +3293,10 @@
java_lang_reflect_Method::compute_offsets();
java_lang_reflect_Constructor::compute_offsets();
java_lang_reflect_Field::compute_offsets();
- if (JDK_Version::is_gte_jdk14x_version()) {
- java_nio_Buffer::compute_offsets();
- }
- if (JDK_Version::is_gte_jdk15x_version()) {
- sun_reflect_ConstantPool::compute_offsets();
- sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
- }
- if (JDK_Version::is_gte_jdk18x_version())
- java_lang_reflect_Parameter::compute_offsets();
+ java_nio_Buffer::compute_offsets();
+ sun_reflect_ConstantPool::compute_offsets();
+ sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
+ java_lang_reflect_Parameter::compute_offsets();
// generated interpreter code wants to know about the offsets we just computed:
AbstractAssembler::update_delayed_values();
@@ -3502,7 +3481,7 @@
// into merlin "for some time." Without it, the vm will fail with early
// merlin builds.
- if (CheckAssertionStatusDirectives && JDK_Version::is_gte_jdk14x_version()) {
+ if (CheckAssertionStatusDirectives) {
const char* nm = "java/lang/AssertionStatusDirectives";
const char* sig = "[Ljava/lang/String;";
CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, classes, sig);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1754,8 +1754,6 @@
// Lazily load klasses
void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
- assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later");
-
// if multiple threads calling this function, only one thread will load
// the class. The other threads will find the loaded version once the
// class is loaded.
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -139,14 +139,13 @@
do_klass(reflect_Constructor_klass, java_lang_reflect_Constructor, Pre ) \
\
/* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
- /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \
- do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
- do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
+ do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Pre ) \
+ do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Pre ) \
do_klass(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt ) \
- do_klass(reflect_ConstantPool_klass, sun_reflect_ConstantPool, Opt_Only_JDK15 ) \
- do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15 ) \
+ do_klass(reflect_ConstantPool_klass, sun_reflect_ConstantPool, Opt ) \
+ do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt ) \
do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \
\
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
@@ -169,7 +168,6 @@
\
/* It's NULL in non-1.4 JDKs. */ \
do_klass(StackTraceElement_klass, java_lang_StackTraceElement, Opt ) \
- /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
do_klass(nio_Buffer_klass, java_nio_Buffer, Opt ) \
\
@@ -209,10 +207,8 @@
// Options after this point will use resolve_or_null instead.
Opt, // preload tried; NULL if not present
- Opt_Only_JDK14NewRef, // preload tried; use only with NewReflection
- Opt_Only_JDK15, // preload tried; use only with JDK1.5+
OPTION_LIMIT,
- CEIL_LG_OPTION_LIMIT = 4 // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
+ CEIL_LG_OPTION_LIMIT = 2 // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
};
@@ -385,15 +381,6 @@
static Klass* check_klass_Pre( Klass* k) { return check_klass(k); }
static Klass* check_klass_Opt( Klass* k) { return k; }
- static Klass* check_klass_Opt_Only_JDK15(Klass* k) {
- assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
- return k;
- }
- static Klass* check_klass_Opt_Only_JDK14NewRef(Klass* k) {
- assert(JDK_Version::is_gte_jdk14x_version(), "JDK 1.4 only");
- // despite the optional loading, if you use this it must be present:
- return check_klass(k);
- }
static bool initialize_wk_klass(WKID id, int init_opt, TRAPS);
static void initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS);
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -320,7 +320,6 @@
template(reference_discovered_name, "discovered") \
template(run_finalization_name, "runFinalization") \
template(run_finalizers_on_exit_name, "runFinalizersOnExit") \
- template(uncaughtException_name, "uncaughtException") \
template(dispatchUncaughtException_name, "dispatchUncaughtException") \
template(initializeSystemClass_name, "initializeSystemClass") \
template(loadClass_name, "loadClass") \
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -945,12 +945,8 @@
Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ?
current_klass() :
InstanceKlass::cast(current_klass())->host_klass();
- // As of the fix for 4486457 we disable verification for all of the
- // dynamically-generated bytecodes associated with the 1.4
- // reflection implementation, not just those associated with
- // sun/reflect/SerializationConstructorAccessor.
- bool is_reflect = JDK_Version::is_gte_jdk14x_version() &&
- klass_to_check->is_subclass_of(
+ // Disable verification for the dynamically-generated reflection bytecodes.
+ bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass());
if (!is_reflect &&
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/guardedMemory.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include "precompiled.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/guardedMemory.hpp"
+#include "runtime/os.hpp"
+
+void* GuardedMemory::wrap_copy(const void* ptr, const size_t len, const void* tag) {
+ size_t total_sz = GuardedMemory::get_total_size(len);
+ void* outerp = os::malloc(total_sz, mtInternal);
+ if (outerp != NULL) {
+ GuardedMemory guarded(outerp, len, tag);
+ void* innerp = guarded.get_user_ptr();
+ memcpy(innerp, ptr, len);
+ return innerp;
+ }
+ return NULL; // OOM
+}
+
+bool GuardedMemory::free_copy(void* p) {
+ if (p == NULL) {
+ return true;
+ }
+ GuardedMemory guarded((u_char*)p);
+ bool verify_ok = guarded.verify_guards();
+
+ /* always attempt to free, pass problem on to any nested memchecker */
+ os::free(guarded.release_for_freeing());
+
+ return verify_ok;
+}
+
+void GuardedMemory::print_on(outputStream* st) const {
+ if (_base_addr == NULL) {
+ st->print_cr("GuardedMemory(" PTR_FORMAT ") not associated to any memory", p2i(this));
+ return;
+ }
+ st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT
+ " tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT,
+ p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr()));
+
+ Guard* guard = get_head_guard();
+ st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
+ guard = get_tail_guard();
+ st->print_cr(" Trailer guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
+
+ u_char udata = *get_user_ptr();
+ switch (udata) {
+ case uninitBlockPad:
+ st->print_cr(" User data appears unused");
+ break;
+ case freeBlockPad:
+ st->print_cr(" User data appears to have been freed");
+ break;
+ default:
+ st->print_cr(" User data appears to be in use");
+ break;
+ }
+}
+
+// test code...
+
+#ifndef PRODUCT
+
+static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
+ assert(p != NULL, "NULL pointer given to check");
+ u_char* c = (u_char*) p;
+ GuardedMemory guarded(c);
+ assert(guarded.get_tag() == tag, "Tag is not the same as supplied");
+ assert(guarded.get_user_ptr() == c, "User pointer is not the same as supplied");
+ assert(guarded.get_user_size() == sz, "User size is not the same as supplied");
+ assert(guarded.verify_guards(), "Guard broken");
+}
+
+void GuardedMemory::test_guarded_memory() {
+ // Test the basic characteristics...
+ size_t total_sz = GuardedMemory::get_total_size(1);
+ assert(total_sz > 1 && total_sz >= (sizeof(GuardHeader) + 1 + sizeof(Guard)), "Unexpected size");
+ u_char* basep = (u_char*) os::malloc(total_sz, mtInternal);
+
+ GuardedMemory guarded(basep, 1, (void*)0xf000f000);
+
+ assert(*basep == badResourceValue, "Expected guard in the form of badResourceValue");
+ u_char* userp = guarded.get_user_ptr();
+ assert(*userp == uninitBlockPad, "Expected uninitialized data in the form of uninitBlockPad");
+ guarded_memory_test_check(userp, 1, (void*)0xf000f000);
+
+ void* freep = guarded.release_for_freeing();
+ assert((u_char*)freep == basep, "Expected the same pointer guard was ");
+ assert(*userp == freeBlockPad, "Expected user data to be free block padded");
+ assert(!guarded.verify_guards(), "Expected failed");
+ os::free(freep);
+
+ // Test a number of odd sizes...
+ size_t sz = 0;
+ do {
+ void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
+ void* up = guarded.wrap_with_guards(p, sz, (void*)1);
+ memset(up, 0, sz);
+ guarded_memory_test_check(up, sz, (void*)1);
+ os::free(guarded.release_for_freeing());
+ sz = (sz << 4) + 1;
+ } while (sz < (256 * 1024));
+
+ // Test buffer overrun into head...
+ basep = (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+ guarded.wrap_with_guards(basep, 1);
+ *basep = 0;
+ assert(!guarded.verify_guards(), "Expected failure");
+ os::free(basep);
+
+ // Test buffer overrun into tail with a number of odd sizes...
+ sz = 1;
+ do {
+ void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
+ void* up = guarded.wrap_with_guards(p, sz, (void*)1);
+ memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
+ assert(!guarded.verify_guards(), "Guard was not broken as expected");
+ os::free(guarded.release_for_freeing());
+ sz = (sz << 4) + 1;
+ } while (sz < (256 * 1024));
+
+ // Test wrap_copy/wrap_free...
+ assert(GuardedMemory::free_copy(NULL), "Expected free NULL to be OK");
+
+ const char* str = "Check my bounds out";
+ size_t str_sz = strlen(str) + 1;
+ char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
+ guarded_memory_test_check(str_copy, str_sz, NULL);
+ assert(strcmp(str, str_copy) == 0, "Not identical copy");
+ assert(GuardedMemory::free_copy(str_copy), "Free copy failed to verify");
+
+ void* no_data = NULL;
+ void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
+ assert(GuardedMemory::free_copy(no_data_copy), "Expected valid guards even for no data copy");
+}
+
+#endif // !PRODUCT
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/guardedMemory.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
+#define SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+/**
+ * Guarded memory for detecting buffer overrun.
+ *
+ * Allows allocations to be wrapped with padded bytes of a known byte pattern,
+ * that is a "guard". Guard patterns may be verified to detect buffer overruns.
+ *
+ * Primarily used by "debug malloc" and "checked JNI".
+ *
+ * Memory layout:
+ *
+ * |Offset | Content | Description |
+ * |------------------------------------------------------------
+ * |base_addr | 0xABABABABABABABAB | Head guard |
+ * |+16 | <size_t:user_size> | User data size |
+ * |+sizeof(uintptr_t) | <tag> | Tag word |
+ * |+sizeof(void*) | 0xF1 <user_data> ( | User data |
+ * |+user_size | 0xABABABABABABABAB | Tail guard |
+ * -------------------------------------------------------------
+ *
+ * Where:
+ * - guard padding uses "badResourceValue" (0xAB)
+ * - tag word is general purpose
+ * - user data
+ * -- initially padded with "uninitBlockPad" (0xF1),
+ * -- to "freeBlockPad" (0xBA), when freed
+ *
+ * Usage:
+ *
+ * * Allocations: one may wrap allocations with guard memory:
+ * <code>
+ * Thing* alloc_thing() {
+ * void* mem = user_alloc_fn(GuardedMemory::get_total_size(sizeof(thing)));
+ * GuardedMemory guarded(mem, sizeof(thing));
+ * return (Thing*) guarded.get_user_ptr();
+ * }
+ * </code>
+ * * Verify: memory guards are still in tact
+ * <code>
+ * bool verify_thing(Thing* thing) {
+ * GuardedMemory guarded((void*)thing);
+ * return guarded.verify_guards();
+ * }
+ * </code>
+ * * Free: one may mark bytes as freed (further debugging support)
+ * <code>
+ * void free_thing(Thing* thing) {
+ * GuardedMemory guarded((void*)thing);
+ * assert(guarded.verify_guards(), "Corrupt thing");
+ * user_free_fn(guards.release_for_freeing();
+ * }
+ * </code>
+ */
+class GuardedMemory : StackObj { // Wrapper on stack
+
+ // Private inner classes for memory layout...
+
+protected:
+
+ /**
+ * Guard class for header and trailer known pattern to test for overwrites.
+ */
+ class Guard { // Class for raw memory (no vtbl allowed)
+ friend class GuardedMemory;
+ protected:
+ enum {
+ GUARD_SIZE = 16
+ };
+
+ u_char _guard[GUARD_SIZE];
+
+ public:
+
+ void build() {
+ u_char* c = _guard; // Possibly unaligned if tail guard
+ u_char* end = c + GUARD_SIZE;
+ while (c < end) {
+ *c = badResourceValue;
+ c++;
+ }
+ }
+
+ bool verify() const {
+ u_char* c = (u_char*) _guard;
+ u_char* end = c + GUARD_SIZE;
+ while (c < end) {
+ if (*c != badResourceValue) {
+ return false;
+ }
+ c++;
+ }
+ return true;
+ }
+
+ }; // GuardedMemory::Guard
+
+ /**
+ * Header guard and size
+ */
+ class GuardHeader : Guard {
+ friend class GuardedMemory;
+ protected:
+ // Take care in modifying fields here, will effect alignment
+ // e.g. x86 ABI 16 byte stack alignment
+ union {
+ uintptr_t __unused_full_word1;
+ size_t _user_size;
+ };
+ void* _tag;
+ public:
+ void set_user_size(const size_t usz) { _user_size = usz; }
+ size_t get_user_size() const { return _user_size; }
+
+ void set_tag(const void* tag) { _tag = (void*) tag; }
+ void* get_tag() const { return _tag; }
+
+ }; // GuardedMemory::GuardHeader
+
+ // Guarded Memory...
+
+ protected:
+ u_char* _base_addr;
+
+ public:
+
+ /**
+ * Create new guarded memory.
+ *
+ * Wraps, starting at the given "base_ptr" with guards. Use "get_user_ptr()"
+ * to return a pointer suitable for user data.
+ *
+ * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
+ * @param user_size the size of the user data to be wrapped.
+ * @param tag optional general purpose tag.
+ */
+ GuardedMemory(void* base_ptr, const size_t user_size, const void* tag = NULL) {
+ wrap_with_guards(base_ptr, user_size, tag);
+ }
+
+ /**
+ * Wrap existing guarded memory.
+ *
+ * To use this constructor, one must have created guarded memory with
+ * "GuardedMemory(void*, size_t, void*)" (or indirectly via helper, e.g. "wrap_copy()").
+ *
+ * @param user_p existing wrapped memory.
+ */
+ GuardedMemory(void* userp) {
+ u_char* user_ptr = (u_char*) userp;
+ assert((uintptr_t)user_ptr > (sizeof(GuardHeader) + 0x1000), "Invalid pointer");
+ _base_addr = (user_ptr - sizeof(GuardHeader));
+ }
+
+ /**
+ * Create new guarded memory.
+ *
+ * Wraps, starting at the given "base_ptr" with guards. Allows reuse of stack allocated helper.
+ *
+ * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
+ * @param user_size the size of the user data to be wrapped.
+ * @param tag optional general purpose tag.
+ *
+ * @return user data pointer (inner pointer to supplied "base_ptr").
+ */
+ void* wrap_with_guards(void* base_ptr, size_t user_size, const void* tag = NULL) {
+ assert(base_ptr != NULL, "Attempt to wrap NULL with memory guard");
+ _base_addr = (u_char*)base_ptr;
+ get_head_guard()->build();
+ get_head_guard()->set_user_size(user_size);
+ get_tail_guard()->build();
+ set_tag(tag);
+ set_user_bytes(uninitBlockPad);
+ assert(verify_guards(), "Expected valid memory guards");
+ return get_user_ptr();
+ }
+
+ /**
+ * Verify head and tail guards.
+ *
+ * @return true if guards are intact, false would indicate a buffer overrun.
+ */
+ bool verify_guards() const {
+ if (_base_addr != NULL) {
+ return (get_head_guard()->verify() && get_tail_guard()->verify());
+ }
+ return false;
+ }
+
+ /**
+ * Set the general purpose tag.
+ *
+ * @param tag general purpose tag.
+ */
+ void set_tag(const void* tag) { get_head_guard()->set_tag(tag); }
+
+ /**
+ * Return the general purpose tag.
+ *
+ * @return the general purpose tag, defaults to NULL.
+ */
+ void* get_tag() const { return get_head_guard()->get_tag(); }
+
+ /**
+ * Return the size of the user data.
+ *
+ * @return the size of the user data.
+ */
+ size_t get_user_size() const {
+ assert(_base_addr != NULL, "Not wrapping any memory");
+ return get_head_guard()->get_user_size();
+ }
+
+ /**
+ * Return the user data pointer.
+ *
+ * @return the user data pointer.
+ */
+ u_char* get_user_ptr() const {
+ assert(_base_addr != NULL, "Not wrapping any memory");
+ return _base_addr + sizeof(GuardHeader);
+ }
+
+ /**
+ * Release the wrapped pointer for resource freeing.
+ *
+ * Pads the user data with "freeBlockPad", and dis-associates the helper.
+ *
+ * @return the original base pointer used to wrap the data.
+ */
+ void* release_for_freeing() {
+ set_user_bytes(freeBlockPad);
+ return release();
+ }
+
+ /**
+ * Dis-associate the help from the original base address.
+ *
+ * @return the original base pointer used to wrap the data.
+ */
+ void* release() {
+ void* p = (void*) _base_addr;
+ _base_addr = NULL;
+ return p;
+ }
+
+ virtual void print_on(outputStream* st) const;
+
+ protected:
+ GuardHeader* get_head_guard() const { return (GuardHeader*) _base_addr; }
+ Guard* get_tail_guard() const { return (Guard*) (get_user_ptr() + get_user_size()); };
+ void set_user_bytes(u_char ch) {
+ memset(get_user_ptr(), ch, get_user_size());
+ }
+
+ public:
+ /**
+ * Return the total size required for wrapping the given user size.
+ *
+ * @return the total size required for wrapping the given user size.
+ */
+ static size_t get_total_size(size_t user_size) {
+ size_t total_size = sizeof(GuardHeader) + user_size + sizeof(Guard);
+ assert(total_size > user_size, "Unexpected wrap-around");
+ return total_size;
+ }
+
+ // Helper functions...
+
+ /**
+ * Wrap a copy of size "len" of "ptr".
+ *
+ * @param ptr the memory to be copied
+ * @param len the length of the copy
+ * @param tag optional general purpose tag (see GuardedMemory::get_tag())
+ *
+ * @return guarded wrapped memory pointer to the user area, or NULL if OOM.
+ */
+ static void* wrap_copy(const void* p, const size_t len, const void* tag = NULL);
+
+ /**
+ * Free wrapped copy.
+ *
+ * Frees memory copied with "wrap_copy()".
+ *
+ * @param p memory returned by "wrap_copy()".
+ *
+ * @return true if guards were verified as intact. false indicates a buffer overrun.
+ */
+ static bool free_copy(void* p);
+
+ // Testing...
+#ifndef PRODUCT
+ static void test_guarded_memory(void);
+#endif
+}; // GuardedMemory
+
+#endif // SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
--- a/hotspot/src/share/vm/memory/metaspace.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -697,6 +697,7 @@
size_t allocated_blocks_words() const { return _allocated_blocks_words; }
size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; }
size_t allocated_chunks_words() const { return _allocated_chunks_words; }
+ size_t allocated_chunks_bytes() const { return _allocated_chunks_words * BytesPerWord; }
size_t allocated_chunks_count() const { return _allocated_chunks_count; }
bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
@@ -3365,6 +3366,16 @@
return capacity_words_slow(mdtype) * BytesPerWord;
}
+size_t Metaspace::allocated_blocks_bytes() const {
+ return vsm()->allocated_blocks_bytes() +
+ (using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0);
+}
+
+size_t Metaspace::allocated_chunks_bytes() const {
+ return vsm()->allocated_chunks_bytes() +
+ (using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0);
+}
+
void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
assert(!SafepointSynchronize::is_at_safepoint()
|| Thread::current()->is_VM_thread(), "should be the VM thread");
--- a/hotspot/src/share/vm/memory/metaspace.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -226,6 +226,9 @@
size_t used_bytes_slow(MetadataType mdtype) const;
size_t capacity_bytes_slow(MetadataType mdtype) const;
+ size_t allocated_blocks_bytes() const;
+ size_t allocated_chunks_bytes() const;
+
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
bool read_only, MetaspaceObj::Type type, TRAPS);
void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
--- a/hotspot/src/share/vm/memory/universe.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1000,9 +1000,6 @@
}
-// This function is defined in JVM.cpp
-extern void initialize_converter_functions();
-
bool universe_post_init() {
assert(!is_init_completed(), "Error: initialization not yet completed!");
Universe::_fully_initialized = true;
@@ -1144,11 +1141,6 @@
SystemDictionary::ProtectionDomain_klass(), m);;
}
- // The following is initializing converter functions for serialization in
- // JVM.cpp. If we clean up the StrictMath code above we may want to find
- // a better solution for this as well.
- initialize_converter_functions();
-
// This needs to be done before the first scavenge/gc, since
// it's an input to soft ref clearing policy.
{
--- a/hotspot/src/share/vm/oops/method.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1023,8 +1023,7 @@
// This is Method.invoke() -- ignore it
return true;
}
- if (JDK_Version::is_gte_jdk14x_version() &&
- method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
+ if (method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
// This is an auxilary frame -- ignore it
return true;
}
--- a/hotspot/src/share/vm/prims/jni.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -3858,6 +3858,7 @@
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#endif
+#include "memory/guardedMemory.hpp"
#include "utilities/quickSort.hpp"
#include "utilities/ostream.hpp"
#if INCLUDE_VM_STRUCTS
@@ -3901,6 +3902,7 @@
run_unit_test(arrayOopDesc::test_max_array_length());
run_unit_test(CollectedHeap::test_is_in());
run_unit_test(QuickSort::test_quick_sort());
+ run_unit_test(GuardedMemory::test_guarded_memory());
run_unit_test(AltHashing::test_alt_hash());
run_unit_test(test_loggc_filename());
run_unit_test(TestNewSize_test());
--- a/hotspot/src/share/vm/prims/jniCheck.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
+#include "memory/guardedMemory.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
@@ -52,6 +53,8 @@
# include "jniTypes_ppc.hpp"
#endif
+// Complain every extra number of unplanned local refs
+#define CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD 32
// Heap objects are allowed to be directly referenced only in VM code,
// not in native code.
@@ -167,12 +170,42 @@
* SUPPORT FUNCTIONS
*/
+/**
+ * Check whether or not a programmer has actually checked for exceptions. According
+ * to the JNI Specification ("jni/spec/design.html#java_exceptions"):
+ *
+ * There are two cases where the programmer needs to check for exceptions without
+ * being able to first check an error code:
+ *
+ * - The JNI functions that invoke a Java method return the result of the Java method.
+ * The programmer must call ExceptionOccurred() to check for possible exceptions
+ * that occurred during the execution of the Java method.
+ *
+ * - Some of the JNI array access functions do not return an error code, but may
+ * throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
+ *
+ * In all other cases, a non-error return value guarantees that no exceptions have been thrown.
+ */
+static inline void
+check_pending_exception(JavaThread* thr) {
+ if (thr->has_pending_exception()) {
+ NativeReportJNIWarning(thr, "JNI call made with exception pending");
+ }
+ if (thr->is_pending_jni_exception_check()) {
+ IN_VM(
+ tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s",
+ thr->get_pending_jni_exception_check());
+ thr->print_stack();
+ )
+ thr->clear_pending_jni_exception_check(); // Just complain once
+ }
+}
+
+
static inline void
functionEnterCritical(JavaThread* thr)
{
- if (thr->has_pending_exception()) {
- NativeReportJNIWarning(thr, "JNI call made with exception pending");
- }
+ check_pending_exception(thr);
}
static inline void
@@ -186,9 +219,7 @@
if (thr->in_critical()) {
tty->print_cr("%s", warn_other_function_in_critical);
}
- if (thr->has_pending_exception()) {
- NativeReportJNIWarning(thr, "JNI call made with exception pending");
- }
+ check_pending_exception(thr);
}
static inline void
@@ -200,9 +231,20 @@
}
static inline void
-functionExit(JNIEnv *env)
+functionExit(JavaThread* thr)
{
- /* nothing to do at this time */
+ JNIHandleBlock* handles = thr->active_handles();
+ size_t planned_capacity = handles->get_planned_capacity();
+ size_t live_handles = handles->get_number_of_live_handles();
+ if (live_handles > planned_capacity) {
+ IN_VM(
+ tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu",
+ live_handles, planned_capacity);
+ thr->print_stack();
+ )
+ // Complain just the once, reset to current + warn threshold
+ handles->set_planned_capacity(live_handles + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ }
}
static inline void
@@ -323,6 +365,74 @@
}
}
+/*
+ * Copy and wrap array elements for bounds checking.
+ * Remember the original elements (GuardedMemory::get_tag())
+ */
+static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
+ void* orig_elements) {
+ void* result;
+ IN_VM(
+ oop a = JNIHandles::resolve_non_null(array);
+ size_t len = arrayOop(a)->length() <<
+ TypeArrayKlass::cast(a->klass())->log2_element_size();
+ result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
+ )
+ return result;
+}
+
+static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
+ void* obj, void* carray, size_t* rsz) {
+ if (carray == NULL) {
+ tty->print_cr("%s: elements vector NULL" PTR_FORMAT, fn_name, p2i(obj));
+ NativeReportJNIFatalError(thr, "Elements vector NULL");
+ }
+ GuardedMemory guarded(carray);
+ void* orig_result = guarded.get_tag();
+ if (!guarded.verify_guards()) {
+ tty->print_cr("ReleasePrimitiveArrayCritical: release array failed bounds "
+ "check, incorrect pointer returned ? array: " PTR_FORMAT " carray: "
+ PTR_FORMAT, p2i(obj), p2i(carray));
+ guarded.print_on(tty);
+ NativeReportJNIFatalError(thr, "ReleasePrimitiveArrayCritical: "
+ "failed bounds check");
+ }
+ if (orig_result == NULL) {
+ tty->print_cr("ReleasePrimitiveArrayCritical: unrecognized elements. array: "
+ PTR_FORMAT " carray: " PTR_FORMAT, p2i(obj), p2i(carray));
+ guarded.print_on(tty);
+ NativeReportJNIFatalError(thr, "ReleasePrimitiveArrayCritical: "
+ "unrecognized elements");
+ }
+ if (rsz != NULL) {
+ *rsz = guarded.get_user_size();
+ }
+ return orig_result;
+}
+
+static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name,
+ void* obj, void* carray, jint mode) {
+ size_t sz;
+ void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz);
+ switch (mode) {
+ case 0:
+ memcpy(orig_result, carray, sz);
+ GuardedMemory::free_copy(carray);
+ break;
+ case JNI_COMMIT:
+ memcpy(orig_result, carray, sz);
+ break;
+ case JNI_ABORT:
+ GuardedMemory::free_copy(carray);
+ break;
+ default:
+ tty->print_cr("%s: Unrecognized mode %i releasing array "
+ PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, p2i(obj), p2i(carray));
+ NativeReportJNIFatalError(thr, "Unrecognized array release mode");
+ }
+ return orig_result;
+}
+
oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
if (JNIHandles::is_frame_handle(thr, obj) ||
JNIHandles::is_local_handle(thr, obj) ||
@@ -439,7 +549,7 @@
jniCheck::validate_object(thr, loader);
)
jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -451,7 +561,7 @@
jniCheck::validate_class_descriptor(thr, name);
)
jclass result = UNCHECKED()->FindClass(env, name);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -463,7 +573,7 @@
jniCheck::validate_object(thr, method);
)
jmethodID result = UNCHECKED()->FromReflectedMethod(env, method);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -475,7 +585,7 @@
jniCheck::validate_object(thr, field);
)
jfieldID result = UNCHECKED()->FromReflectedField(env, field);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -491,7 +601,7 @@
)
jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
isStatic);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -503,7 +613,7 @@
jniCheck::validate_class(thr, sub, true);
)
jclass result = UNCHECKED()->GetSuperclass(env, sub);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -517,7 +627,7 @@
jniCheck::validate_class(thr, sup, true);
)
jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -532,7 +642,7 @@
)
jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID,
isStatic);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -550,7 +660,7 @@
}
)
jint result = UNCHECKED()->Throw(env, obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -565,15 +675,16 @@
jniCheck::validate_throwable_klass(thr, k);
)
jint result = UNCHECKED()->ThrowNew(env, clazz, msg);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
JNI_ENTRY_CHECKED(jthrowable,
checked_jni_ExceptionOccurred(JNIEnv *env))
+ thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr);
jthrowable result = UNCHECKED()->ExceptionOccurred(env);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -581,22 +692,24 @@
checked_jni_ExceptionDescribe(JNIEnv *env))
functionEnterExceptionAllowed(thr);
UNCHECKED()->ExceptionDescribe(env);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_ExceptionClear(JNIEnv *env))
+ thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr);
UNCHECKED()->ExceptionClear(env);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_FatalError(JNIEnv *env,
const char *msg))
+ thr->clear_pending_jni_exception_check();
functionEnter(thr);
UNCHECKED()->FatalError(env, msg);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jint,
@@ -606,7 +719,10 @@
if (capacity < 0)
NativeReportJNIFatalError(thr, "negative capacity");
jint result = UNCHECKED()->PushLocalFrame(env, capacity);
- functionExit(env);
+ if (result == JNI_OK) {
+ thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ }
+ functionExit(thr);
return result;
JNI_END
@@ -615,7 +731,7 @@
jobject result))
functionEnterExceptionAllowed(thr);
jobject res = UNCHECKED()->PopLocalFrame(env, result);
- functionExit(env);
+ functionExit(thr);
return res;
JNI_END
@@ -629,7 +745,7 @@
}
)
jobject result = UNCHECKED()->NewGlobalRef(env,lobj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -645,7 +761,7 @@
}
)
UNCHECKED()->DeleteGlobalRef(env,gref);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -660,7 +776,7 @@
"Invalid local JNI handle passed to DeleteLocalRef");
)
UNCHECKED()->DeleteLocalRef(env, obj);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jboolean,
@@ -681,7 +797,7 @@
}
)
jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -695,7 +811,7 @@
}
)
jobject result = UNCHECKED()->NewLocalRef(env, ref);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -707,7 +823,10 @@
NativeReportJNIFatalError(thr, "negative capacity");
}
jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
- functionExit(env);
+ if (result == JNI_OK) {
+ thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ }
+ functionExit(thr);
return result;
JNI_END
@@ -719,7 +838,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jobject result = UNCHECKED()->AllocObject(env,clazz);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -737,7 +856,7 @@
va_start(args, methodID);
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
va_end(args);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -752,7 +871,7 @@
jniCheck::validate_jmethod_id(thr, methodID);
)
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -767,7 +886,7 @@
jniCheck::validate_jmethod_id(thr, methodID);
)
jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -779,7 +898,7 @@
jniCheck::validate_object(thr, obj);
)
jclass result = UNCHECKED()->GetObjectClass(env,obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -793,7 +912,7 @@
jniCheck::validate_class(thr, clazz, true);
)
jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -807,7 +926,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -826,7 +945,8 @@
ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
args); \
va_end(args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Call"#Result"Method"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -841,7 +961,8 @@
) \
ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Call"#Result"MethodV"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -856,7 +977,8 @@
) \
ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Call"#Result"MethodA"); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -883,7 +1005,8 @@
va_start(args,methodID);
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
va_end(args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallVoidMethod");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -896,7 +1019,8 @@
jniCheck::validate_call_object(thr, obj, methodID);
)
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallVoidMethodV");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -909,7 +1033,8 @@
jniCheck::validate_call_object(thr, obj, methodID);
)
UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallVoidMethodA");
+ functionExit(thr);
JNI_END
#define WRAPPER_CallNonvirtualMethod(ResultType, Result) \
@@ -932,7 +1057,8 @@
methodID,\
args); \
va_end(args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"Method"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -952,7 +1078,8 @@
clazz, \
methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -972,7 +1099,8 @@
clazz, \
methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1001,7 +1129,8 @@
va_start(args,methodID);
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
va_end(args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallNonvirtualVoidMethod");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1016,7 +1145,8 @@
jniCheck::validate_call_class(thr, clazz, methodID);
)
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1031,7 +1161,8 @@
jniCheck::validate_call_class(thr, clazz, methodID);
)
UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jfieldID,
@@ -1044,7 +1175,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1058,7 +1189,7 @@
checkInstanceFieldID(thr, fieldID, obj, FieldType); \
) \
ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \
- functionExit(env); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1083,7 +1214,7 @@
checkInstanceFieldID(thr, fieldID, obj, FieldType); \
) \
UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \
- functionExit(env); \
+ functionExit(thr); \
JNI_END
WRAPPER_SetField(jobject, Object, T_OBJECT)
@@ -1107,7 +1238,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1129,7 +1260,8 @@
methodID, \
args); \
va_end(args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallStatic"#Result"Method"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -1147,7 +1279,8 @@
clazz, \
methodID, \
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -1165,7 +1298,8 @@
clazz, \
methodID, \
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1193,7 +1327,8 @@
va_start(args,methodID);
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
va_end(args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallStaticVoidMethod");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1207,7 +1342,8 @@
jniCheck::validate_class(thr, cls, false);
)
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1221,7 +1357,8 @@
jniCheck::validate_class(thr, cls, false);
)
UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallStaticVoidMethodA");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jfieldID,
@@ -1234,7 +1371,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1251,7 +1388,7 @@
ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \
clazz, \
fieldID); \
- functionExit(env); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1277,7 +1414,7 @@
checkStaticFieldID(thr, fieldID, clazz, FieldType); \
) \
UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \
- functionExit(env); \
+ functionExit(thr); \
JNI_END
WRAPPER_SetStaticField(jobject, Object, T_OBJECT)
@@ -1297,7 +1434,7 @@
jsize len))
functionEnter(thr);
jstring result = UNCHECKED()->NewString(env,unicode,len);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1309,12 +1446,12 @@
checkString(thr, str);
)
jsize result = UNCHECKED()->GetStringLength(env,str);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
// Arbitrary (but well-known) tag
-const jint STRING_TAG = 0x47114711;
+const void* STRING_TAG = (void*)0x47114711;
JNI_ENTRY_CHECKED(const jchar *,
checked_jni_GetStringChars(JNIEnv *env,
@@ -1324,21 +1461,22 @@
IN_VM(
checkString(thr, str);
)
- jchar* newResult = NULL;
+ jchar* new_result = NULL;
const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
if (result != NULL) {
size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
- jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
- *tagLocation = STRING_TAG;
- newResult = (jchar*) (tagLocation + 1);
- memcpy(newResult, result, len * sizeof(jchar));
+ len *= sizeof(jchar);
+ new_result = (jchar*) GuardedMemory::wrap_copy(result, len, STRING_TAG);
+ if (new_result == NULL) {
+ vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringChars");
+ }
// Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
// Note that the dtrace arguments for the allocated memory will not match up with this solution.
FreeHeap((char*)result);
}
- functionExit(env);
- return newResult;
+ functionExit(thr);
+ return new_result;
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1354,13 +1492,25 @@
UNCHECKED()->ReleaseStringChars(env,str,chars);
}
else {
- jint* tagLocation = ((jint*) chars) - 1;
- if (*tagLocation != STRING_TAG) {
- NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars");
- }
- UNCHECKED()->ReleaseStringChars(env,str,(const jchar*)tagLocation);
+ GuardedMemory guarded((void*)chars);
+ if (!guarded.verify_guards()) {
+ tty->print_cr("ReleaseStringChars: release chars failed bounds check. "
+ "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars));
+ guarded.print_on(tty);
+ NativeReportJNIFatalError(thr, "ReleaseStringChars: "
+ "release chars failed bounds check.");
+ }
+ if (guarded.get_tag() != STRING_TAG) {
+ tty->print_cr("ReleaseStringChars: called on something not allocated "
+ "by GetStringChars. string: " PTR_FORMAT " chars: " PTR_FORMAT,
+ p2i(str), p2i(chars));
+ NativeReportJNIFatalError(thr, "ReleaseStringChars called on something "
+ "not allocated by GetStringChars");
+ }
+ UNCHECKED()->ReleaseStringChars(env, str,
+ (const jchar*) guarded.release_for_freeing());
}
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jstring,
@@ -1368,7 +1518,7 @@
const char *utf))
functionEnter(thr);
jstring result = UNCHECKED()->NewStringUTF(env,utf);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1380,12 +1530,12 @@
checkString(thr, str);
)
jsize result = UNCHECKED()->GetStringUTFLength(env,str);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
// Arbitrary (but well-known) tag - different than GetStringChars
-const jint STRING_UTF_TAG = 0x48124812;
+const void* STRING_UTF_TAG = (void*) 0x48124812;
JNI_ENTRY_CHECKED(const char *,
checked_jni_GetStringUTFChars(JNIEnv *env,
@@ -1395,21 +1545,21 @@
IN_VM(
checkString(thr, str);
)
- char* newResult = NULL;
+ char* new_result = NULL;
const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
if (result != NULL) {
size_t len = strlen(result) + 1; // + 1 for NULL termination
- jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
- *tagLocation = STRING_UTF_TAG;
- newResult = (char*) (tagLocation + 1);
- strcpy(newResult, result);
+ new_result = (char*) GuardedMemory::wrap_copy(result, len, STRING_UTF_TAG);
+ if (new_result == NULL) {
+ vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringUTFChars");
+ }
// Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
// Note that the dtrace arguments for the allocated memory will not match up with this solution.
FreeHeap((char*)result, mtInternal);
}
- functionExit(env);
- return newResult;
+ functionExit(thr);
+ return new_result;
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1425,13 +1575,25 @@
UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
}
else {
- jint* tagLocation = ((jint*) chars) - 1;
- if (*tagLocation != STRING_UTF_TAG) {
- NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars");
- }
- UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*)tagLocation);
+ GuardedMemory guarded((void*)chars);
+ if (!guarded.verify_guards()) {
+ tty->print_cr("ReleaseStringUTFChars: release chars failed bounds check. "
+ "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars));
+ guarded.print_on(tty);
+ NativeReportJNIFatalError(thr, "ReleaseStringUTFChars: "
+ "release chars failed bounds check.");
+ }
+ if (guarded.get_tag() != STRING_UTF_TAG) {
+ tty->print_cr("ReleaseStringUTFChars: called on something not "
+ "allocated by GetStringUTFChars. string: " PTR_FORMAT " chars: "
+ PTR_FORMAT, p2i(str), p2i(chars));
+ NativeReportJNIFatalError(thr, "ReleaseStringUTFChars "
+ "called on something not allocated by GetStringUTFChars");
+ }
+ UNCHECKED()->ReleaseStringUTFChars(env, str,
+ (const char*) guarded.release_for_freeing());
}
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jsize,
@@ -1442,7 +1604,7 @@
check_is_array(thr, array);
)
jsize result = UNCHECKED()->GetArrayLength(env,array);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1453,7 +1615,7 @@
jobject init))
functionEnter(thr);
jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1466,7 +1628,8 @@
check_is_obj_array(thr, array);
)
jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
- functionExit(env);
+ thr->set_pending_jni_exception_check("GetObjectArrayElement");
+ functionExit(thr);
return result;
JNI_END
@@ -1480,7 +1643,8 @@
check_is_obj_array(thr, array);
)
UNCHECKED()->SetObjectArrayElement(env,array,index,val);
- functionExit(env);
+ thr->set_pending_jni_exception_check("SetObjectArrayElement");
+ functionExit(thr);
JNI_END
#define WRAPPER_NewScalarArray(Return, Result) \
@@ -1489,7 +1653,7 @@
jsize len)) \
functionEnter(thr); \
Return result = UNCHECKED()->New##Result##Array(env,len); \
- functionExit(env); \
+ functionExit(thr); \
return (Return) result; \
JNI_END
@@ -1514,7 +1678,10 @@
ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \
array, \
isCopy); \
- functionExit(env); \
+ if (result != NULL) { \
+ result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \
+ } \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1538,13 +1705,11 @@
check_primitive_array_type(thr, array, ElementTag); \
ASSERT_OOPS_ALLOWED; \
typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
- /* cannot check validity of copy, unless every request is logged by
- * checking code. Implementation of this check is deferred until a
- * subsequent release.
- */ \
) \
- UNCHECKED()->Release##Result##ArrayElements(env,array,elems,mode); \
- functionExit(env); \
+ ElementType* orig_result = (ElementType *) check_wrapped_array_release( \
+ thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \
+ UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \
+ functionExit(thr); \
JNI_END
WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool)
@@ -1568,7 +1733,8 @@
check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Get"#Result"ArrayRegion"); \
+ functionExit(thr); \
JNI_END
WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
@@ -1592,7 +1758,8 @@
check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Set"#Result"ArrayRegion"); \
+ functionExit(thr); \
JNI_END
WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
@@ -1611,7 +1778,7 @@
jint nMethods))
functionEnter(thr);
jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1620,7 +1787,7 @@
jclass clazz))
functionEnter(thr);
jint result = UNCHECKED()->UnregisterNatives(env,clazz);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1632,7 +1799,7 @@
jniCheck::validate_object(thr, obj);
)
jint result = UNCHECKED()->MonitorEnter(env,obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1644,7 +1811,7 @@
jniCheck::validate_object(thr, obj);
)
jint result = UNCHECKED()->MonitorExit(env,obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1653,7 +1820,7 @@
JavaVM **vm))
functionEnter(thr);
jint result = UNCHECKED()->GetJavaVM(env,vm);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1668,7 +1835,8 @@
checkString(thr, str);
)
UNCHECKED()->GetStringRegion(env, str, start, len, buf);
- functionExit(env);
+ thr->set_pending_jni_exception_check("GetStringRegion");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1682,7 +1850,8 @@
checkString(thr, str);
)
UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
- functionExit(env);
+ thr->set_pending_jni_exception_check("GetStringUTFRegion");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void *,
@@ -1694,7 +1863,10 @@
check_is_primitive_array(thr, array);
)
void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
- functionExit(env);
+ if (result != NULL) {
+ result = check_jni_wrap_copy_array(thr, array, result);
+ }
+ functionExit(thr);
return result;
JNI_END
@@ -1707,11 +1879,10 @@
IN_VM(
check_is_primitive_array(thr, array);
)
- /* The Hotspot JNI code does not use the parameters, so just check the
- * array parameter as a minor sanity check
- */
- UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, carray, mode);
- functionExit(env);
+ // Check the element array...
+ void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode);
+ UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(const jchar*,
@@ -1723,7 +1894,7 @@
checkString(thr, string);
)
const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1739,7 +1910,7 @@
* string parameter as a minor sanity check
*/
UNCHECKED()->ReleaseStringCritical(env, str, chars);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jweak,
@@ -1752,7 +1923,7 @@
}
)
jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1761,14 +1932,15 @@
jweak ref))
functionEnterExceptionAllowed(thr);
UNCHECKED()->DeleteWeakGlobalRef(env, ref);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jboolean,
checked_jni_ExceptionCheck(JNIEnv *env))
+ thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr);
jboolean result = UNCHECKED()->ExceptionCheck(env);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1778,7 +1950,7 @@
jlong capacity))
functionEnter(thr);
jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1787,7 +1959,7 @@
jobject buf))
functionEnter(thr);
void* result = UNCHECKED()->GetDirectBufferAddress(env, buf);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1796,7 +1968,7 @@
jobject buf))
functionEnter(thr);
jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1809,7 +1981,7 @@
jniCheck::validate_object(thr, obj);
)
jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1818,7 +1990,7 @@
checked_jni_GetVersion(JNIEnv *env))
functionEnter(thr);
jint result = UNCHECKED()->GetVersion(env);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -3923,50 +3923,6 @@
}
-// Support for Serialization
-
-typedef jfloat (JNICALL *IntBitsToFloatFn )(JNIEnv* env, jclass cb, jint value);
-typedef jdouble (JNICALL *LongBitsToDoubleFn)(JNIEnv* env, jclass cb, jlong value);
-typedef jint (JNICALL *FloatToIntBitsFn )(JNIEnv* env, jclass cb, jfloat value);
-typedef jlong (JNICALL *DoubleToLongBitsFn)(JNIEnv* env, jclass cb, jdouble value);
-
-static IntBitsToFloatFn int_bits_to_float_fn = NULL;
-static LongBitsToDoubleFn long_bits_to_double_fn = NULL;
-static FloatToIntBitsFn float_to_int_bits_fn = NULL;
-static DoubleToLongBitsFn double_to_long_bits_fn = NULL;
-
-
-void initialize_converter_functions() {
- if (JDK_Version::is_gte_jdk14x_version()) {
- // These functions only exist for compatibility with 1.3.1 and earlier
- return;
- }
-
- // called from universe_post_init()
- assert(
- int_bits_to_float_fn == NULL &&
- long_bits_to_double_fn == NULL &&
- float_to_int_bits_fn == NULL &&
- double_to_long_bits_fn == NULL ,
- "initialization done twice"
- );
- // initialize
- int_bits_to_float_fn = CAST_TO_FN_PTR(IntBitsToFloatFn , NativeLookup::base_library_lookup("java/lang/Float" , "intBitsToFloat" , "(I)F"));
- long_bits_to_double_fn = CAST_TO_FN_PTR(LongBitsToDoubleFn, NativeLookup::base_library_lookup("java/lang/Double", "longBitsToDouble", "(J)D"));
- float_to_int_bits_fn = CAST_TO_FN_PTR(FloatToIntBitsFn , NativeLookup::base_library_lookup("java/lang/Float" , "floatToIntBits" , "(F)I"));
- double_to_long_bits_fn = CAST_TO_FN_PTR(DoubleToLongBitsFn, NativeLookup::base_library_lookup("java/lang/Double", "doubleToLongBits", "(D)J"));
- // verify
- assert(
- int_bits_to_float_fn != NULL &&
- long_bits_to_double_fn != NULL &&
- float_to_int_bits_fn != NULL &&
- double_to_long_bits_fn != NULL ,
- "initialization failed"
- );
-}
-
-
-
// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
--- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -185,64 +185,7 @@
// Get/SetObject must be special-cased, since it works with handles.
-// The xxx140 variants for backward compatibility do not allow a full-width offset.
-UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
- UnsafeWrapper("Unsafe_GetObject");
- if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
- GET_OOP_FIELD(obj, offset, v)
- jobject ret = JNIHandles::make_local(env, v);
-#if INCLUDE_ALL_GCS
- // We could be accessing the referent field in a reference
- // object. If G1 is enabled then we need to register a non-null
- // referent with the SATB barrier.
- if (UseG1GC) {
- bool needs_barrier = false;
-
- if (ret != NULL) {
- if (offset == java_lang_ref_Reference::referent_offset) {
- oop o = JNIHandles::resolve_non_null(obj);
- Klass* k = o->klass();
- if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
- assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
- needs_barrier = true;
- }
- }
- }
-
- if (needs_barrier) {
- oop referent = JNIHandles::resolve(ret);
- G1SATBCardTableModRefBS::enqueue(referent);
- }
- }
-#endif // INCLUDE_ALL_GCS
- return ret;
-UNSAFE_END
-
-UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
- UnsafeWrapper("Unsafe_SetObject");
- if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
- oop x = JNIHandles::resolve(x_h);
- //SET_FIELD(obj, offset, oop, x);
- oop p = JNIHandles::resolve(obj);
- if (UseCompressedOops) {
- if (x != NULL) {
- // If there is a heap base pointer, we are obliged to emit a store barrier.
- oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
- } else {
- narrowOop n = oopDesc::encode_heap_oop_not_null(x);
- *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
- }
- } else {
- if (x != NULL) {
- // If there is a heap base pointer, we are obliged to emit a store barrier.
- oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
- } else {
- *(oop*)index_oop_from_field_offset_long(p, offset) = x;
- }
- }
-UNSAFE_END
-
-// The normal variants allow a null base pointer with an arbitrary address.
+// These functions allow a null base pointer with an arbitrary address.
// But if the base pointer is non-null, the offset should make some sense.
// That is, it should be in the range [0, MAX_OBJECT_SIZE].
UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
@@ -1350,9 +1293,6 @@
// These are the methods for 1.4.0
static JNINativeMethod methods_140[] = {
- {CC"getObject", CC"("OBJ"I)"OBJ"", FN_PTR(Unsafe_GetObject140)},
- {CC"putObject", CC"("OBJ"I"OBJ")V", FN_PTR(Unsafe_SetObject140)},
-
DECLARE_GETSETOOP_140(Boolean, Z),
DECLARE_GETSETOOP_140(Byte, B),
DECLARE_GETSETOOP_140(Short, S),
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -222,10 +222,8 @@
const char* spec_vendor = "Sun Microsystems Inc.";
uint32_t spec_version = 0;
- if (JDK_Version::is_gte_jdk17x_version()) {
- spec_vendor = "Oracle Corporation";
- spec_version = JDK_Version::current().major_version();
- }
+ spec_vendor = "Oracle Corporation";
+ spec_version = JDK_Version::current().major_version();
jio_snprintf(buffer, bufsz, "1." UINT32_FORMAT, spec_version);
PropertyList_add(&_system_properties,
@@ -3699,14 +3697,6 @@
PrintGC = true;
}
- if (!JDK_Version::is_gte_jdk18x_version()) {
- // To avoid changing the log format for 7 updates this flag is only
- // true by default in JDK8 and above.
- if (FLAG_IS_DEFAULT(PrintGCCause)) {
- FLAG_SET_DEFAULT(PrintGCCause, false);
- }
- }
-
// Set object alignment values.
set_object_alignment();
--- a/hotspot/src/share/vm/runtime/java.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/java.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -197,58 +197,6 @@
_runtime_version = version;
}
- // Convenience methods for queries on the current major/minor version
- static bool is_jdk12x_version() {
- return current().compare_major(2) == 0;
- }
-
- static bool is_jdk13x_version() {
- return current().compare_major(3) == 0;
- }
-
- static bool is_jdk14x_version() {
- return current().compare_major(4) == 0;
- }
-
- static bool is_jdk15x_version() {
- return current().compare_major(5) == 0;
- }
-
- static bool is_jdk16x_version() {
- return current().compare_major(6) == 0;
- }
-
- static bool is_jdk17x_version() {
- return current().compare_major(7) == 0;
- }
-
- static bool is_jdk18x_version() {
- return current().compare_major(8) == 0;
- }
-
- static bool is_gte_jdk13x_version() {
- return current().compare_major(3) >= 0;
- }
-
- static bool is_gte_jdk14x_version() {
- return current().compare_major(4) >= 0;
- }
-
- static bool is_gte_jdk15x_version() {
- return current().compare_major(5) >= 0;
- }
-
- static bool is_gte_jdk16x_version() {
- return current().compare_major(6) >= 0;
- }
-
- static bool is_gte_jdk17x_version() {
- return current().compare_major(7) >= 0;
- }
-
- static bool is_gte_jdk18x_version() {
- return current().compare_major(8) >= 0;
- }
};
#endif // SHARE_VM_RUNTIME_JAVA_HPP
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -298,6 +298,7 @@
block->_top = 0;
block->_next = NULL;
block->_pop_frame_link = NULL;
+ block->_planned_capacity = block_size_in_oops;
// _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
debug_only(block->_last = NULL);
debug_only(block->_free_list = NULL);
@@ -531,6 +532,12 @@
return result;
}
+const size_t JNIHandleBlock::get_number_of_live_handles() {
+ CountHandleClosure counter;
+ oops_do(&counter);
+ return counter.count();
+}
+
// This method is not thread-safe, i.e., must be called while holding a lock on the
// structure.
long JNIHandleBlock::memory_usage() const {
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -112,6 +112,9 @@
oop* _free_list; // Handle free list
int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
+ // Check JNI, "planned capacity" for current frame (or push/ensure)
+ size_t _planned_capacity;
+
#ifndef PRODUCT
JNIHandleBlock* _block_list_link; // Link for list below
static JNIHandleBlock* _block_list; // List of all allocated blocks (for debugging only)
@@ -152,6 +155,11 @@
// Traversal of weak handles. Unreachable oops are cleared.
void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
+ // Checked JNI support
+ void set_planned_capacity(size_t planned_capacity) { _planned_capacity = planned_capacity; }
+ const size_t get_planned_capacity() { return _planned_capacity; }
+ const size_t get_number_of_live_handles();
+
// Debugging
bool chain_contains(jobject handle) const; // Does this block or following blocks contain handle
bool contains(jobject handle) const; // Does this block contain handle
--- a/hotspot/src/share/vm/runtime/os.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -32,6 +32,9 @@
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/allocation.inline.hpp"
+#ifdef ASSERT
+#include "memory/guardedMemory.hpp"
+#endif
#include "oops/oop.inline.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
@@ -523,121 +526,20 @@
}
-
-#ifdef ASSERT
-#define space_before (MallocCushion + sizeof(double))
-#define space_after MallocCushion
-#define size_addr_from_base(p) (size_t*)(p + space_before - sizeof(size_t))
-#define size_addr_from_obj(p) ((size_t*)p - 1)
-// MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly
-// NB: cannot be debug variable, because these aren't set from the command line until
-// *after* the first few allocs already happened
-#define MallocCushion 16
-#else
-#define space_before 0
-#define space_after 0
-#define size_addr_from_base(p) should not use w/o ASSERT
-#define size_addr_from_obj(p) should not use w/o ASSERT
-#define MallocCushion 0
-#endif
#define paranoid 0 /* only set to 1 if you suspect checking code has bug */
#ifdef ASSERT
-inline size_t get_size(void* obj) {
- size_t size = *size_addr_from_obj(obj);
- if (size < 0) {
- fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten ("
- SIZE_FORMAT ")", obj, size));
- }
- return size;
-}
-u_char* find_cushion_backwards(u_char* start) {
- u_char* p = start;
- while (p[ 0] != badResourceValue || p[-1] != badResourceValue ||
- p[-2] != badResourceValue || p[-3] != badResourceValue) p--;
- // ok, we have four consecutive marker bytes; find start
- u_char* q = p - 4;
- while (*q == badResourceValue) q--;
- return q + 1;
-}
-
-u_char* find_cushion_forwards(u_char* start) {
- u_char* p = start;
- while (p[0] != badResourceValue || p[1] != badResourceValue ||
- p[2] != badResourceValue || p[3] != badResourceValue) p++;
- // ok, we have four consecutive marker bytes; find end of cushion
- u_char* q = p + 4;
- while (*q == badResourceValue) q++;
- return q - MallocCushion;
-}
-
-void print_neighbor_blocks(void* ptr) {
- // find block allocated before ptr (not entirely crash-proof)
- if (MallocCushion < 4) {
- tty->print_cr("### cannot find previous block (MallocCushion < 4)");
- return;
- }
- u_char* start_of_this_block = (u_char*)ptr - space_before;
- u_char* end_of_prev_block_data = start_of_this_block - space_after -1;
- // look for cushion in front of prev. block
- u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data);
- ptrdiff_t size = *size_addr_from_base(start_of_prev_block);
- u_char* obj = start_of_prev_block + space_before;
- if (size <= 0 ) {
- // start is bad; may have been confused by OS data in between objects
- // search one more backwards
- start_of_prev_block = find_cushion_backwards(start_of_prev_block);
- size = *size_addr_from_base(start_of_prev_block);
- obj = start_of_prev_block + space_before;
- }
-
- if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
- tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
- } else {
- tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
- }
-
- // now find successor block
- u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after;
- start_of_next_block = find_cushion_forwards(start_of_next_block);
- u_char* next_obj = start_of_next_block + space_before;
- ptrdiff_t next_size = *size_addr_from_base(start_of_next_block);
- if (start_of_next_block[0] == badResourceValue &&
- start_of_next_block[1] == badResourceValue &&
- start_of_next_block[2] == badResourceValue &&
- start_of_next_block[3] == badResourceValue) {
- tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
- } else {
- tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
+static void verify_memory(void* ptr) {
+ GuardedMemory guarded(ptr);
+ if (!guarded.verify_guards()) {
+ tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
+ tty->print_cr("## memory stomp:");
+ guarded.print_on(tty);
+ fatal("memory stomping error");
}
}
-
-void report_heap_error(void* memblock, void* bad, const char* where) {
- tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
- tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
- print_neighbor_blocks(memblock);
- fatal("memory stomping error");
-}
-
-void verify_block(void* memblock) {
- size_t size = get_size(memblock);
- if (MallocCushion) {
- u_char* ptr = (u_char*)memblock - space_before;
- for (int i = 0; i < MallocCushion; i++) {
- if (ptr[i] != badResourceValue) {
- report_heap_error(memblock, ptr+i, "in front of");
- }
- }
- u_char* end = (u_char*)memblock + size + space_after;
- for (int j = -MallocCushion; j < 0; j++) {
- if (end[j] != badResourceValue) {
- report_heap_error(memblock, end+j, "after");
- }
- }
- }
-}
#endif
//
@@ -686,16 +588,18 @@
size = 1;
}
- const size_t alloc_size = size + space_before + space_after;
-
+#ifndef ASSERT
+ const size_t alloc_size = size;
+#else
+ const size_t alloc_size = GuardedMemory::get_total_size(size);
if (size > alloc_size) { // Check for rollover.
return NULL;
}
+#endif
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
u_char* ptr;
-
if (MallocMaxTestWords > 0) {
ptr = testMalloc(alloc_size);
} else {
@@ -703,28 +607,26 @@
}
#ifdef ASSERT
- if (ptr == NULL) return NULL;
- if (MallocCushion) {
- for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue;
- u_char* end = ptr + space_before + size;
- for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad;
- for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue;
+ if (ptr == NULL) {
+ return NULL;
}
- // put size just before data
- *size_addr_from_base(ptr) = size;
+ // Wrap memory with guard
+ GuardedMemory guarded(ptr, size);
+ ptr = guarded.get_user_ptr();
#endif
- u_char* memblock = ptr + space_before;
- if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
- tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
+ if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
+ tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
breakpoint();
}
- debug_only(if (paranoid) verify_block(memblock));
- if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
+ debug_only(if (paranoid) verify_memory(ptr));
+ if (PrintMalloc && tty != NULL) {
+ tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
+ }
- // we do not track MallocCushion memory
- MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
+ // we do not track guard memory
+ MemTracker::record_malloc((address)ptr, size, memflags, caller == 0 ? CALLER_PC : caller);
- return memblock;
+ return ptr;
}
@@ -743,27 +645,32 @@
return ptr;
#else
if (memblock == NULL) {
- return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
+ return os::malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
}
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
breakpoint();
}
- verify_block(memblock);
+ verify_memory(memblock);
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
- if (size == 0) return NULL;
+ if (size == 0) {
+ return NULL;
+ }
// always move the block
- void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
- if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
+ void* ptr = os::malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
+ if (PrintMalloc) {
+ tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
+ }
// Copy to new memory if malloc didn't fail
if ( ptr != NULL ) {
- memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
- if (paranoid) verify_block(ptr);
+ GuardedMemory guarded(memblock);
+ memcpy(ptr, memblock, MIN2(size, guarded.get_user_size()));
+ if (paranoid) verify_memory(ptr);
if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
breakpoint();
}
- free(memblock);
+ os::free(memblock);
}
return ptr;
#endif
@@ -771,6 +678,7 @@
void os::free(void *memblock, MEMFLAGS memflags) {
+ address trackp = (address) memblock;
NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
#ifdef ASSERT
if (memblock == NULL) return;
@@ -778,34 +686,20 @@
if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
breakpoint();
}
- verify_block(memblock);
+ verify_memory(memblock);
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
- // Added by detlefs.
- if (MallocCushion) {
- u_char* ptr = (u_char*)memblock - space_before;
- for (u_char* p = ptr; p < ptr + MallocCushion; p++) {
- guarantee(*p == badResourceValue,
- "Thing freed should be malloc result.");
- *p = (u_char)freeBlockPad;
- }
- size_t size = get_size(memblock);
- inc_stat_counter(&free_bytes, size);
- u_char* end = ptr + space_before + size;
- for (u_char* q = end; q < end + MallocCushion; q++) {
- guarantee(*q == badResourceValue,
- "Thing freed should be malloc result.");
- *q = (u_char)freeBlockPad;
- }
- if (PrintMalloc && tty != NULL)
+
+ GuardedMemory guarded(memblock);
+ size_t size = guarded.get_user_size();
+ inc_stat_counter(&free_bytes, size);
+ memblock = guarded.release_for_freeing();
+ if (PrintMalloc && tty != NULL) {
fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
- } else if (PrintMalloc && tty != NULL) {
- // tty->print_cr("os::free %p", memblock);
- fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
}
#endif
- MemTracker::record_free((address)memblock, memflags);
+ MemTracker::record_free(trackp, memflags);
- ::free((char*)memblock - space_before);
+ ::free(memblock);
}
void os::init_random(long initval) {
--- a/hotspot/src/share/vm/runtime/reflection.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -410,49 +410,6 @@
}
-bool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) {
- // field_class : declaring class
- // acc : declared field access
- // target_class : for protected
-
- // Check if field or method is accessible to client. Throw an
- // IllegalAccessException and return false if not.
-
- // The "client" is the class associated with the nearest real frame
- // getCallerClass already skips Method.invoke frames, so pass 0 in
- // that case (same as classic).
- ResourceMark rm(THREAD);
- assert(THREAD->is_Java_thread(), "sanity check");
- Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
-
- if (client_class != field_class) {
- if (!verify_class_access(client_class, field_class, false)
- || !verify_field_access(client_class,
- field_class,
- field_class,
- acc,
- false)) {
- THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
- }
- }
-
- // Additional test for protected members: JLS 6.6.2
-
- if (acc.is_protected()) {
- if (target_class != client_class) {
- if (!is_same_class_package(client_class, field_class)) {
- if (!target_class->is_subclass_of(client_class)) {
- THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
- }
- }
- }
- }
-
- // Passed all tests
- return true;
-}
-
-
bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
// Verify that current_class can access new_class. If the classloader_only
// flag is set, we automatically allow any accesses in which current_class
@@ -463,10 +420,9 @@
is_same_class_package(current_class, new_class)) {
return true;
}
- // New (1.4) reflection implementation. Allow all accesses from
- // sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
- if ( JDK_Version::is_gte_jdk14x_version()
- && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
+ // Allow all accesses from sun/reflect/MagicAccessorImpl subclasses to
+ // succeed trivially.
+ if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
return true;
}
@@ -567,10 +523,9 @@
return true;
}
- // New (1.4) reflection implementation. Allow all accesses from
- // sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
- if ( JDK_Version::is_gte_jdk14x_version()
- && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
+ // Allow all accesses from sun/reflect/MagicAccessorImpl subclasses to
+ // succeed trivially.
+ if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
return true;
}
@@ -707,12 +662,10 @@
oop Reflection::new_method(methodHandle method, bool for_constant_pool_access, TRAPS) {
- // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert.
- // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
+ // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
assert(!method()->is_initializer() ||
- (for_constant_pool_access && method()->is_static()) ||
- (method()->name() == vmSymbols::class_initializer_name()
- && method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
+ (for_constant_pool_access && method()->is_static()),
+ "should call new_constructor instead");
instanceKlassHandle holder (THREAD, method->method_holder());
int slot = method->method_idnum();
@@ -978,22 +931,6 @@
reflected_method->signature()));
}
- // In the JDK 1.4 reflection implementation, the security check is
- // done at the Java level
- if (!JDK_Version::is_gte_jdk14x_version()) {
-
- // Access checking (unless overridden by Method)
- if (!override) {
- if (!(klass->is_public() && reflected_method->is_public())) {
- bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
- if (!access) {
- return NULL; // exception
- }
- }
- }
-
- } // !Universe::is_gte_jdk14x_version()
-
assert(ptypes->is_objArray(), "just checking");
int args_len = args.is_null() ? 0 : args->length();
// Check number of arguments
--- a/hotspot/src/share/vm/runtime/reflection.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -44,9 +44,6 @@
class Reflection: public AllStatic {
private:
- // Access checking
- static bool reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS);
-
// Conversion
static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS);
static oop basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS);
--- a/hotspot/src/share/vm/runtime/reflectionUtils.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/reflectionUtils.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,15 +76,10 @@
int offset;
offset = java_lang_Throwable::get_backtrace_offset();
_filtered_fields->append(new FilteredField(SystemDictionary::Throwable_klass(), offset));
- // The latest version of vm may be used with old jdk.
- if (JDK_Version::is_gte_jdk16x_version()) {
- // The following class fields do not exist in
- // previous version of jdk.
- offset = sun_reflect_ConstantPool::oop_offset();
- _filtered_fields->append(new FilteredField(SystemDictionary::reflect_ConstantPool_klass(), offset));
- offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
- _filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
- }
+ offset = sun_reflect_ConstantPool::oop_offset();
+ _filtered_fields->append(new FilteredField(SystemDictionary::reflect_ConstantPool_klass(), offset));
+ offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
+ _filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
}
int FilteredFieldStream::field_count() {
--- a/hotspot/src/share/vm/runtime/serviceThread.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/serviceThread.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,8 +41,7 @@
instanceKlassHandle klass (THREAD, SystemDictionary::Thread_klass());
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK);
- const char* name = JDK_Version::is_gte_jdk17x_version() ?
- "Service Thread" : "Low Memory Detector";
+ const char* name = "Service Thread";
Handle string = java_lang_String::create_from_str(name, CHECK);
--- a/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -26,6 +26,7 @@
#include "prims/jni.h"
#include "runtime/interfaceSupport.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "runtime/sharedRuntimeMath.hpp"
// This file contains copies of the fdlibm routines used by
// StrictMath. It turns out that it is almost always required to use
@@ -36,35 +37,6 @@
// pointer out to libjava.so in SharedRuntime speeds these routines up
// by roughly 15% on both Win32/x86 and Solaris/SPARC.
-// Enabling optimizations in this file causes incorrect code to be
-// generated; can not figure out how to turn down optimization for one
-// file in the IDE on Windows
-#ifdef WIN32
-# pragma optimize ( "", off )
-#endif
-
-/* The above workaround now causes more problems with the latest MS compiler.
- * Visual Studio 2010's /GS option tries to guard against buffer overruns.
- * /GS is on by default if you specify optimizations, which we do globally
- * via /W3 /O2. However the above selective turning off of optimizations means
- * that /GS issues a warning "4748". And since we treat warnings as errors (/WX)
- * then the compilation fails. There are several possible solutions
- * (1) Remove that pragma above as obsolete with VS2010 - requires testing.
- * (2) Stop treating warnings as errors - would be a backward step
- * (3) Disable /GS - may help performance but you lose the security checks
- * (4) Disable the warning with "#pragma warning( disable : 4748 )"
- * (5) Disable planting the code with __declspec(safebuffers)
- * I've opted for (5) although we should investigate the local performance
- * benefits of (1) and global performance benefit of (3).
- */
-#if defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1600))
-#define SAFEBUF __declspec(safebuffers)
-#else
-#define SAFEBUF
-#endif
-
-#include "runtime/sharedRuntimeMath.hpp"
-
/*
* __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
* double x[],y[]; int e0,nx,prec; int ipio2[];
@@ -201,7 +173,7 @@
two24B = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
-static SAFEBUF int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2) {
+static int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2) {
int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
double z,fw,f[20],fq[20],q[20];
@@ -417,7 +389,7 @@
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
-static SAFEBUF int __ieee754_rem_pio2(double x, double *y) {
+static int __ieee754_rem_pio2(double x, double *y) {
double z,w,t,r,fn;
double tx[3];
int e0,i,j,nx,n,ix,hx,i0;
@@ -916,8 +888,3 @@
-1 -- n odd */
}
JRT_END
-
-
-#ifdef WIN32
-# pragma optimize ( "", on )
-#endif
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1448,6 +1448,7 @@
_thread_stat = new ThreadStatistics();
_blocked_on_compilation = false;
_jni_active_critical = 0;
+ _pending_jni_exception_check_fn = NULL;
_do_not_unlock_if_synchronized = false;
_cached_monitor_info = NULL;
_parker = Parker::Allocate(this) ;
@@ -1738,55 +1739,26 @@
CLEAR_PENDING_EXCEPTION;
}
- // FIXIT: The is_null check is only so it works better on JDK1.2 VM's. This
- // has to be fixed by a runtime query method
- if (!destroy_vm || JDK_Version::is_jdk12x_version()) {
- // JSR-166: change call from from ThreadGroup.uncaughtException to
- // java.lang.Thread.dispatchUncaughtException
+ if (!destroy_vm) {
if (uncaught_exception.not_null()) {
- Handle group(this, java_lang_Thread::threadGroup(threadObj()));
- {
- EXCEPTION_MARK;
- // Check if the method Thread.dispatchUncaughtException() exists. If so
- // call it. Otherwise we have an older library without the JSR-166 changes,
- // so call ThreadGroup.uncaughtException()
- KlassHandle recvrKlass(THREAD, threadObj->klass());
- CallInfo callinfo;
- KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
- LinkResolver::resolve_virtual_call(callinfo, threadObj, recvrKlass, thread_klass,
- vmSymbols::dispatchUncaughtException_name(),
- vmSymbols::throwable_void_signature(),
- KlassHandle(), false, false, THREAD);
+ EXCEPTION_MARK;
+ // Call method Thread.dispatchUncaughtException().
+ KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
+ JavaValue result(T_VOID);
+ JavaCalls::call_virtual(&result,
+ threadObj, thread_klass,
+ vmSymbols::dispatchUncaughtException_name(),
+ vmSymbols::throwable_void_signature(),
+ uncaught_exception,
+ THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ ResourceMark rm(this);
+ jio_fprintf(defaultStream::error_stream(),
+ "\nException: %s thrown from the UncaughtExceptionHandler"
+ " in thread \"%s\"\n",
+ pending_exception()->klass()->external_name(),
+ get_thread_name());
CLEAR_PENDING_EXCEPTION;
- methodHandle method = callinfo.selected_method();
- if (method.not_null()) {
- JavaValue result(T_VOID);
- JavaCalls::call_virtual(&result,
- threadObj, thread_klass,
- vmSymbols::dispatchUncaughtException_name(),
- vmSymbols::throwable_void_signature(),
- uncaught_exception,
- THREAD);
- } else {
- KlassHandle thread_group(THREAD, SystemDictionary::ThreadGroup_klass());
- JavaValue result(T_VOID);
- JavaCalls::call_virtual(&result,
- group, thread_group,
- vmSymbols::uncaughtException_name(),
- vmSymbols::thread_throwable_void_signature(),
- threadObj, // Arg 1
- uncaught_exception, // Arg 2
- THREAD);
- }
- if (HAS_PENDING_EXCEPTION) {
- ResourceMark rm(this);
- jio_fprintf(defaultStream::error_stream(),
- "\nException: %s thrown from the UncaughtExceptionHandler"
- " in thread \"%s\"\n",
- pending_exception()->klass()->external_name(),
- get_thread_name());
- CLEAR_PENDING_EXCEPTION;
- }
}
}
@@ -2848,7 +2820,7 @@
Thread::print_on(st);
// print guess for valid stack memory region (assume 4K pages); helps lock debugging
st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
- if (thread_oop != NULL && JDK_Version::is_gte_jdk15x_version()) {
+ if (thread_oop != NULL) {
st->print_cr(" java.lang.Thread.State: %s", java_lang_Thread::thread_status_name(thread_oop));
}
#ifndef PRODUCT
@@ -3948,15 +3920,8 @@
}
os::wait_for_keypress_at_exit();
- if (JDK_Version::is_jdk12x_version()) {
- // We are the last thread running, so check if finalizers should be run.
- // For 1.3 or later this is done in thread->invoke_shutdown_hooks()
- HandleMark rm(thread);
- Universe::run_finalizers_on_exit();
- } else {
- // run Java level shutdown hooks
- thread->invoke_shutdown_hooks();
- }
+ // run Java level shutdown hooks
+ thread->invoke_shutdown_hooks();
before_exit(thread);
--- a/hotspot/src/share/vm/runtime/thread.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -915,6 +915,9 @@
// support for JNI critical regions
jint _jni_active_critical; // count of entries into JNI critical region
+ // Checked JNI: function name requires exception check
+ char* _pending_jni_exception_check_fn;
+
// For deadlock detection.
int _depth_first_number;
@@ -1400,6 +1403,12 @@
assert(_jni_active_critical >= 0,
"JNI critical nesting problem?"); }
+ // Checked JNI, is the programmer required to check for exceptions, specify which function name
+ bool is_pending_jni_exception_check() const { return _pending_jni_exception_check_fn != NULL; }
+ void clear_pending_jni_exception_check() { _pending_jni_exception_check_fn = NULL; }
+ const char* get_pending_jni_exception_check() const { return _pending_jni_exception_check_fn; }
+ void set_pending_jni_exception_check(const char* fn_name) { _pending_jni_exception_check_fn = (char*) fn_name; }
+
// For deadlock detection
int depth_first_number() { return _depth_first_number; }
void set_depth_first_number(int dfn) { _depth_first_number = dfn; }
--- a/hotspot/src/share/vm/runtime/vframe.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/vframe.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -480,9 +480,8 @@
void vframeStreamCommon::skip_reflection_related_frames() {
while (!at_end() &&
- (JDK_Version::is_gte_jdk14x_version() &&
(method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) ||
- method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) {
+ method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass()))) {
next();
}
}
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -184,9 +184,7 @@
assert(Thread::current()->is_Java_thread(), "just checking");
// Make sure AbstractOwnableSynchronizer is loaded
- if (JDK_Version::is_gte_jdk16x_version()) {
- java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
- }
+ java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
// Get Heap_lock if concurrent locks will be dumped
if (_print_concurrent_locks) {
@@ -225,7 +223,7 @@
assert(Thread::current()->is_Java_thread(), "just checking");
// Load AbstractOwnableSynchronizer class
- if (_concurrent_locks && JDK_Version::is_gte_jdk16x_version()) {
+ if (_concurrent_locks) {
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
}
@@ -283,9 +281,7 @@
assert(Thread::current()->is_Java_thread(), "just checking");
// Load AbstractOwnableSynchronizer class before taking thread snapshots
- if (JDK_Version::is_gte_jdk16x_version()) {
- java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
- }
+ java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
if (_with_locked_synchronizers) {
// Acquire Heap_lock to dump concurrent locks
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Fri Jun 13 19:07:11 2014 -0700
@@ -98,6 +98,7 @@
template(LinuxDllLoad) \
template(RotateGCLog) \
template(WhiteBoxOperation) \
+ template(ClassLoaderStatsOperation) \
class VM_Operation: public CHeapObj<mtInternal> {
public:
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -160,8 +160,7 @@
#ifdef VENDOR
return XSTR(VENDOR);
#else
- return JDK_Version::is_gte_jdk17x_version() ?
- "Oracle Corporation" : "Sun Microsystems Inc.";
+ return "Oracle Corporation";
#endif
}
@@ -222,20 +221,12 @@
#ifndef HOTSPOT_BUILD_COMPILER
#ifdef _MSC_VER
- #if _MSC_VER == 1100
- #define HOTSPOT_BUILD_COMPILER "MS VC++ 5.0"
- #elif _MSC_VER == 1200
- #define HOTSPOT_BUILD_COMPILER "MS VC++ 6.0"
- #elif _MSC_VER == 1310
- #define HOTSPOT_BUILD_COMPILER "MS VC++ 7.1 (VS2003)"
- #elif _MSC_VER == 1400
- #define HOTSPOT_BUILD_COMPILER "MS VC++ 8.0 (VS2005)"
- #elif _MSC_VER == 1500
- #define HOTSPOT_BUILD_COMPILER "MS VC++ 9.0 (VS2008)"
- #elif _MSC_VER == 1600
+ #if _MSC_VER == 1600
#define HOTSPOT_BUILD_COMPILER "MS VC++ 10.0 (VS2010)"
#elif _MSC_VER == 1700
#define HOTSPOT_BUILD_COMPILER "MS VC++ 11.0 (VS2012)"
+ #elif _MSC_VER == 1800
+ #define HOTSPOT_BUILD_COMPILER "MS VC++ 12.0 (VS2013)"
#else
#define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER)
#endif
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/classLoaderStats.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
@@ -58,6 +59,7 @@
#endif // INCLUDE_SERVICES
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
// Enhanced JMX Agent Support
// These commands won't be exported via the DiagnosticCommandMBean until an
--- a/hotspot/src/share/vm/services/management.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/services/management.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -1229,10 +1229,8 @@
"The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
}
- if (JDK_Version::is_gte_jdk16x_version()) {
- // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
- java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
- }
+ // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
+ java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
// Must use ThreadDumpResult to store the ThreadSnapshot.
// GC may occur after the thread snapshots are taken but before
@@ -1303,10 +1301,8 @@
JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, jboolean locked_synchronizers))
ResourceMark rm(THREAD);
- if (JDK_Version::is_gte_jdk16x_version()) {
- // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
- java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
- }
+ // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
+ java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
int num_threads = (ta != NULL ? ta->length() : 0);
--- a/hotspot/src/share/vm/services/threadService.cpp Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/src/share/vm/services/threadService.cpp Fri Jun 13 19:07:11 2014 -0700
@@ -665,17 +665,15 @@
// dump all locked concurrent locks
assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
- if (JDK_Version::is_gte_jdk16x_version()) {
- ResourceMark rm;
+ ResourceMark rm;
- GrowableArray<oop>* aos_objects = new GrowableArray<oop>(INITIAL_ARRAY_SIZE);
+ GrowableArray<oop>* aos_objects = new GrowableArray<oop>(INITIAL_ARRAY_SIZE);
- // Find all instances of AbstractOwnableSynchronizer
- HeapInspection::find_instances_at_safepoint(SystemDictionary::abstract_ownable_synchronizer_klass(),
+ // Find all instances of AbstractOwnableSynchronizer
+ HeapInspection::find_instances_at_safepoint(SystemDictionary::abstract_ownable_synchronizer_klass(),
aos_objects);
- // Build a map of thread to its owned AQS locks
- build_map(aos_objects);
- }
+ // Build a map of thread to its owned AQS locks
+ build_map(aos_objects);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/EnclosingMethodAttr/EnclMethTest.jcod Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This test has a EnclosingMethod attribute with an illegal
+ * attribute_length field value of 6. This should cause a
+ * java.lang.ClassFormatError exception to be thrown.
+ */
+
+class EnclMethTest {
+ 0xCAFEBABE;
+ 0; // minor version
+ 52; // version
+ [22] { // Constant Pool
+ ; // first element is empty
+ Field #3 #14; // #1 at 0x0A
+ Method #4 #15; // #2 at 0x0F
+ class #16; // #3 at 0x14
+ class #19; // #4 at 0x17
+ Utf8 "this$0"; // #5 at 0x1A
+ Utf8 "La;"; // #6 at 0x23
+ Utf8 "Synthetic"; // #7 at 0x29
+ Utf8 "<init>"; // #8 at 0x35
+ Utf8 "(Ljava/lang/Object;)V"; // #9 at 0x3E
+ Utf8 "Code"; // #10 at 0x56
+ Utf8 "LineNumberTable"; // #11 at 0x5D
+ Utf8 "SourceFile"; // #12 at 0x6F
+ Utf8 "a.java"; // #13 at 0x7C
+ NameAndType #5 #6; // #14 at 0x85
+ NameAndType #8 #20; // #15 at 0x8A
+ Utf8 "EnclMethTest"; // #16 at 0x8F
+ Utf8 "Loc"; // #17 at 0x9E
+ Utf8 "InnerClasses"; // #18 at 0xA4
+ Utf8 "java/lang/Object"; // #19 at 0xB3
+ Utf8 "()V"; // #20 at 0xC6
+ Utf8 "EnclosingMethod"; // #21 at 0xCC
+ } // Constant Pool
+
+ 0x0000; // access
+ #3;// this_cpx
+ #4;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [1] { // fields
+ { // Member at 0xE8
+ 0x0000; // access
+ #5; // name_cpx
+ #6; // sig_cpx
+ [1] { // Attributes
+ Attr(#7, 0) { // Synthetic at 0xF0
+ } // end Synthetic
+ } // Attributes
+ } // Member
+ } // fields
+
+ [1] { // methods
+ { // Member at 0xF8
+ 0x0001; // access
+ #8; // name_cpx
+ #20; // sig_cpx
+ [1] { // Attributes
+ Attr(#10, 17) { // Code at 0x0100
+ 2; // max_stack
+ 2; // max_locals
+ Bytes[5]{
+ 0x2AB70002B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [3] { // Attributes
+ Attr(#12, 2) { // SourceFile at 0x0119
+ #13;
+ } // end SourceFile
+ ;
+ Attr(#18, 10) { // InnerClasses at 0x0121
+ [1] { // InnerClasses
+ #3 #0 #17 0; // at 0x0131
+ }
+ } // end InnerClasses
+ ;
+ Attr(#21, 6) { // EnclosingMethod at 0x0131
+ // invalid length of EnclosingMethod attr: 6 (should be 4) !!
+ 0x0004000F;
+ } // end EnclosingMethod
+ } // Attributes
+} // end class EnclMethTest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8044738
+ * @library /testlibrary
+ * @summary Check attribute_length of EnclosingMethod attribute
+ * @run main EnclMethodAttr
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.*;
+
+public class EnclMethodAttr {
+
+ static final String testsrc = System.getProperty("test.src");
+
+ public static void main(String args[]) throws Throwable {
+ System.out.println("Regression test for bug 8044738");
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-jar", testsrc + File.separator + "enclMethodAttr.jar");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("java.lang.ClassFormatError: Wrong EnclosingMethod");
+ }
+}
+
Binary file hotspot/test/runtime/EnclosingMethodAttr/enclMethodAttr.jar has changed
--- a/hotspot/test/runtime/Thread/TestThreadDumpMonitorContention.java Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/test/runtime/Thread/TestThreadDumpMonitorContention.java Fri Jun 13 19:07:11 2014 -0700
@@ -24,6 +24,7 @@
/*
* @test
* @bug 8036823
+ * @bug 8046287
* @summary Creates two threads contending for the same lock and checks
* whether jstack reports "locked" by more than one thread.
*
@@ -52,10 +53,13 @@
// looking for header lines with these patterns:
// "ContendingThread-1" #19 prio=5 os_prio=64 tid=0x000000000079c000 nid=0x23 runnable [0xffff80ffb8b87000]
// "ContendingThread-2" #21 prio=5 os_prio=64 tid=0x0000000000780000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
+ // "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
final static Pattern HEADER_PREFIX_PATTERN = Pattern.compile(
"^\"ContendingThread-.*");
- final static Pattern HEADER_WAITING_PATTERN = Pattern.compile(
+ final static Pattern HEADER_WAITING_PATTERN1 = Pattern.compile(
"^\"ContendingThread-.* waiting for monitor entry .*");
+ final static Pattern HEADER_WAITING_PATTERN2 = Pattern.compile(
+ "^\"ContendingThread-.* waiting on condition .*");
final static Pattern HEADER_RUNNABLE_PATTERN = Pattern.compile(
"^\"ContendingThread-.* runnable .*");
@@ -80,17 +84,34 @@
final static Pattern WAITING_PATTERN = Pattern.compile(
".* waiting to lock \\<.*\\(a TestThreadDumpMonitorContention.*");
+ final static Object barrier = new Object();
volatile static boolean done = false;
+ static int barrier_cnt = 0;
+ static int blank_line_match_cnt = 0;
static int error_cnt = 0;
- static String header_line = null;
static boolean have_header_line = false;
static boolean have_thread_state_line = false;
- static int match_cnt = 0;
- static String[] match_list = new String[2];
+ static String header_line = null;
+ static int header_prefix_match_cnt = 0;
+ static int locked_line_match_cnt = 0;
+ static String[] locked_match_list = new String[2];
static int n_samples = 15;
+ static int sum_both_running_cnt = 0;
+ static int sum_both_waiting_cnt = 0;
+ static int sum_contended_cnt = 0;
+ static int sum_locked_hdr_runnable_cnt = 0;
+ static int sum_locked_hdr_waiting1_cnt = 0;
+ static int sum_locked_hdr_waiting2_cnt = 0;
+ static int sum_locked_thr_state_blocked_cnt = 0;
+ static int sum_locked_thr_state_runnable_cnt = 0;
+ static int sum_one_waiting_cnt = 0;
+ static int sum_uncontended_cnt = 0;
+ static int sum_waiting_hdr_waiting1_cnt = 0;
+ static int sum_waiting_thr_state_blocked_cnt = 0;
static String thread_state_line = null;
static boolean verbose = false;
+ static int waiting_line_match_cnt = 0;
public static void main(String[] args) throws Exception {
if (args.length != 0) {
@@ -110,6 +131,11 @@
Runnable runnable = new Runnable() {
public void run() {
+ synchronized (barrier) {
+ // let the main thread know we're running
+ barrier_cnt++;
+ barrier.notify();
+ }
while (!done) {
synchronized (this) { }
}
@@ -118,8 +144,16 @@
Thread[] thread_list = new Thread[2];
thread_list[0] = new Thread(runnable, "ContendingThread-1");
thread_list[1] = new Thread(runnable, "ContendingThread-2");
- thread_list[0].start();
- thread_list[1].start();
+ synchronized (barrier) {
+ thread_list[0].start();
+ thread_list[1].start();
+
+ // Wait until the contending threads are running so that
+ // we don't sample any thread init states.
+ while (barrier_cnt < 2) {
+ barrier.wait();
+ }
+ }
doSamples();
@@ -143,11 +177,12 @@
// Example:
// "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
// java.lang.Thread.State: RUNNABLE
- // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
+ // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
// at java.lang.Thread.run(Thread.java:745)
//
static boolean checkBlankLine(String line) {
if (line.length() == 0) {
+ blank_line_match_cnt++;
have_header_line = false;
have_thread_state_line = false;
return true;
@@ -161,49 +196,73 @@
// Example 1:
// "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
// java.lang.Thread.State: RUNNABLE
- // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
+ // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
// - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
// at java.lang.Thread.run(Thread.java:745)
//
// Example 2:
// "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
// java.lang.Thread.State: BLOCKED (on object monitor)
- // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
+ // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
// - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
// at java.lang.Thread.run(Thread.java:745)
//
+ // Example 3:
+ // "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
+ // java.lang.Thread.State: RUNNABLE
+ // JavaThread state: _thread_blocked
+ // Thread: 0x0000000000ec8800 [0x31] State: _at_safepoint _has_called_back 0 _at_poll_safepoint 0
+ // JavaThread state: _thread_blocked
+ // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
+ // - locked <0xfffffd7e6d03eb28> (a TestThreadDumpMonitorContention$1)
+ // at java.lang.Thread.run(Thread.java:745)
+ //
static boolean checkLockedLine(String line) {
Matcher matcher = LOCK_PATTERN.matcher(line);
if (matcher.matches()) {
if (verbose) {
System.out.println("locked_line='" + line + "'");
}
- match_list[match_cnt] = new String(line);
- match_cnt++;
+ locked_match_list[locked_line_match_cnt] = new String(line);
+ locked_line_match_cnt++;
matcher = HEADER_RUNNABLE_PATTERN.matcher(header_line);
- if (!matcher.matches()) {
+ if (matcher.matches()) {
+ sum_locked_hdr_runnable_cnt++;
+ } else {
// It's strange, but a locked line can also
- // match the HEADER_WAITING_PATTERN.
- matcher = HEADER_WAITING_PATTERN.matcher(header_line);
- if (!matcher.matches()) {
- System.err.println();
- System.err.println("ERROR: header line does " +
- "not match runnable or waiting patterns.");
- System.err.println("ERROR: header_line='" +
- header_line + "'");
- System.err.println("ERROR: locked_line='" + line + "'");
- error_cnt++;
+ // match the HEADER_WAITING_PATTERN{1,2}.
+ matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
+ if (matcher.matches()) {
+ sum_locked_hdr_waiting1_cnt++;
+ } else {
+ matcher = HEADER_WAITING_PATTERN2.matcher(header_line);
+ if (matcher.matches()) {
+ sum_locked_hdr_waiting2_cnt++;
+ } else {
+ System.err.println();
+ System.err.println("ERROR: header line does " +
+ "not match runnable or waiting patterns.");
+ System.err.println("ERROR: header_line='" +
+ header_line + "'");
+ System.err.println("ERROR: locked_line='" + line +
+ "'");
+ error_cnt++;
+ }
}
}
matcher = THREAD_STATE_RUNNABLE_PATTERN.matcher(thread_state_line);
- if (!matcher.matches()) {
+ if (matcher.matches()) {
+ sum_locked_thr_state_runnable_cnt++;
+ } else {
// It's strange, but a locked line can also
// match the THREAD_STATE_BLOCKED_PATTERN.
matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(
thread_state_line);
- if (!matcher.matches()) {
+ if (matcher.matches()) {
+ sum_locked_thr_state_blocked_cnt++;
+ } else {
System.err.println();
System.err.println("ERROR: thread state line does not " +
"match runnable or waiting patterns.");
@@ -229,19 +288,22 @@
// Example:
// "ContendingThread-2" #22 prio=5 os_prio=64 tid=0x00000000007b9800 nid=0x30 waiting for monitor entry [0xfffffd7fc1010000]
// java.lang.Thread.State: BLOCKED (on object monitor)
- // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
+ // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
// - waiting to lock <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
// at java.lang.Thread.run(Thread.java:745)
//
static boolean checkWaitingLine(String line) {
Matcher matcher = WAITING_PATTERN.matcher(line);
if (matcher.matches()) {
+ waiting_line_match_cnt++;
if (verbose) {
System.out.println("waiting_line='" + line + "'");
}
- matcher = HEADER_WAITING_PATTERN.matcher(header_line);
- if (!matcher.matches()) {
+ matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
+ if (matcher.matches()) {
+ sum_waiting_hdr_waiting1_cnt++;
+ } else {
System.err.println();
System.err.println("ERROR: header line does " +
"not match a waiting pattern.");
@@ -251,7 +313,9 @@
}
matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(thread_state_line);
- if (!matcher.matches()) {
+ if (matcher.matches()) {
+ sum_waiting_thr_state_blocked_cnt++;
+ } else {
System.err.println();
System.err.println("ERROR: thread state line " +
"does not match a waiting pattern.");
@@ -273,7 +337,10 @@
static void doSamples() throws Exception {
for (int count = 0; count < n_samples; count++) {
- match_cnt = 0;
+ blank_line_match_cnt = 0;
+ header_prefix_match_cnt = 0;
+ locked_line_match_cnt = 0;
+ waiting_line_match_cnt = 0;
// verbose mode or an error has a lot of output so add more space
if (verbose || error_cnt > 0) System.out.println();
System.out.println("Sample #" + count);
@@ -290,12 +357,12 @@
// a failure and we report it
// - for a stack trace that matches LOCKED_PATTERN, we verify:
// - the header line matches HEADER_RUNNABLE_PATTERN
- // or HEADER_WAITING_PATTERN
+ // or HEADER_WAITING_PATTERN{1,2}
// - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
// or THREAD_STATE_RUNNABLE_PATTERN
// - we report any mismatches as failures
// - for a stack trace that matches WAITING_PATTERN, we verify:
- // - the header line matches HEADER_WAITING_PATTERN
+ // - the header line matches HEADER_WAITING_PATTERN1
// - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
// - we report any mismatches as failures
// - the stack traces that match HEADER_PREFIX_PATTERN may
@@ -324,6 +391,7 @@
if (!have_header_line) {
matcher = HEADER_PREFIX_PATTERN.matcher(line);
if (matcher.matches()) {
+ header_prefix_match_cnt++;
if (verbose) {
System.out.println();
System.out.println("header='" + line + "'");
@@ -366,19 +434,80 @@
}
process.waitFor();
- if (match_cnt == 2) {
- if (match_list[0].equals(match_list[1])) {
- System.err.println();
- System.err.println("ERROR: matching lock lines:");
- System.err.println("ERROR: line[0]'" + match_list[0] + "'");
- System.err.println("ERROR: line[1]'" + match_list[1] + "'");
- error_cnt++;
- }
- }
+ if (header_prefix_match_cnt != 2) {
+ System.err.println();
+ System.err.println("ERROR: should match exactly two headers.");
+ System.err.println("ERROR: header_prefix_match_cnt=" +
+ header_prefix_match_cnt);
+ error_cnt++;
+ }
+
+ if (locked_line_match_cnt == 2) {
+ if (locked_match_list[0].equals(locked_match_list[1])) {
+ System.err.println();
+ System.err.println("ERROR: matching lock lines:");
+ System.err.println("ERROR: line[0]'" +
+ locked_match_list[0] + "'");
+ System.err.println("ERROR: line[1]'" +
+ locked_match_list[1] + "'");
+ error_cnt++;
+ }
+ }
+
+ if (locked_line_match_cnt == 1) {
+ // one thread has the lock
+ if (waiting_line_match_cnt == 1) {
+ // and the other contended for it
+ sum_contended_cnt++;
+ } else {
+ // and the other is just running
+ sum_uncontended_cnt++;
+ }
+ } else if (waiting_line_match_cnt == 1) {
+ // one thread is waiting
+ sum_one_waiting_cnt++;
+ } else if (waiting_line_match_cnt == 2) {
+ // both threads are waiting
+ sum_both_waiting_cnt++;
+ } else {
+ // both threads are running
+ sum_both_running_cnt++;
+ }
// slight delay between jstack launches
Thread.sleep(500);
}
+
+ if (error_cnt != 0) {
+ // skip summary info since there were errors
+ return;
+ }
+
+ System.out.println("INFO: Summary for all samples:");
+ System.out.println("INFO: both_running_cnt=" + sum_both_running_cnt);
+ System.out.println("INFO: both_waiting_cnt=" + sum_both_waiting_cnt);
+ System.out.println("INFO: contended_cnt=" + sum_contended_cnt);
+ System.out.println("INFO: one_waiting_cnt=" + sum_one_waiting_cnt);
+ System.out.println("INFO: uncontended_cnt=" + sum_uncontended_cnt);
+ System.out.println("INFO: locked_hdr_runnable_cnt=" +
+ sum_locked_hdr_runnable_cnt);
+ System.out.println("INFO: locked_hdr_waiting1_cnt=" +
+ sum_locked_hdr_waiting1_cnt);
+ System.out.println("INFO: locked_hdr_waiting2_cnt=" +
+ sum_locked_hdr_waiting2_cnt);
+ System.out.println("INFO: locked_thr_state_blocked_cnt=" +
+ sum_locked_thr_state_blocked_cnt);
+ System.out.println("INFO: locked_thr_state_runnable_cnt=" +
+ sum_locked_thr_state_runnable_cnt);
+ System.out.println("INFO: waiting_hdr_waiting1_cnt=" +
+ sum_waiting_hdr_waiting1_cnt);
+ System.out.println("INFO: waiting_thr_state_blocked_cnt=" +
+ sum_waiting_thr_state_blocked_cnt);
+
+ if (sum_contended_cnt == 0) {
+ System.err.println("WARNING: the primary scenario for 8036823" +
+ " has not been exercised by this test run.");
+ }
}
// This helper relies on RuntimeMXBean.getName() returning a string
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java Fri Jun 13 19:07:11 2014 -0700
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ *
+ * @build ClassLoaderStatsTest DcmdUtil
+ * @run main ClassLoaderStatsTest
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassLoaderStatsTest {
+
+ // ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
+ // 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader>
+ // 455 1210368 672848 + unsafe anonymous classes
+ // 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader
+ // 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader
+ // ...
+
+ static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
+ static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
+
+ public static DummyClassLoader dummyloader;
+
+ public static void main(String arg[]) throws Exception {
+
+ // create a classloader and load our special class
+ dummyloader = new DummyClassLoader();
+ Class<?> c = Class.forName("TestClass", true, dummyloader);
+ if (c.getClassLoader() != dummyloader) {
+ throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
+ }
+
+ String result = DcmdUtil.executeDcmd("VM.classloader_stats");
+ BufferedReader r = new BufferedReader(new StringReader(result));
+ String line;
+ while((line = r.readLine()) != null) {
+ Matcher m = clLine.matcher(line);
+ if (m.matches()) {
+ // verify that DummyClassLoader has loaded 1 class and 1 anonymous class
+ if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
+ System.out.println("line: " + line);
+ if (!m.group(1).equals("1")) {
+ throw new Exception("Should have loaded 1 class: " + line);
+ }
+ checkPositiveInt(m.group(2));
+ checkPositiveInt(m.group(3));
+
+ String next = r.readLine();
+ System.out.println("next: " + next);
+ Matcher m1 = anonLine.matcher(next);
+ m1.matches();
+ if (!m1.group(1).equals("1")) {
+ throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
+ }
+ checkPositiveInt(m1.group(2));
+ checkPositiveInt(m1.group(3));
+ }
+ }
+ }
+ }
+
+ private static void checkPositiveInt(String s) throws Exception {
+ if (Integer.parseInt(s) <= 0) {
+ throw new Exception("Value should have been > 0: " + s);
+ }
+ }
+
+ public static class DummyClassLoader extends ClassLoader {
+
+ public static final String CLASS_NAME = "TestClass";
+
+ static ByteBuffer readClassFile(String name)
+ {
+ File f = new File(System.getProperty("test.classes", "."),
+ name);
+ try (FileInputStream fin = new FileInputStream(f);
+ FileChannel fc = fin.getChannel())
+ {
+ return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+ } catch (IOException e) {
+ throw new RuntimeException("Can't open file: " + name, e);
+ }
+ }
+
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ Class<?> c;
+ if (!"TestClass".equals(name)) {
+ c = super.loadClass(name, resolve);
+ } else {
+ // should not delegate to the system class loader
+ c = findClass(name);
+ if (resolve) {
+ resolveClass(c);
+ }
+ }
+ return c;
+ }
+
+ protected Class<?> findClass(String name)
+ throws ClassNotFoundException
+ {
+ if (!"TestClass".equals(name)) {
+ throw new ClassNotFoundException("Unexpected class: " + name);
+ }
+ return defineClass(name, readClassFile(name + ".class"), null);
+ }
+ } /* DummyClassLoader */
+
+}
+
+class TestClass {
+ static {
+ // force creation of anonymous class (for the lambdaform)
+ Runnable r = () -> System.out.println("Hello");
+ r.run();
+ }
+}
--- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Fri Jun 13 12:04:33 2014 -0700
+++ b/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Fri Jun 13 19:07:11 2014 -0700
@@ -26,6 +26,7 @@
* @bug 8028623
* @summary Test hashing of extended characters in Serviceability Agent.
* @library /testlibrary
+ * @ignore 8044416
* @build com.oracle.java.testlibrary.*
* @compile -encoding utf8 Test8028623.java
* @run main Test8028623