--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/Generation.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/Generation.java Thu Dec 11 12:28:03 2014 -0800
@@ -37,10 +37,7 @@
<ul>
<li> CardGeneration
<ul>
- <li> OneContigSpaceCardGeneration
- <ul>
- <li> TenuredGeneration
- </ul>
+ <li> TenuredGeneration
</ul>
<li> DefNewGeneration
</ul>
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/OneContigSpaceCardGeneration.java Thu Dec 11 11:44:00 2014 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2000, 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.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.io.*;
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-/** <P> OneSpaceOldGeneration models a heap of old objects contained
- in a single contiguous space. </P>
-
- <P> Garbage collection is performed using mark-compact. </P> */
-
-public abstract class OneContigSpaceCardGeneration extends CardGeneration {
- private static AddressField theSpaceField;
-
- static {
- VM.registerVMInitializedObserver(new Observer() {
- public void update(Observable o, Object data) {
- initialize(VM.getVM().getTypeDataBase());
- }
- });
- }
-
- private static synchronized void initialize(TypeDataBase db) {
- Type type = db.lookupType("OneContigSpaceCardGeneration");
-
- theSpaceField = type.getAddressField("_the_space");
- }
-
- public OneContigSpaceCardGeneration(Address addr) {
- super(addr);
- }
-
- public ContiguousSpace theSpace() {
- return (ContiguousSpace) VMObjectFactory.newObject(ContiguousSpace.class, theSpaceField.getValue(addr));
- }
-
- public boolean isIn(Address p) {
- return theSpace().contains(p);
- }
-
- /** Space queries */
- public long capacity() { return theSpace().capacity(); }
- public long used() { return theSpace().used(); }
- public long free() { return theSpace().free(); }
- public long contiguousAvailable() { return theSpace().free() + virtualSpace().uncommittedSize(); }
-
- public void spaceIterate(SpaceClosure blk, boolean usedOnly) {
- blk.doSpace(theSpace());
- }
-
- public void printOn(PrintStream tty) {
- tty.print(" old ");
- theSpace().printOn(tty);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/TenuredGeneration.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/TenuredGeneration.java Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -24,13 +24,62 @@
package sun.jvm.hotspot.memory;
+import java.io.*;
+import java.util.*;
+
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+
+/** <P> TenuredGeneration models a heap of old objects contained
+ in a single contiguous space. </P>
+
+ <P> Garbage collection is performed using mark-compact. </P> */
+
+public class TenuredGeneration extends CardGeneration {
+ private static AddressField theSpaceField;
-public class TenuredGeneration extends OneContigSpaceCardGeneration {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("TenuredGeneration");
+
+ theSpaceField = type.getAddressField("_the_space");
+ }
+
public TenuredGeneration(Address addr) {
super(addr);
}
+ public ContiguousSpace theSpace() {
+ return (ContiguousSpace) VMObjectFactory.newObject(ContiguousSpace.class, theSpaceField.getValue(addr));
+ }
+
+ public boolean isIn(Address p) {
+ return theSpace().contains(p);
+ }
+
+ /** Space queries */
+ public long capacity() { return theSpace().capacity(); }
+ public long used() { return theSpace().used(); }
+ public long free() { return theSpace().free(); }
+ public long contiguousAvailable() { return theSpace().free() + virtualSpace().uncommittedSize(); }
+
+ public void spaceIterate(SpaceClosure blk, boolean usedOnly) {
+ blk.doSpace(theSpace());
+ }
+
+ public void printOn(PrintStream tty) {
+ tty.print(" old ");
+ theSpace().printOn(tty);
+ }
+
public Generation.Name kind() {
return Generation.Name.MARK_SWEEP_COMPACT;
}
--- a/hotspot/make/solaris/makefiles/gcc.make Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/make/solaris/makefiles/gcc.make Thu Dec 11 12:28:03 2014 -0800
@@ -226,18 +226,8 @@
# Allow no optimizations.
DEBUG_CFLAGS=-O0
-# Use the stabs format for debugging information (this is the default
-# on gcc-2.91). It's good enough, has all the information about line
-# numbers and local variables, and libjvm.so is only about 16M.
-# Change this back to "-g" if you want the most expressive format.
-# (warning: that could easily inflate libjvm.so to 150M!)
-# Note: The Itanium gcc compiler crashes when using -gstabs.
-DEBUG_CFLAGS/ia64 = -g
-DEBUG_CFLAGS/amd64 = -g
-DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
-ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
- DEBUG_CFLAGS += -gstabs
-endif
+# Enable debug symbols
+DEBUG_CFLAGS += -g
# Enable bounds checking.
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1"
--- a/hotspot/make/solaris/makefiles/sparcWorks.make Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make Thu Dec 11 12:28:03 2014 -0800
@@ -496,15 +496,6 @@
FASTDEBUG_CFLAGS += -xs
endif
-# Special global options for SS12
-ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
- # There appears to be multiple issues with the new Dwarf2 debug format, so
- # we tell the compiler to use the older 'stabs' debug format all the time.
- # Note that this needs to be used in optimized compiles too to be 100%.
- # This is a workaround for SS12 (5.9) bug 6694600
- CFLAGS += -xdebugformat=stabs
-endif
-
# Enable the following CFLAGS additions if you need to compare the
# built ELF objects.
#
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -570,10 +570,12 @@
static uint cores_per_cpu() {
uint result = 1;
if (is_intel()) {
- if (supports_processor_topology()) {
+ bool supports_topology = supports_processor_topology();
+ if (supports_topology) {
result = _cpuid_info.tpl_cpuidB1_ebx.bits.logical_cpus /
_cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus;
- } else {
+ }
+ if (!supports_topology || result == 0) {
result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1);
}
} else if (is_amd()) {
--- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -569,13 +569,13 @@
char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal);
sprintf(ld_library_path, "%s%s" DEFAULT_LIBPATH, v, v_colon);
Arguments::set_library_path(ld_library_path);
- FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, ld_library_path);
// Extensions directories.
sprintf(buf, "%s" EXTENSIONS_DIR, Arguments::get_java_home());
Arguments::set_ext_dirs(buf);
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
#undef DEFAULT_LIBPATH
#undef EXTENSIONS_DIR
@@ -1300,11 +1300,11 @@
// release the storage
for (int i = 0; i < n; i++) {
if (pelements[i] != NULL) {
- FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+ FREE_C_HEAP_ARRAY(char, pelements[i]);
}
}
if (pelements != NULL) {
- FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+ FREE_C_HEAP_ARRAY(char*, pelements);
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -4144,8 +4144,29 @@
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
char *addr, size_t bytes, bool read_only,
bool allow_exec) {
- Unimplemented();
- return NULL;
+ int prot;
+ int flags = MAP_PRIVATE;
+
+ if (read_only) {
+ prot = PROT_READ;
+ } else {
+ prot = PROT_READ | PROT_WRITE;
+ }
+
+ if (allow_exec) {
+ prot |= PROT_EXEC;
+ }
+
+ if (addr != NULL) {
+ flags |= MAP_FIXED;
+ }
+
+ char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
+ fd, file_offset);
+ if (mapped_address == MAP_FAILED) {
+ return NULL;
+ }
+ return mapped_address;
}
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -127,7 +127,7 @@
}
}
}
- FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+ FREE_C_HEAP_ARRAY(char, destfile);
}
@@ -279,14 +279,14 @@
"pw_name zero length");
}
}
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return NULL;
}
char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
strcpy(user_name, p->pw_name);
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return user_name;
}
@@ -347,7 +347,7 @@
DIR* subdirp = os::opendir(usrdir_name);
if (subdirp == NULL) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
continue;
}
@@ -358,7 +358,7 @@
// symlink can be exploited.
//
if (!is_directory_secure(usrdir_name)) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
os::closedir(subdirp);
continue;
}
@@ -382,13 +382,13 @@
// don't follow symbolic links for the file
RESTARTABLE(::lstat(filename, &statbuf), result);
if (result == OS_ERR) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
// skip over files that are not regular files.
if (!S_ISREG(statbuf.st_mode)) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
@@ -398,7 +398,7 @@
if (statbuf.st_ctime > oldest_ctime) {
char* user = strchr(dentry->d_name, '_') + 1;
- if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+ if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
strcpy(oldest_user, user);
@@ -406,15 +406,15 @@
}
}
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
}
}
os::closedir(subdirp);
- FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, udbuf);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
}
os::closedir(tmpdirp);
- FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, tdbuf);
return(oldest_user);
}
@@ -481,7 +481,7 @@
remove_file(path);
- FREE_C_HEAP_ARRAY(char, path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, path);
}
@@ -558,7 +558,7 @@
errno = 0;
}
os::closedir(dirp);
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
}
// make the user specific temporary directory. Returns true if
@@ -703,11 +703,11 @@
fd = create_sharedmem_resources(dirname, filename, size);
- FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, user_name);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (fd == -1) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -723,7 +723,7 @@
warning("mmap failed - %s\n", strerror(errno));
}
remove_file(filename);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -769,7 +769,7 @@
remove_file(backing_store_file_name);
// Don't.. Free heap memory could deadlock os::abort() if it is called
// from signal handler. OS will reclaim the heap memory.
- // FREE_C_HEAP_ARRAY(char, backing_store_file_name, mtInternal);
+ // FREE_C_HEAP_ARRAY(char, backing_store_file_name);
backing_store_file_name = NULL;
}
}
@@ -853,9 +853,9 @@
// store file, we don't follow them when attaching either.
//
if (!is_directory_secure(dirname)) {
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (luser != user) {
- FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ FREE_C_HEAP_ARRAY(char, luser);
}
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
@@ -871,9 +871,9 @@
strcpy(rfilename, filename);
// free the c heap resources that are no longer needed
- if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+ FREE_C_HEAP_ARRAY(char, dirname);
+ FREE_C_HEAP_ARRAY(char, filename);
// open the shared memory file for the give vmid
fd = open_sharedmem_file(rfilename, file_flags, CHECK);
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -416,14 +416,14 @@
mtInternal);
sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);
Arguments::set_library_path(ld_library_path);
- FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, ld_library_path);
}
// Extensions directories.
sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
Arguments::set_ext_dirs(buf);
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
#else // __APPLE__
@@ -506,7 +506,7 @@
sprintf(ld_library_path, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.",
v, v_colon, l, l_colon, user_home_dir);
Arguments::set_library_path(ld_library_path);
- FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, ld_library_path);
}
// Extensions directories.
@@ -518,7 +518,7 @@
user_home_dir, Arguments::get_java_home());
Arguments::set_ext_dirs(buf);
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
#undef SYS_EXTENSIONS_DIR
#undef SYS_EXTENSIONS_DIRS
@@ -1303,11 +1303,11 @@
// release the storage
for (int i = 0; i < n; i++) {
if (pelements[i] != NULL) {
- FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+ FREE_C_HEAP_ARRAY(char, pelements[i]);
}
}
if (pelements != NULL) {
- FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+ FREE_C_HEAP_ARRAY(char*, pelements);
}
} else {
snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -127,7 +127,7 @@
}
}
}
- FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+ FREE_C_HEAP_ARRAY(char, destfile);
}
@@ -279,14 +279,14 @@
"pw_name zero length");
}
}
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return NULL;
}
char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
strcpy(user_name, p->pw_name);
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return user_name;
}
@@ -347,7 +347,7 @@
DIR* subdirp = os::opendir(usrdir_name);
if (subdirp == NULL) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
continue;
}
@@ -358,7 +358,7 @@
// symlink can be exploited.
//
if (!is_directory_secure(usrdir_name)) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
os::closedir(subdirp);
continue;
}
@@ -382,13 +382,13 @@
// don't follow symbolic links for the file
RESTARTABLE(::lstat(filename, &statbuf), result);
if (result == OS_ERR) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
// skip over files that are not regular files.
if (!S_ISREG(statbuf.st_mode)) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
@@ -398,7 +398,7 @@
if (statbuf.st_ctime > oldest_ctime) {
char* user = strchr(dentry->d_name, '_') + 1;
- if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+ if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
strcpy(oldest_user, user);
@@ -406,15 +406,15 @@
}
}
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
}
}
os::closedir(subdirp);
- FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, udbuf);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
}
os::closedir(tmpdirp);
- FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, tdbuf);
return(oldest_user);
}
@@ -481,7 +481,7 @@
remove_file(path);
- FREE_C_HEAP_ARRAY(char, path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, path);
}
@@ -558,7 +558,7 @@
errno = 0;
}
os::closedir(dirp);
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
}
// make the user specific temporary directory. Returns true if
@@ -725,11 +725,11 @@
fd = create_sharedmem_resources(dirname, filename, size);
- FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, user_name);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (fd == -1) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -743,7 +743,7 @@
warning("mmap failed - %s\n", strerror(errno));
}
remove_file(filename);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -872,9 +872,9 @@
// store file, we don't follow them when attaching either.
//
if (!is_directory_secure(dirname)) {
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (luser != user) {
- FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ FREE_C_HEAP_ARRAY(char, luser);
}
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
@@ -890,9 +890,9 @@
strcpy(rfilename, filename);
// free the c heap resources that are no longer needed
- if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+ FREE_C_HEAP_ARRAY(char, dirname);
+ FREE_C_HEAP_ARRAY(char, filename);
// open the shared memory file for the give vmid
fd = open_sharedmem_file(rfilename, file_flags, CHECK);
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -402,14 +402,14 @@
mtInternal);
sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);
Arguments::set_library_path(ld_library_path);
- FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, ld_library_path);
}
// Extensions directories.
sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
Arguments::set_ext_dirs(buf);
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
#undef DEFAULT_LIBPATH
#undef SYS_EXT_DIR
@@ -1614,11 +1614,11 @@
// release the storage
for (int i = 0; i < n; i++) {
if (pelements[i] != NULL) {
- FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+ FREE_C_HEAP_ARRAY(char, pelements[i]);
}
}
if (pelements != NULL) {
- FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+ FREE_C_HEAP_ARRAY(char*, pelements);
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -2929,7 +2929,7 @@
}
}
}
- FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
+ FREE_C_HEAP_ARRAY(unsigned long, cpu_map);
}
int os::Linux::get_node_by_cpu(int cpu_id) {
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -127,7 +127,7 @@
}
}
}
- FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+ FREE_C_HEAP_ARRAY(char, destfile);
}
@@ -279,14 +279,14 @@
"pw_name zero length");
}
}
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return NULL;
}
char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
strcpy(user_name, p->pw_name);
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return user_name;
}
@@ -347,7 +347,7 @@
DIR* subdirp = os::opendir(usrdir_name);
if (subdirp == NULL) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
continue;
}
@@ -358,7 +358,7 @@
// symlink can be exploited.
//
if (!is_directory_secure(usrdir_name)) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
os::closedir(subdirp);
continue;
}
@@ -382,13 +382,13 @@
// don't follow symbolic links for the file
RESTARTABLE(::lstat(filename, &statbuf), result);
if (result == OS_ERR) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
// skip over files that are not regular files.
if (!S_ISREG(statbuf.st_mode)) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
@@ -398,7 +398,7 @@
if (statbuf.st_ctime > oldest_ctime) {
char* user = strchr(dentry->d_name, '_') + 1;
- if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+ if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
strcpy(oldest_user, user);
@@ -406,15 +406,15 @@
}
}
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
}
}
os::closedir(subdirp);
- FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, udbuf);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
}
os::closedir(tmpdirp);
- FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, tdbuf);
return(oldest_user);
}
@@ -481,7 +481,7 @@
remove_file(path);
- FREE_C_HEAP_ARRAY(char, path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, path);
}
@@ -558,7 +558,7 @@
errno = 0;
}
os::closedir(dirp);
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
}
// make the user specific temporary directory. Returns true if
@@ -725,11 +725,11 @@
fd = create_sharedmem_resources(dirname, filename, size);
- FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, user_name);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (fd == -1) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -743,7 +743,7 @@
warning("mmap failed - %s\n", strerror(errno));
}
remove_file(filename);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -872,9 +872,9 @@
// store file, we don't follow them when attaching either.
//
if (!is_directory_secure(dirname)) {
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (luser != user) {
- FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ FREE_C_HEAP_ARRAY(char, luser);
}
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
@@ -890,9 +890,9 @@
strcpy(rfilename, filename);
// free the c heap resources that are no longer needed
- if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+ FREE_C_HEAP_ARRAY(char, dirname);
+ FREE_C_HEAP_ARRAY(char, filename);
// open the shared memory file for the give vmid
fd = open_sharedmem_file(rfilename, file_flags, THREAD);
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -506,7 +506,7 @@
}
}
if (available_id != NULL) {
- FREE_C_HEAP_ARRAY(bool, available_id, mtInternal);
+ FREE_C_HEAP_ARRAY(bool, available_id);
}
return true;
}
@@ -538,7 +538,7 @@
}
}
if (id_array != NULL) {
- FREE_C_HEAP_ARRAY(processorid_t, id_array, mtInternal);
+ FREE_C_HEAP_ARRAY(processorid_t, id_array);
}
return result;
}
@@ -673,7 +673,7 @@
// Determine search path count and required buffer size.
if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) {
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror());
}
@@ -684,8 +684,8 @@
// Obtain search path information.
if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) {
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
- FREE_C_HEAP_ARRAY(char, info, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
+ FREE_C_HEAP_ARRAY(char, info);
vm_exit_during_initialization("dlinfo SERINFO request", dlerror());
}
@@ -755,15 +755,15 @@
// Callee copies into its own buffer.
Arguments::set_library_path(library_path);
- FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
- FREE_C_HEAP_ARRAY(char, info, mtInternal);
+ FREE_C_HEAP_ARRAY(char, library_path);
+ FREE_C_HEAP_ARRAY(char, info);
}
// Extensions directories.
sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
Arguments::set_ext_dirs(buf);
- FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buf);
#undef SYS_EXT_DIR
#undef EXTENSIONS_DIR
@@ -1592,11 +1592,11 @@
// release the storage
for (int i = 0; i < n; i++) {
if (pelements[i] != NULL) {
- FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+ FREE_C_HEAP_ARRAY(char, pelements[i]);
}
}
if (pelements != NULL) {
- FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+ FREE_C_HEAP_ARRAY(char*, pelements);
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -4683,7 +4683,7 @@
size_t lgrp_limit = os::numa_get_groups_num();
int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
- FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal);
+ FREE_C_HEAP_ARRAY(int, lgrp_ids);
if (lgrp_num < 2) {
// There's only one locality group, disable NUMA.
UseNUMA = false;
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -129,7 +129,7 @@
}
}
}
- FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+ FREE_C_HEAP_ARRAY(char, destfile);
}
@@ -270,14 +270,14 @@
"pw_name zero length");
}
}
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return NULL;
}
char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
strcpy(user_name, p->pw_name);
- FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pwbuf);
return user_name;
}
@@ -338,7 +338,7 @@
DIR* subdirp = os::opendir(usrdir_name);
if (subdirp == NULL) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
continue;
}
@@ -349,7 +349,7 @@
// symlink can be exploited.
//
if (!is_directory_secure(usrdir_name)) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
os::closedir(subdirp);
continue;
}
@@ -373,13 +373,13 @@
// don't follow symbolic links for the file
RESTARTABLE(::lstat(filename, &statbuf), result);
if (result == OS_ERR) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
// skip over files that are not regular files.
if (!S_ISREG(statbuf.st_mode)) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
@@ -389,7 +389,7 @@
if (statbuf.st_ctime > oldest_ctime) {
char* user = strchr(dentry->d_name, '_') + 1;
- if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+ if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
strcpy(oldest_user, user);
@@ -397,15 +397,15 @@
}
}
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
}
}
os::closedir(subdirp);
- FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, udbuf);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
}
os::closedir(tmpdirp);
- FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, tdbuf);
return(oldest_user);
}
@@ -520,7 +520,7 @@
remove_file(path);
- FREE_C_HEAP_ARRAY(char, path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, path);
}
@@ -597,7 +597,7 @@
errno = 0;
}
os::closedir(dirp);
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
}
// make the user specific temporary directory. Returns true if
@@ -742,11 +742,11 @@
fd = create_sharedmem_resources(dirname, filename, size);
- FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, user_name);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (fd == -1) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -760,7 +760,7 @@
warning("mmap failed - %s\n", strerror(errno));
}
remove_file(filename);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
return NULL;
}
@@ -890,9 +890,9 @@
// store file, we don't follow them when attaching either.
//
if (!is_directory_secure(dirname)) {
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (luser != user) {
- FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ FREE_C_HEAP_ARRAY(char, luser);
}
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
@@ -908,9 +908,9 @@
strcpy(rfilename, filename);
// free the c heap resources that are no longer needed
- if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+ FREE_C_HEAP_ARRAY(char, dirname);
+ FREE_C_HEAP_ARRAY(char, filename);
// open the shared memory file for the give vmid
fd = open_sharedmem_file(rfilename, file_flags, THREAD);
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -211,7 +211,7 @@
}
strcpy(home_path, home_dir);
Arguments::set_java_home(home_path);
- FREE_C_HEAP_ARRAY(char, home_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, home_path);
dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1,
mtInternal);
@@ -221,7 +221,7 @@
strcpy(dll_path, home_dir);
strcat(dll_path, bin);
Arguments::set_dll_dir(dll_path);
- FREE_C_HEAP_ARRAY(char, dll_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dll_path);
if (!set_boot_path('\\', ';')) {
return;
@@ -276,7 +276,7 @@
strcat(library_path, ";.");
Arguments::set_library_path(library_path);
- FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, library_path);
}
// Default extensions directory
@@ -1123,7 +1123,7 @@
dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);
if (dirp->path == 0) {
- free(dirp, mtInternal);
+ free(dirp);
errno = ENOMEM;
return 0;
}
@@ -1131,13 +1131,13 @@
fattr = GetFileAttributes(dirp->path);
if (fattr == 0xffffffff) {
- free(dirp->path, mtInternal);
- free(dirp, mtInternal);
+ free(dirp->path);
+ free(dirp);
errno = ENOENT;
return 0;
} else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- free(dirp->path, mtInternal);
- free(dirp, mtInternal);
+ free(dirp->path);
+ free(dirp);
errno = ENOTDIR;
return 0;
}
@@ -1155,8 +1155,8 @@
dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
if (dirp->handle == INVALID_HANDLE_VALUE) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- free(dirp->path, mtInternal);
- free(dirp, mtInternal);
+ free(dirp->path);
+ free(dirp);
errno = EACCES;
return 0;
}
@@ -1194,8 +1194,8 @@
}
dirp->handle = INVALID_HANDLE_VALUE;
}
- free(dirp->path, mtInternal);
- free(dirp, mtInternal);
+ free(dirp->path);
+ free(dirp);
return 0;
}
@@ -1262,11 +1262,11 @@
// release the storage
for (int i = 0; i < n; i++) {
if (pelements[i] != NULL) {
- FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+ FREE_C_HEAP_ARRAY(char, pelements[i]);
}
}
if (pelements != NULL) {
- FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+ FREE_C_HEAP_ARRAY(char*, pelements);
}
} else {
jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
@@ -2732,7 +2732,7 @@
void free_node_list() {
if (_numa_used_node_list != NULL) {
- FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal);
+ FREE_C_HEAP_ARRAY(int, _numa_used_node_list);
}
}
@@ -3768,8 +3768,8 @@
return NULL;
}
-#define MAX_EXIT_HANDLES 16
-#define EXIT_TIMEOUT 1000 /* 1 sec */
+#define MAX_EXIT_HANDLES PRODUCT_ONLY(32) NOT_PRODUCT(128)
+#define EXIT_TIMEOUT PRODUCT_ONLY(1000) NOT_PRODUCT(4000) /* 1 sec in product, 4 sec in debug */
static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
@@ -3820,6 +3820,9 @@
// If there's no free slot in the array of the kept handles, we'll have to
// wait until at least one thread completes exiting.
if ((handle_count = j) == MAX_EXIT_HANDLES) {
+ // Raise the priority of the oldest exiting thread to increase its chances
+ // to complete sooner.
+ SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
i = (res - WAIT_OBJECT_0);
@@ -3828,7 +3831,8 @@
handles[i] = handles[i + 1];
}
} else {
- warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+ warning("WaitForMultipleObjects %s in %s: %d\n",
+ (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__);
// Don't keep handles, if we failed waiting for them.
for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
CloseHandle(handles[i]);
@@ -3854,9 +3858,20 @@
if (handle_count > 0) {
// Before ending the process, make sure all the threads that had called
// _endthreadex() completed.
+
+ // Set the priority level of the current thread to the same value as
+ // the priority level of exiting threads.
+ // This is to ensure it will be given a fair chance to execute if
+ // the timeout expires.
+ hthr = GetCurrentThread();
+ SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
+ for (i = 0; i < handle_count; ++i) {
+ SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL);
+ }
res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
- if (res == WAIT_FAILED) {
- warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+ if (res < WAIT_OBJECT_0 || res >= (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
+ warning("WaitForMultipleObjects %s in %s: %d\n",
+ (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__);
}
for (i = 0; i < handle_count; ++i) {
CloseHandle(handles[i]);
@@ -4631,7 +4646,7 @@
error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);
if (error == 0) {
- os::free(lpBuffer, mtInternal);
+ os::free(lpBuffer);
return FALSE;
}
@@ -4652,7 +4667,7 @@
}
if (lpBuffer != NULL) {
- os::free(lpBuffer, mtInternal);
+ os::free(lpBuffer);
}
*pbytes = (long) actualLength;
--- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -122,7 +122,7 @@
}
}
- FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+ FREE_C_HEAP_ARRAY(char, destfile);
}
// Shared Memory Implementation Details
@@ -335,7 +335,7 @@
DIR* subdirp = os::opendir(usrdir_name);
if (subdirp == NULL) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
continue;
}
@@ -346,7 +346,7 @@
// symlink can be exploited.
//
if (!is_directory_secure(usrdir_name)) {
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
os::closedir(subdirp);
continue;
}
@@ -367,13 +367,13 @@
strcat(filename, udentry->d_name);
if (::stat(filename, &statbuf) == OS_ERR) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
// skip over files that are not regular files.
if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
continue;
}
@@ -395,22 +395,22 @@
if (statbuf.st_ctime > latest_ctime) {
char* user = strchr(dentry->d_name, '_') + 1;
- if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user, mtInternal);
+ if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
strcpy(latest_user, user);
latest_ctime = statbuf.st_ctime;
}
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
}
}
os::closedir(subdirp);
- FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
- FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, udbuf);
+ FREE_C_HEAP_ARRAY(char, usrdir_name);
}
os::closedir(tmpdirp);
- FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, tdbuf);
return(latest_user);
}
@@ -502,7 +502,7 @@
}
}
- FREE_C_HEAP_ARRAY(char, path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, path);
}
// returns true if the process represented by pid is alive, otherwise
@@ -683,7 +683,7 @@
errno = 0;
}
os::closedir(dirp);
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
}
// create a file mapping object with the requested name, and size
@@ -749,11 +749,11 @@
// be an ACL we enlisted. free the resources.
//
if (success && exists && pACL != NULL && !isdefault) {
- FREE_C_HEAP_ARRAY(char, pACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pACL);
}
// free the security descriptor
- FREE_C_HEAP_ARRAY(char, pSD, mtInternal);
+ FREE_C_HEAP_ARRAY(char, pSD);
}
}
@@ -768,7 +768,7 @@
lpSA->lpSecurityDescriptor = NULL;
// free the security attributes structure
- FREE_C_HEAP_ARRAY(char, lpSA, mtInternal);
+ FREE_C_HEAP_ARRAY(char, lpSA);
}
}
@@ -815,7 +815,7 @@
warning("GetTokenInformation failure: lasterror = %d,"
" rsize = %d\n", GetLastError(), rsize);
}
- FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, token_buf);
CloseHandle(hAccessToken);
return NULL;
}
@@ -828,15 +828,15 @@
warning("GetTokenInformation failure: lasterror = %d,"
" rsize = %d\n", GetLastError(), rsize);
}
- FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
- FREE_C_HEAP_ARRAY(char, pSID, mtInternal);
+ FREE_C_HEAP_ARRAY(char, token_buf);
+ FREE_C_HEAP_ARRAY(char, pSID);
CloseHandle(hAccessToken);
return NULL;
}
// close the access token.
CloseHandle(hAccessToken);
- FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, token_buf);
return pSID;
}
@@ -920,7 +920,7 @@
if (PrintMiscellaneous && Verbose) {
warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
@@ -933,7 +933,7 @@
if (PrintMiscellaneous && Verbose) {
warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) {
@@ -960,7 +960,7 @@
if (PrintMiscellaneous && Verbose) {
warning("AddAce failure: lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
}
@@ -976,7 +976,7 @@
warning("AddAccessAllowedAce failure: lasterror = %d \n",
GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
}
@@ -991,7 +991,7 @@
if (PrintMiscellaneous && Verbose) {
warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
@@ -999,7 +999,7 @@
if (PrintMiscellaneous && Verbose) {
warning("AddAce failure: lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
ace_index++;
@@ -1012,7 +1012,7 @@
warning("SetSecurityDescriptorDacl failure:"
" lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
@@ -1032,7 +1032,7 @@
warning("SetSecurityDescriptorControl failure:"
" lasterror = %d \n", GetLastError());
}
- FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+ FREE_C_HEAP_ARRAY(char, newACL);
return false;
}
}
@@ -1149,7 +1149,7 @@
// create a security attributes structure with access control
// entries as initialized above.
LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3);
- FREE_C_HEAP_ARRAY(char, aces[0].pSid, mtInternal);
+ FREE_C_HEAP_ARRAY(char, aces[0].pSid);
FreeSid(everybodySid);
FreeSid(administratorsSid);
return(lpSA);
@@ -1464,15 +1464,15 @@
assert(((size != 0) && (size % os::vm_page_size() == 0)),
"unexpected PerfMemry region size");
- FREE_C_HEAP_ARRAY(char, user, mtInternal);
+ FREE_C_HEAP_ARRAY(char, user);
// create the shared memory resources
sharedmem_fileMapHandle =
create_sharedmem_resources(dirname, filename, objectname, size);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
- FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, filename);
+ FREE_C_HEAP_ARRAY(char, objectname);
+ FREE_C_HEAP_ARRAY(char, dirname);
if (sharedmem_fileMapHandle == NULL) {
return NULL;
@@ -1627,7 +1627,7 @@
// store file, we also don't following them when attaching
//
if (!is_directory_secure(dirname)) {
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirname);
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
}
@@ -1646,10 +1646,10 @@
strcpy(robjectname, objectname);
// free the c heap resources that are no longer needed
- if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
- FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
- FREE_C_HEAP_ARRAY(char, filename, mtInternal);
- FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
+ if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+ FREE_C_HEAP_ARRAY(char, dirname);
+ FREE_C_HEAP_ARRAY(char, filename);
+ FREE_C_HEAP_ARRAY(char, objectname);
if (*sizep == 0) {
size = sharedmem_filesize(rfilename, CHECK);
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1025,7 +1025,7 @@
~CodeString() {
assert(_next == NULL, "wrong interface for freeing list");
- os::free((void*)_string, mtCode);
+ os::free((void*)_string);
}
bool is_comment() const { return _offset >= 0; }
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -36,6 +36,7 @@
#include "interpreter/bytecodes.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/compile.hpp"
+#include "opto/node.hpp"
#include "runtime/deoptimization.hpp"
#include "utilities/growableArray.hpp"
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -165,7 +165,7 @@
MetaIndex::~MetaIndex() {
- FREE_C_HEAP_ARRAY(char*, _meta_package_names, mtClass);
+ FREE_C_HEAP_ARRAY(char*, _meta_package_names);
}
@@ -251,7 +251,7 @@
if (ZipClose != NULL) {
(*ZipClose)(_zip);
}
- FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
+ FREE_C_HEAP_ARRAY(char, _zip_name);
}
u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
--- a/hotspot/src/share/vm/classfile/imageFile.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/classfile/imageFile.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -90,7 +90,7 @@
close();
// Free up name.
- FREE_C_HEAP_ARRAY(char, _name, mtClass);
+ FREE_C_HEAP_ARRAY(char, _name);
}
bool ImageFile::open() {
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, 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
@@ -164,7 +164,7 @@
// Purge entry
*p = probe->next();
- FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass);
+ FREE_C_HEAP_ARRAY(oop, probe->loaders());
free_entry(probe);
} else {
#ifdef ASSERT
@@ -340,7 +340,7 @@
ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
p->set_max_loaders(n);
- FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass);
+ FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
p->set_loaders(new_loaders);
}
}
@@ -422,7 +422,7 @@
}
*pp2 = p2->next();
- FREE_C_HEAP_ARRAY(oop, p2->loaders(), mtClass);
+ FREE_C_HEAP_ARRAY(oop, p2->loaders());
free_entry(p2);
return;
}
--- a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -89,7 +89,7 @@
}
~SharedPathsMiscInfo() {
if (_allocated) {
- FREE_C_HEAP_ARRAY(char, _buf_start, mtClass);
+ FREE_C_HEAP_ARRAY(char, _buf_start);
}
}
int get_used_bytes() {
--- a/hotspot/src/share/vm/code/codeBlob.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/code/codeBlob.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -168,7 +168,7 @@
void CodeBlob::flush() {
if (_oop_maps) {
- FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode);
+ FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
_oop_maps = NULL;
}
_strings.free();
--- a/hotspot/src/share/vm/code/codeCache.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/code/codeCache.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1190,7 +1190,7 @@
}
}
- FREE_C_HEAP_ARRAY(int, buckets, mtCode);
+ FREE_C_HEAP_ARRAY(int, buckets);
print_memory_overhead();
}
--- a/hotspot/src/share/vm/compiler/compileLog.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/compiler/compileLog.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -58,10 +58,8 @@
CompileLog::~CompileLog() {
delete _out; // Close fd in fileStream::~fileStream()
_out = NULL;
- // Remove partial file after merging in CompileLog::finish_log_on_error
- unlink(_file);
- FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
- FREE_C_HEAP_ARRAY(char, _file, mtCompiler);
+ FREE_C_HEAP_ARRAY(char, _identities);
+ FREE_C_HEAP_ARRAY(char, _file);
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -52,21 +52,9 @@
}
void ConcurrentMarkSweepPolicy::initialize_generations() {
- _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC,
- CURRENT_PC, AllocFailStrategy::RETURN_NULL);
- if (_generations == NULL)
- vm_exit_during_initialization("Unable to allocate gen spec");
-
- Generation::Name yg_name =
- UseParNewGC ? Generation::ParNew : Generation::DefNew;
- _generations[0] = new GenerationSpec(yg_name, _initial_young_size,
- _max_young_size);
- _generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep,
- _initial_old_size, _max_old_size);
-
- if (_generations[0] == NULL || _generations[1] == NULL) {
- vm_exit_during_initialization("Unable to allocate gen spec");
- }
+ _generations = NEW_C_HEAP_ARRAY(GenerationSpecPtr, number_of_generations(), mtGC);
+ _generations[0] = new GenerationSpec(Generation::ParNew, _initial_young_size, _max_young_size);
+ _generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep, _initial_old_size, _max_old_size);
}
void ConcurrentMarkSweepPolicy::initialize_size_policy(size_t init_eden_size,
@@ -82,10 +70,5 @@
void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
// initialize the policy counters - 2 collectors, 3 generations
- if (UseParNewGC) {
- _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3);
- }
- else {
- _gc_policy_counters = new GCPolicyCounters("Copy:CMS", 2, 3);
- }
+ _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3);
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -90,7 +90,8 @@
CMSRescanMultiple),
_marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
CMSConcMarkMultiple),
- _collector(NULL)
+ _collector(NULL),
+ _preconsumptionDirtyCardClosure(NULL)
{
assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
"FreeChunk is larger than expected");
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -155,6 +155,9 @@
// Used to keep track of limit of sweep for the space
HeapWord* _sweep_limit;
+ // Used to make the young collector update the mod union table
+ MemRegionClosure* _preconsumptionDirtyCardClosure;
+
// Support for compacting cms
HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
@@ -356,6 +359,14 @@
void initialize_sequential_subtasks_for_marking(int n_threads,
HeapWord* low = NULL);
+ virtual MemRegionClosure* preconsumptionDirtyCardClosure() const {
+ return _preconsumptionDirtyCardClosure;
+ }
+
+ void setPreconsumptionDirtyCardClosure(MemRegionClosure* cl) {
+ _preconsumptionDirtyCardClosure = cl;
+ }
+
// Space enquiries
size_t used() const;
size_t free() const;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -623,7 +623,8 @@
// Support for parallelizing young gen rescan
GenCollectedHeap* gch = GenCollectedHeap::heap();
- _young_gen = gch->prev_gen(_cmsGen);
+ assert(gch->prev_gen(_cmsGen)->kind() == Generation::ParNew, "CMS can only be used with ParNew");
+ _young_gen = (ParNewGeneration*)gch->prev_gen(_cmsGen);
if (gch->supports_inline_contig_alloc()) {
_top_addr = gch->top_addr();
_end_addr = gch->end_addr();
@@ -650,15 +651,15 @@
|| _cursor == NULL) {
warning("Failed to allocate survivor plab/chunk array");
if (_survivor_plab_array != NULL) {
- FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array, mtGC);
+ FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
_survivor_plab_array = NULL;
}
if (_survivor_chunk_array != NULL) {
- FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array, mtGC);
+ FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
_survivor_chunk_array = NULL;
}
if (_cursor != NULL) {
- FREE_C_HEAP_ARRAY(size_t, _cursor, mtGC);
+ FREE_C_HEAP_ARRAY(size_t, _cursor);
_cursor = NULL;
}
} else {
@@ -668,10 +669,10 @@
if (vec == NULL) {
warning("Failed to allocate survivor plab array");
for (int j = i; j > 0; j--) {
- FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array(), mtGC);
+ FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
}
- FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array, mtGC);
- FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array, mtGC);
+ FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
+ FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
_survivor_plab_array = NULL;
_survivor_chunk_array = NULL;
_survivor_chunk_capacity = 0;
@@ -1203,14 +1204,6 @@
void
ConcurrentMarkSweepGeneration::
-par_promote_alloc_undo(int thread_num,
- HeapWord* obj, size_t word_sz) {
- // CMS does not support promotion undo.
- ShouldNotReachHere();
-}
-
-void
-ConcurrentMarkSweepGeneration::
par_promote_alloc_done(int thread_num) {
CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
ps->lab.retire(thread_num);
@@ -1641,13 +1634,12 @@
do_compaction_work(clear_all_soft_refs);
// Has the GC time limit been exceeded?
- DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration();
- size_t max_eden_size = young_gen->max_capacity() -
- young_gen->to()->capacity() -
- young_gen->from()->capacity();
+ size_t max_eden_size = _young_gen->max_capacity() -
+ _young_gen->to()->capacity() -
+ _young_gen->from()->capacity();
GCCause::Cause gc_cause = gch->gc_cause();
size_policy()->check_gc_overhead_limit(_young_gen->used(),
- young_gen->eden()->used(),
+ _young_gen->eden()->used(),
_cmsGen->max_capacity(),
max_eden_size,
full,
@@ -1768,10 +1760,9 @@
}
void CMSCollector::print_eden_and_survivor_chunk_arrays() {
- DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
- ContiguousSpace* eden_space = dng->eden();
- ContiguousSpace* from_space = dng->from();
- ContiguousSpace* to_space = dng->to();
+ ContiguousSpace* eden_space = _young_gen->eden();
+ ContiguousSpace* from_space = _young_gen->from();
+ ContiguousSpace* to_space = _young_gen->to();
// Eden
if (_eden_chunk_array != NULL) {
gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
@@ -2821,7 +2812,7 @@
}
// YSR: All of this generation expansion/shrinking stuff is an exact copy of
-// OneContigSpaceCardGeneration, which makes me wonder if we should move this
+// TenuredGeneration, which makes me wonder if we should move this
// to CardGeneration and share it...
bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) {
return CardGeneration::expand(bytes, expand_bytes);
@@ -4094,10 +4085,6 @@
}
if (clean_survivor) { // preclean the active survivor space(s)
- assert(_young_gen->kind() == Generation::DefNew ||
- _young_gen->kind() == Generation::ParNew,
- "incorrect type for cast");
- DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
PushAndMarkClosure pam_cl(this, _span, ref_processor(),
&_markBitMap, &_modUnionTable,
&_markStack, true /* precleaning phase */);
@@ -4110,8 +4097,8 @@
SurvivorSpacePrecleanClosure
sss_cl(this, _span, &_markBitMap, &_markStack,
&pam_cl, before_count, CMSYield);
- dng->from()->object_iterate_careful(&sss_cl);
- dng->to()->object_iterate_careful(&sss_cl);
+ _young_gen->from()->object_iterate_careful(&sss_cl);
+ _young_gen->to()->object_iterate_careful(&sss_cl);
}
MarkRefsIntoAndScanClosure
mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
@@ -4696,10 +4683,10 @@
};
void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) {
- DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
- ContiguousSpace* eden_space = dng->eden();
- ContiguousSpace* from_space = dng->from();
- ContiguousSpace* to_space = dng->to();
+ ParNewGeneration* young_gen = _collector->_young_gen;
+ ContiguousSpace* eden_space = young_gen->eden();
+ ContiguousSpace* from_space = young_gen->from();
+ ContiguousSpace* to_space = young_gen->to();
HeapWord** eca = _collector->_eden_chunk_array;
size_t ect = _collector->_eden_chunk_index;
@@ -5168,11 +5155,10 @@
CMSCollector::
initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
assert(n_threads > 0, "Unexpected n_threads argument");
- DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
// Eden space
- if (!dng->eden()->is_empty()) {
- SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
+ if (!_young_gen->eden()->is_empty()) {
+ SequentialSubTasksDone* pst = _young_gen->eden()->par_seq_tasks();
assert(!pst->valid(), "Clobbering existing data?");
// Each valid entry in [0, _eden_chunk_index) represents a task.
size_t n_tasks = _eden_chunk_index + 1;
@@ -5185,14 +5171,14 @@
// Merge the survivor plab arrays into _survivor_chunk_array
if (_survivor_plab_array != NULL) {
- merge_survivor_plab_arrays(dng->from(), n_threads);
+ merge_survivor_plab_arrays(_young_gen->from(), n_threads);
} else {
assert(_survivor_chunk_index == 0, "Error");
}
// To space
{
- SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
+ SequentialSubTasksDone* pst = _young_gen->to()->par_seq_tasks();
assert(!pst->valid(), "Clobbering existing data?");
// Sets the condition for completion of the subtask (how many threads
// need to finish in order to be done).
@@ -5203,7 +5189,7 @@
// From space
{
- SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
+ SequentialSubTasksDone* pst = _young_gen->from()->par_seq_tasks();
assert(!pst->valid(), "Clobbering existing data?");
size_t n_tasks = _survivor_chunk_index + 1;
assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
@@ -5945,7 +5931,6 @@
}
void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
- gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer_cm->gc_id());
TraceCollectorStats tcs(counters());
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -721,7 +721,8 @@
private:
// Support for parallelizing young gen rescan in CMS remark phase
- Generation* _young_gen; // the younger gen
+ ParNewGeneration* _young_gen; // the younger gen
+
HeapWord** _top_addr; // ... Top of Eden
HeapWord** _end_addr; // ... End of Eden
Mutex* _eden_chunk_lock;
@@ -1151,9 +1152,6 @@
// Overrides for parallel promotion.
virtual oop par_promote(int thread_num,
oop obj, markOop m, size_t word_sz);
- // This one should not be called for CMS.
- virtual void par_promote_alloc_undo(int thread_num,
- HeapWord* obj, size_t word_sz);
virtual void par_promote_alloc_done(int thread_num);
virtual void par_oop_since_save_marks_iterate_done(int thread_num);
@@ -1256,8 +1254,6 @@
virtual const char* short_name() const { return "CMS"; }
void print() const;
void printOccupancy(const char* s);
- bool must_be_youngest() const { return false; }
- bool must_be_oldest() const { return true; }
// Resize the generation after a compacting GC. The
// generation can be treated as a contiguous space
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -29,8 +29,9 @@
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
+#include "gc_implementation/parNew/parNewGeneration.hpp"
#include "gc_implementation/shared/gcUtil.hpp"
-#include "memory/defNewGeneration.hpp"
+#include "memory/genCollectedHeap.hpp"
inline void CMSBitMap::clear_all() {
assert_locked();
@@ -257,11 +258,11 @@
}
inline size_t CMSCollector::get_eden_used() const {
- return _young_gen->as_DefNewGeneration()->eden()->used();
+ return _young_gen->eden()->used();
}
inline size_t CMSCollector::get_eden_capacity() const {
- return _young_gen->as_DefNewGeneration()->eden()->capacity();
+ return _young_gen->eden()->capacity();
}
inline bool CMSStats::valid() const {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -107,7 +107,7 @@
for (uint i = 0; i < _n_threads; i++) {
delete _threads[i];
}
- FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads, mtGC);
+ FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -180,9 +180,32 @@
}
};
+class ParClearNextMarkBitmapTask : public AbstractGangTask {
+ ClearBitmapHRClosure* _cl;
+ HeapRegionClaimer _hrclaimer;
+ bool _suspendible; // If the task is suspendible, workers must join the STS.
+
+public:
+ ParClearNextMarkBitmapTask(ClearBitmapHRClosure *cl, uint n_workers, bool suspendible) :
+ _cl(cl), _suspendible(suspendible), AbstractGangTask("Parallel Clear Bitmap Task"), _hrclaimer(n_workers) {}
+
+ void work(uint worker_id) {
+ if (_suspendible) {
+ SuspendibleThreadSet::join();
+ }
+ G1CollectedHeap::heap()->heap_region_par_iterate(_cl, worker_id, &_hrclaimer, true);
+ if (_suspendible) {
+ SuspendibleThreadSet::leave();
+ }
+ }
+};
+
void CMBitMap::clearAll() {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
ClearBitmapHRClosure cl(NULL, this, false /* may_yield */);
- G1CollectedHeap::heap()->heap_region_iterate(&cl);
+ uint n_workers = g1h->workers()->active_workers();
+ ParClearNextMarkBitmapTask task(&cl, n_workers, false);
+ g1h->workers()->run_task(&task);
guarantee(cl.complete(), "Must have completed iteration.");
return;
}
@@ -861,7 +884,8 @@
guarantee(!g1h->mark_in_progress(), "invariant");
ClearBitmapHRClosure cl(this, _nextMarkBitMap, true /* may_yield */);
- g1h->heap_region_iterate(&cl);
+ ParClearNextMarkBitmapTask task(&cl, parallel_marking_threads(), true);
+ _parallel_workers->run_task(&task);
// Clear the liveness counting data. If the marking has been aborted, the abort()
// call already did that.
@@ -2099,6 +2123,7 @@
// We reclaimed old regions so we should calculate the sizes to make
// sure we update the old gen/space data.
g1h->g1mm()->update_sizes();
+ g1h->allocation_context_stats().update_after_mark();
g1h->trace_heap_after_concurrent_cycle();
}
@@ -3219,7 +3244,6 @@
_g1h->set_par_threads(n_workers);
_g1h->workers()->run_task(&g1_par_agg_task);
_g1h->set_par_threads(0);
- _g1h->allocation_context_stats().update_at_remark();
}
// Clear the per-worker arrays used to store the per-region counting data
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -280,7 +280,6 @@
// We may have aborted just before the remark. Do not bother clearing the
// bitmap then, as it has been done during mark abort.
if (!cm()->has_aborted()) {
- SuspendibleThreadSetJoiner sts;
_cm->clearNextBitmap();
} else {
assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocationContext.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocationContext.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -45,7 +45,7 @@
public:
inline void clear() { }
inline void update(bool full_gc) { }
- inline void update_at_remark() { }
+ inline void update_after_mark() { }
inline bool available() { return false; }
};
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -59,7 +59,7 @@
!(retained_region->top() == retained_region->end()) &&
!retained_region->is_empty() &&
!retained_region->is_humongous()) {
- retained_region->record_top_and_timestamp();
+ retained_region->record_timestamp();
// The retained region was added to the old region set when it was
// retired. We have to remove it now, since we don't allow regions
// we allocate to in the region sets. We'll re-add it later, when
@@ -94,6 +94,9 @@
// want either way so no reason to check explicitly for either
// condition.
_retained_old_gc_alloc_region = old_gc_alloc_region(context)->release();
+ if (_retained_old_gc_alloc_region != NULL) {
+ _retained_old_gc_alloc_region->record_retained_region();
+ }
if (ResizePLAB) {
_g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -111,13 +111,13 @@
// read next before freeing.
e = e->next();
unlink_entry(to_remove);
- FREE_C_HEAP_ARRAY(char, to_remove, mtGC);
+ FREE_C_HEAP_ARRAY(char, to_remove);
}
}
assert(number_of_entries() == 0, "should have removed all entries");
free_buckets();
for (BasicHashtableEntry<mtGC>* e = new_entry_free_list(); e != NULL; e = new_entry_free_list()) {
- FREE_C_HEAP_ARRAY(char, e, mtGC);
+ FREE_C_HEAP_ARRAY(char, e);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1222,7 +1222,6 @@
// Timing
assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant");
- gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
{
@@ -2258,6 +2257,7 @@
case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
case GCCause::_g1_humongous_allocation: return true;
case GCCause::_update_allocation_context_stats_inc: return true;
+ case GCCause::_wb_conc_mark: return true;
default: return false;
}
}
@@ -2552,8 +2552,9 @@
void
G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl,
uint worker_id,
- HeapRegionClaimer *hrclaimer) const {
- _hrm.par_iterate(cl, worker_id, hrclaimer);
+ HeapRegionClaimer *hrclaimer,
+ bool concurrent) const {
+ _hrm.par_iterate(cl, worker_id, hrclaimer, concurrent);
}
// Clear the cached CSet starting regions and (more importantly)
@@ -3561,7 +3562,7 @@
void
G1CollectedHeap::cleanup_surviving_young_words() {
guarantee( _surviving_young_words != NULL, "pre-condition" );
- FREE_C_HEAP_ARRAY(size_t, _surviving_young_words, mtGC);
+ FREE_C_HEAP_ARRAY(size_t, _surviving_young_words);
_surviving_young_words = NULL;
}
@@ -6530,7 +6531,7 @@
// We really only need to do this for old regions given that we
// should never scan survivors. But it doesn't hurt to do it
// for survivors too.
- new_alloc_region->record_top_and_timestamp();
+ new_alloc_region->record_timestamp();
if (survivor) {
new_alloc_region->set_survivor();
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1380,10 +1380,13 @@
// in the range [0..max(ParallelGCThreads-1, 1)]. Applies "blk->doHeapRegion"
// to each of the regions, by attempting to claim the region using the
// HeapRegionClaimer and, if successful, applying the closure to the claimed
- // region.
+ // region. The concurrent argument should be set to true if iteration is
+ // performed concurrently, during which no assumptions are made for consistent
+ // attributes of the heap regions (as they might be modified while iterating).
void heap_region_par_iterate(HeapRegionClosure* cl,
uint worker_id,
- HeapRegionClaimer* hrclaimer) const;
+ HeapRegionClaimer* hrclaimer,
+ bool concurrent = false) const;
// Clear the cached cset start regions and (more importantly)
// the time stamps. Called when we reset the GC time stamp.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1425,6 +1425,18 @@
#endif // PRODUCT
}
+bool G1CollectorPolicy::is_young_list_full() {
+ uint young_list_length = _g1->young_list()->length();
+ uint young_list_target_length = _young_list_target_length;
+ return young_list_length >= young_list_target_length;
+}
+
+bool G1CollectorPolicy::can_expand_young_list() {
+ uint young_list_length = _g1->young_list()->length();
+ uint young_list_max_length = _young_list_max_length;
+ return young_list_length < young_list_max_length;
+}
+
uint G1CollectorPolicy::max_regions(int purpose) {
switch (purpose) {
case GCAllocForSurvived:
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_HPP
#include "gc_implementation/g1/collectionSetChooser.hpp"
+#include "gc_implementation/g1/g1Allocator.hpp"
#include "gc_implementation/g1/g1MMUTracker.hpp"
#include "memory/collectorPolicy.hpp"
@@ -807,7 +808,7 @@
// If an expansion would be appropriate, because recent GC overhead had
// exceeded the desired limit, return an amount to expand by.
- size_t expansion_amount();
+ virtual size_t expansion_amount();
// Print tracing information.
void print_tracing_info() const;
@@ -826,17 +827,9 @@
size_t young_list_target_length() const { return _young_list_target_length; }
- bool is_young_list_full() {
- uint young_list_length = _g1->young_list()->length();
- uint young_list_target_length = _young_list_target_length;
- return young_list_length >= young_list_target_length;
- }
+ bool is_young_list_full();
- bool can_expand_young_list() {
- uint young_list_length = _g1->young_list()->length();
- uint young_list_max_length = _young_list_max_length;
- return young_list_length < young_list_max_length;
- }
+ bool can_expand_young_list();
uint young_list_max_length() {
return _young_list_max_length;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy_ext.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
+
+#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+
+class G1CollectorPolicyExt : public G1CollectorPolicy { };
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -53,7 +53,7 @@
}
~WorkerDataArray() {
- FREE_C_HEAP_ARRAY(T, _data, mtGC);
+ FREE_C_HEAP_ARRAY(T, _data);
}
void set(uint worker_i, T value) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -53,7 +53,7 @@
G1HotCardCache::~G1HotCardCache() {
if (default_use_cache()) {
assert(_hot_cache != NULL, "Logic");
- FREE_C_HEAP_ARRAY(jbyte*, _hot_cache, mtGC);
+ FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -65,7 +65,7 @@
G1ParScanThreadState::~G1ParScanThreadState() {
_g1_par_allocator->retire_alloc_buffers();
delete _g1_par_allocator;
- FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
+ FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
}
void
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -94,7 +94,7 @@
for (uint i = 0; i < n_workers(); i++) {
assert(_cset_rs_update_cl[i] == NULL, "it should be");
}
- FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
+ FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl);
}
class ScanRSClosure : public HeapRegionClosure {
@@ -140,11 +140,9 @@
// Set the "from" region in the closure.
_oc->set_region(r);
- HeapWord* card_start = _bot_shared->address_for_index(index);
- HeapWord* card_end = card_start + G1BlockOffsetSharedArray::N_words;
- Space *sp = SharedHeap::heap()->space_containing(card_start);
- MemRegion sm_region = sp->used_region_at_save_marks();
- MemRegion mr = sm_region.intersection(MemRegion(card_start,card_end));
+ MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
+ MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
+ MemRegion mr = pre_gc_allocated.intersection(card_region);
if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
// We make the card as "claimed" lazily (so races are possible
// but they're benign), which reduces the number of duplicate
@@ -353,7 +351,7 @@
for (uint i = 0; i < n_workers(); ++i) {
_total_cards_scanned += _cards_scanned[i];
}
- FREE_C_HEAP_ARRAY(size_t, _cards_scanned, mtGC);
+ FREE_C_HEAP_ARRAY(size_t, _cards_scanned);
_cards_scanned = NULL;
// Cleanup after copy
_g1->set_refine_cte_cl_concurrency(true);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -59,7 +59,7 @@
void free_and_null() {
if (_rs_threads_vtimes) {
- FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes, mtGC);
+ FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes);
_rs_threads_vtimes = NULL;
_num_vtimes = 0;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -187,7 +187,7 @@
}
G1StringDedupTable::~G1StringDedupTable() {
- FREE_C_HEAP_ARRAY(G1StringDedupEntry*, _buckets, mtGC);
+ FREE_C_HEAP_ARRAY(G1StringDedupEntry*, _buckets);
}
void G1StringDedupTable::create() {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -326,7 +326,7 @@
hr_clear(false /*par*/, false /*clear_space*/);
set_top(bottom());
- record_top_and_timestamp();
+ record_timestamp();
assert(mr.end() == orig_end(),
err_msg("Given region end address " PTR_FORMAT " should match exactly "
@@ -416,9 +416,9 @@
// If we're within a stop-world GC, then we might look at a card in a
// GC alloc region that extends onto a GC LAB, which may not be
- // parseable. Stop such at the "saved_mark" of the region.
+ // parseable. Stop such at the "scan_top" of the region.
if (g1h->is_gc_active()) {
- mr = mr.intersection(used_region_at_save_marks());
+ mr = mr.intersection(MemRegion(bottom(), scan_top()));
} else {
mr = mr.intersection(used_region());
}
@@ -969,7 +969,7 @@
void G1OffsetTableContigSpace::clear(bool mangle_space) {
set_top(bottom());
- set_saved_mark_word(bottom());
+ _scan_top = bottom();
CompactibleSpace::clear(mangle_space);
reset_bot();
}
@@ -1001,41 +1001,42 @@
return _offsets.threshold();
}
-HeapWord* G1OffsetTableContigSpace::saved_mark_word() const {
+HeapWord* G1OffsetTableContigSpace::scan_top() const {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" );
HeapWord* local_top = top();
OrderAccess::loadload();
- if (_gc_time_stamp < g1h->get_gc_time_stamp()) {
+ const unsigned local_time_stamp = _gc_time_stamp;
+ assert(local_time_stamp <= g1h->get_gc_time_stamp(), "invariant");
+ if (local_time_stamp < g1h->get_gc_time_stamp()) {
return local_top;
} else {
- return Space::saved_mark_word();
+ return _scan_top;
}
}
-void G1OffsetTableContigSpace::record_top_and_timestamp() {
+void G1OffsetTableContigSpace::record_timestamp() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp();
if (_gc_time_stamp < curr_gc_time_stamp) {
- // The order of these is important, as another thread might be
- // about to start scanning this region. If it does so after
- // set_saved_mark and before _gc_time_stamp = ..., then the latter
- // will be false, and it will pick up top() as the high water mark
- // of region. If it does so after _gc_time_stamp = ..., then it
- // will pick up the right saved_mark_word() as the high water mark
- // of the region. Either way, the behavior will be correct.
- Space::set_saved_mark_word(top());
- OrderAccess::storestore();
+ // Setting the time stamp here tells concurrent readers to look at
+ // scan_top to know the maximum allowed address to look at.
+
+ // scan_top should be bottom for all regions except for the
+ // retained old alloc region which should have scan_top == top
+ HeapWord* st = _scan_top;
+ guarantee(st == _bottom || st == _top, "invariant");
+
_gc_time_stamp = curr_gc_time_stamp;
- // No need to do another barrier to flush the writes above. If
- // this is called in parallel with other threads trying to
- // allocate into the region, the caller should call this while
- // holding a lock and when the lock is released the writes will be
- // flushed.
}
}
+void G1OffsetTableContigSpace::record_retained_region() {
+ // scan_top is the maximum address where it's safe for the next gc to
+ // scan this region.
+ _scan_top = top();
+}
+
void G1OffsetTableContigSpace::safe_object_iterate(ObjectClosure* blk) {
object_iterate(blk);
}
@@ -1063,6 +1064,8 @@
void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) {
CompactibleSpace::initialize(mr, clear_space, mangle_space);
_top = bottom();
+ _scan_top = bottom();
+ set_saved_mark_word(NULL);
reset_bot();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -101,28 +101,25 @@
// OffsetTableContigSpace. If the two versions of BlockOffsetTable could
// be reconciled, then G1OffsetTableContigSpace could go away.
-// The idea behind time stamps is the following. Doing a save_marks on
-// all regions at every GC pause is time consuming (if I remember
-// well, 10ms or so). So, we would like to do that only for regions
-// that are GC alloc regions. To achieve this, we use time
-// stamps. For every evacuation pause, G1CollectedHeap generates a
-// unique time stamp (essentially a counter that gets
-// incremented). Every time we want to call save_marks on a region,
-// we set the saved_mark_word to top and also copy the current GC
-// time stamp to the time stamp field of the space. Reading the
-// saved_mark_word involves checking the time stamp of the
-// region. If it is the same as the current GC time stamp, then we
-// can safely read the saved_mark_word field, as it is valid. If the
-// time stamp of the region is not the same as the current GC time
-// stamp, then we instead read top, as the saved_mark_word field is
-// invalid. Time stamps (on the regions and also on the
-// G1CollectedHeap) are reset at every cleanup (we iterate over
-// the regions anyway) and at the end of a Full GC. The current scheme
-// that uses sequential unsigned ints will fail only if we have 4b
+// The idea behind time stamps is the following. We want to keep track of
+// the highest address where it's safe to scan objects for each region.
+// This is only relevant for current GC alloc regions so we keep a time stamp
+// per region to determine if the region has been allocated during the current
+// GC or not. If the time stamp is current we report a scan_top value which
+// was saved at the end of the previous GC for retained alloc regions and which is
+// equal to the bottom for all other regions.
+// There is a race between card scanners and allocating gc workers where we must ensure
+// that card scanners do not read the memory allocated by the gc workers.
+// In order to enforce that, we must not return a value of _top which is more recent than the
+// time stamp. This is due to the fact that a region may become a gc alloc region at
+// some point after we've read the timestamp value as being < the current time stamp.
+// The time stamps are re-initialized to zero at cleanup and at Full GCs.
+// The current scheme that uses sequential unsigned ints will fail only if we have 4b
// evacuation pauses between two cleanups, which is _highly_ unlikely.
class G1OffsetTableContigSpace: public CompactibleSpace {
friend class VMStructs;
HeapWord* _top;
+ HeapWord* volatile _scan_top;
protected:
G1BlockOffsetArrayContigSpace _offsets;
Mutex _par_alloc_lock;
@@ -166,10 +163,11 @@
void set_bottom(HeapWord* value);
void set_end(HeapWord* value);
- virtual HeapWord* saved_mark_word() const;
- void record_top_and_timestamp();
+ HeapWord* scan_top() const;
+ void record_timestamp();
void reset_gc_time_stamp() { _gc_time_stamp = 0; }
unsigned get_gc_time_stamp() { return _gc_time_stamp; }
+ void record_retained_region();
// See the comment above in the declaration of _pre_dummy_top for an
// explanation of what it is.
@@ -191,6 +189,8 @@
virtual HeapWord* allocate(size_t word_size);
HeapWord* par_allocate(size_t word_size);
+ HeapWord* saved_mark_word() const { ShouldNotReachHere(); return NULL; }
+
// MarkSweep support phase3
virtual HeapWord* initialize_threshold();
virtual HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -260,7 +260,7 @@
return num_regions;
}
-void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const {
+void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer, bool concurrent) const {
const uint start_index = hrclaimer->start_region_for_worker(worker_id);
// Every worker will actually look at all regions, skipping over regions that
@@ -279,7 +279,11 @@
// We'll ignore "continues humongous" regions (we'll process them
// when we come across their corresponding "start humongous"
// region) and regions already claimed.
- if (hrclaimer->is_region_claimed(index) || r->is_continues_humongous()) {
+ // However, if the iteration is specified as concurrent, the values for
+ // is_starts_humongous and is_continues_humongous can not be trusted,
+ // and we should just blindly iterate over regions regardless of their
+ // humongous status.
+ if (hrclaimer->is_region_claimed(index) || (!concurrent && r->is_continues_humongous())) {
continue;
}
// OK, try to claim it
@@ -287,7 +291,9 @@
continue;
}
// Success!
- if (r->is_starts_humongous()) {
+ // As mentioned above, special treatment of humongous regions can only be
+ // done if we are iterating non-concurrently.
+ if (!concurrent && r->is_starts_humongous()) {
// If the region is "starts humongous" we'll iterate over its
// "continues humongous" first; in fact we'll do them
// first. The order is important. In one case, calling the
@@ -449,7 +455,7 @@
HeapRegionClaimer::~HeapRegionClaimer() {
if (_claims != NULL) {
- FREE_C_HEAP_ARRAY(uint, _claims, mtGC);
+ FREE_C_HEAP_ARRAY(uint, _claims);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -222,7 +222,7 @@
// terminating the iteration early if doHeapRegion() returns true.
void iterate(HeapRegionClosure* blk) const;
- void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const;
+ void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer, bool concurrent) const;
// Uncommit up to num_regions_to_remove regions that are completely free.
// Return the actual number of uncommitted regions.
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -449,5 +449,5 @@
bot_storage->uncommit_regions(0, num_regions_in_test);
delete bot_storage;
- FREE_C_HEAP_ARRAY(HeapWord, bot_data, mtGC);
+ FREE_C_HEAP_ARRAY(HeapWord, bot_data);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -129,7 +129,7 @@
assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
void* b = BufferNode::make_block_from_node(_buf_free_list);
_buf_free_list = _buf_free_list->next();
- FREE_C_HEAP_ARRAY(char, b, mtGC);
+ FREE_C_HEAP_ARRAY(char, b);
_buf_free_list_sz --;
n--;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -154,11 +154,11 @@
RSHashTable::~RSHashTable() {
if (_entries != NULL) {
- FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
+ FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries);
_entries = NULL;
}
if (_buckets != NULL) {
- FREE_C_HEAP_ARRAY(int, _buckets, mtGC);
+ FREE_C_HEAP_ARRAY(int, _buckets);
_buckets = NULL;
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -106,13 +106,13 @@
_stats_arrays_length = _region_num;
if (old_surv_rate != NULL) {
- FREE_C_HEAP_ARRAY(double, old_surv_rate, mtGC);
+ FREE_C_HEAP_ARRAY(double, old_surv_rate);
}
if (old_accum_surv_rate_pred != NULL) {
- FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred, mtGC);
+ FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
}
if (old_surv_rate_pred != NULL) {
- FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred, mtGC);
+ FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -92,12 +92,8 @@
void VM_G1IncCollectionPause::doit() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- assert(!_should_initiate_conc_mark ||
- ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
- (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
- _gc_cause == GCCause::_g1_humongous_allocation ||
- _gc_cause == GCCause::_update_allocation_context_stats_inc),
- "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle");
+ assert(!_should_initiate_conc_mark || g1h->should_do_concurrent_full_gc(_gc_cause),
+ "only a GC locker, a System.gc(), stats update, whitebox, or a hum allocation induced GC should start a cycle");
if (_word_size > 0) {
// An allocation has been requested. So, try to do that first.
@@ -230,7 +226,6 @@
}
void VM_CGC_Operation::doit() {
- gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm(), G1CollectedHeap::heap()->concurrent_mark()->concurrent_gc_id());
SharedHeap* sh = SharedHeap::heap();
--- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -462,7 +462,7 @@
if (_lowest_non_clean[i] != NULL) {
assert(n_chunks != _lowest_non_clean_chunk_size[i],
"logical consequence");
- FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i], mtGC);
+ FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
_lowest_non_clean[i] = NULL;
}
// Now allocate a new one if necessary.
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -39,7 +39,6 @@
#include "memory/genCollectedHeap.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "memory/generation.hpp"
-#include "memory/generation.inline.hpp"
#include "memory/referencePolicy.hpp"
#include "memory/resourceArea.hpp"
#include "memory/sharedHeap.hpp"
@@ -884,8 +883,6 @@
// A Generation that does parallel young-gen collection.
-bool ParNewGeneration::_avoid_promotion_undo = false;
-
void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
assert(_promo_failure_scan_stack.is_empty(), "post condition");
_promo_failure_scan_stack.clear(true); // Clear cached segments.
@@ -934,10 +931,6 @@
assert(gch->n_gens() == 2,
"Par collection currently only works with single older gen.");
_next_gen = gch->next_gen(this);
- // Do we have to avoid promotion_undo?
- if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
- set_avoid_promotion_undo(true);
- }
// If the next generation is too full to accommodate worst-case promotion
// from this generation, pass on collection; let the next generation
@@ -999,6 +992,11 @@
thread_state_set.reset(0 /* Bad value in debug if not reset */,
promotion_failed());
+ // Trace and reset failed promotion info.
+ if (promotion_failed()) {
+ thread_state_set.trace_promotion_failed(gc_tracer);
+ }
+
// Process (weak) reference objects found during scavenge.
ReferenceProcessor* rp = ref_processor();
IsAliveClosure is_alive(this);
@@ -1136,7 +1134,7 @@
#ifdef ASSERT
bool ParNewGeneration::is_legal_forward_ptr(oop p) {
return
- (_avoid_promotion_undo && p == ClaimedForwardPtr)
+ (p == ClaimedForwardPtr)
|| Universe::heap()->is_in_reserved(p);
}
#endif
@@ -1157,7 +1155,7 @@
// thus avoiding the need to undo the copy as in
// copy_to_survivor_space_avoiding_with_undo.
-oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
+oop ParNewGeneration::copy_to_survivor_space(
ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
// In the sequential version, this assert also says that the object is
// not forwarded. That might not be the case here. It is the case that
@@ -1277,131 +1275,6 @@
return forward_ptr;
}
-
-// Multiple GC threads may try to promote the same object. If two
-// or more GC threads copy the object, only one wins the race to install
-// the forwarding pointer. The other threads have to undo their copy.
-
-oop ParNewGeneration::copy_to_survivor_space_with_undo(
- ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
-
- // In the sequential version, this assert also says that the object is
- // not forwarded. That might not be the case here. It is the case that
- // the caller observed it to be not forwarded at some time in the past.
- assert(is_in_reserved(old), "shouldn't be scavenging this oop");
-
- // The sequential code read "old->age()" below. That doesn't work here,
- // since the age is in the mark word, and that might be overwritten with
- // a forwarding pointer by a parallel thread. So we must save the mark
- // word here, install it in a local oopDesc, and then analyze it.
- oopDesc dummyOld;
- dummyOld.set_mark(m);
- assert(!dummyOld.is_forwarded(),
- "should not be called with forwarding pointer mark word.");
-
- bool failed_to_promote = false;
- oop new_obj = NULL;
- oop forward_ptr;
-
- // Try allocating obj in to-space (unless too old)
- if (dummyOld.age() < tenuring_threshold()) {
- new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
- if (new_obj == NULL) {
- set_survivor_overflow(true);
- }
- }
-
- if (new_obj == NULL) {
- // Either to-space is full or we decided to promote
- // try allocating obj tenured
- new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
- old, m, sz);
-
- if (new_obj == NULL) {
- // promotion failed, forward to self
- forward_ptr = old->forward_to_atomic(old);
- new_obj = old;
-
- if (forward_ptr != NULL) {
- return forward_ptr; // someone else succeeded
- }
-
- _promotion_failed = true;
- failed_to_promote = true;
-
- preserve_mark_if_necessary(old, m);
- par_scan_state->register_promotion_failure(sz);
- }
- } else {
- // Is in to-space; do copying ourselves.
- Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
- // Restore the mark word copied above.
- new_obj->set_mark(m);
- // Increment age if new_obj still in new generation
- new_obj->incr_age();
- par_scan_state->age_table()->add(new_obj, sz);
- }
- assert(new_obj != NULL, "just checking");
-
-#ifndef PRODUCT
- // This code must come after the CAS test, or it will print incorrect
- // information.
- if (TraceScavenge) {
- gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
- is_in_reserved(new_obj) ? "copying" : "tenuring",
- new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
- }
-#endif
-
- // Now attempt to install the forwarding pointer (atomically).
- // We have to copy the mark word before overwriting with forwarding
- // ptr, so we can restore it below in the copy.
- if (!failed_to_promote) {
- forward_ptr = old->forward_to_atomic(new_obj);
- }
-
- if (forward_ptr == NULL) {
- oop obj_to_push = new_obj;
- if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) {
- // Length field used as index of next element to be scanned.
- // Real length can be obtained from real_forwardee()
- arrayOop(old)->set_length(0);
- obj_to_push = old;
- assert(obj_to_push->is_forwarded() && obj_to_push->forwardee() != obj_to_push,
- "push forwarded object");
- }
- // Push it on one of the queues of to-be-scanned objects.
- bool simulate_overflow = false;
- NOT_PRODUCT(
- if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) {
- // simulate a stack overflow
- simulate_overflow = true;
- }
- )
- if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
- // Add stats for overflow pushes.
- push_on_overflow_list(old, par_scan_state);
- TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
- }
-
- return new_obj;
- }
-
- // Oops. Someone beat us to it. Undo the allocation. Where did we
- // allocate it?
- if (is_in_reserved(new_obj)) {
- // Must be in to_space.
- assert(to()->is_in_reserved(new_obj), "Checking");
- par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
- } else {
- assert(!_avoid_promotion_undo, "Should not be here if avoiding.");
- _next_gen->par_promote_alloc_undo(par_scan_state->thread_num(),
- (HeapWord*)new_obj, sz);
- }
-
- return forward_ptr;
-}
-
#ifndef PRODUCT
// It's OK to call this multi-threaded; the worst thing
// that can happen is that we'll get a bunch of closely
@@ -1609,7 +1482,7 @@
// This can become a scaling bottleneck when there is work queue overflow coincident
// with promotion failure.
oopDesc* f = cur;
- FREE_C_HEAP_ARRAY(oopDesc, f, mtGC);
+ FREE_C_HEAP_ARRAY(oopDesc, f);
} else if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
obj_to_push = cur;
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -329,9 +329,6 @@
oop _overflow_list;
NOT_PRODUCT(ssize_t _num_par_pushes;)
- // If true, older generation does not support promotion undo, so avoid.
- static bool _avoid_promotion_undo;
-
// This closure is used by the reference processor to filter out
// references to live referent.
DefNewGeneration::IsAliveClosure _is_alive_closure;
@@ -349,9 +346,6 @@
bool _survivor_overflow;
- bool avoid_promotion_undo() { return _avoid_promotion_undo; }
- void set_avoid_promotion_undo(bool v) { _avoid_promotion_undo = v; }
-
bool survivor_overflow() { return _survivor_overflow; }
void set_survivor_overflow(bool v) { _survivor_overflow = v; }
@@ -372,7 +366,6 @@
// override
virtual bool refs_discovery_is_mt() const {
- assert(UseParNewGC, "ParNewGeneration only when UseParNewGC");
return ParallelGCThreads > 1;
}
@@ -386,20 +379,7 @@
// "obj" is the object to be copied, "m" is a recent value of its mark
// that must not contain a forwarding pointer (though one might be
// inserted in "obj"s mark word by a parallel thread).
- inline oop copy_to_survivor_space(ParScanThreadState* par_scan_state,
- oop obj, size_t obj_sz, markOop m) {
- if (_avoid_promotion_undo) {
- return copy_to_survivor_space_avoiding_promotion_undo(par_scan_state,
- obj, obj_sz, m);
- }
-
- return copy_to_survivor_space_with_undo(par_scan_state, obj, obj_sz, m);
- }
-
- oop copy_to_survivor_space_avoiding_promotion_undo(ParScanThreadState* par_scan_state,
- oop obj, size_t obj_sz, markOop m);
-
- oop copy_to_survivor_space_with_undo(ParScanThreadState* par_scan_state,
+ oop copy_to_survivor_space(ParScanThreadState* par_scan_state,
oop obj, size_t obj_sz, markOop m);
// in support of testing overflow code
--- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -28,6 +28,7 @@
#include "gc_implementation/parNew/parNewGeneration.hpp"
#include "gc_implementation/parNew/parOopClosures.hpp"
#include "memory/cardTableRS.hpp"
+#include "memory/genCollectedHeap.hpp"
template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
assert (!oopDesc::is_null(*p), "null weak reference?");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -429,7 +429,7 @@
}
tty->cr();
}
- FREE_C_HEAP_ARRAY(uint, processor_assignment, mtGC);
+ FREE_C_HEAP_ARRAY(uint, processor_assignment);
}
reset_busy_workers();
set_unblocked();
@@ -458,11 +458,11 @@
GCTaskThread::destroy(thread(i));
set_thread(i, NULL);
}
- FREE_C_HEAP_ARRAY(GCTaskThread*, _thread, mtGC);
+ FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
_thread = NULL;
}
if (_resource_flag != NULL) {
- FREE_C_HEAP_ARRAY(bool, _resource_flag, mtGC);
+ FREE_C_HEAP_ARRAY(bool, _resource_flag);
_resource_flag = NULL;
}
if (queue() != NULL) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -58,7 +58,7 @@
GCTaskThread::~GCTaskThread() {
if (_time_stamps != NULL) {
- FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps, mtGC);
+ FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps);
}
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -168,7 +168,6 @@
{
HandleMark hm;
- gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer->gc_id());
TraceCollectorStats tcs(counters());
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -2055,7 +2055,6 @@
gc_task_manager()->task_idle_workers();
heap->set_par_threads(gc_task_manager()->active_workers());
- gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
TraceCollectorStats tcs(counters());
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -330,7 +330,6 @@
ResourceMark rm;
HandleMark hm;
- gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
TraceCollectorStats tcs(counters());
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -53,7 +53,7 @@
ContiguousSpace* s, GenerationCounters* gc);
~CSpaceCounters() {
- if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtInternal);
+ if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
}
virtual inline void update_capacity() {
--- a/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -50,7 +50,7 @@
CollectorCounters(const char* name, int ordinal);
~CollectorCounters() {
- if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+ if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
}
inline PerfCounter* invocation_counter() const { return _invocations; }
--- a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -55,7 +55,7 @@
GenerationCounters* gc, bool sampled=true);
~GSpaceCounters() {
- if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+ if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
}
inline void update_capacity() {
--- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -49,10 +49,8 @@
}
if (_doit) {
- if (PrintGCTimeStamps) {
- gclog_or_tty->stamp();
- gclog_or_tty->print(": ");
- }
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
if (PrintGCID) {
gclog_or_tty->print("#%u: ", gc_id.id());
}
--- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -69,7 +69,7 @@
size_t min_capacity, size_t max_capacity, VirtualSpace* v);
~GenerationCounters() {
- if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+ if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
}
virtual void update_all();
--- a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -54,7 +54,7 @@
size_t initial_capacity, GenerationCounters* gc);
~HSpaceCounters() {
- if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+ if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
}
inline void update_capacity(size_t v) {
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -276,7 +276,7 @@
}
}
- FREE_C_HEAP_ARRAY(int, lgrp_ids, mtGC);
+ FREE_C_HEAP_ARRAY(int, lgrp_ids);
if (changed) {
for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -142,216 +142,3 @@
"FT"[_retained], _retained_filler.start(), _retained_filler.end());
}
#endif // !PRODUCT
-
-const size_t ParGCAllocBufferWithBOT::ChunkSizeInWords =
-MIN2(CardTableModRefBS::par_chunk_heapword_alignment(),
- ((size_t)Generation::GenGrain)/HeapWordSize);
-const size_t ParGCAllocBufferWithBOT::ChunkSizeInBytes =
-MIN2(CardTableModRefBS::par_chunk_heapword_alignment() * HeapWordSize,
- (size_t)Generation::GenGrain);
-
-ParGCAllocBufferWithBOT::ParGCAllocBufferWithBOT(size_t word_sz,
- BlockOffsetSharedArray* bsa) :
- ParGCAllocBuffer(word_sz),
- _bsa(bsa),
- _bt(bsa, MemRegion(_bottom, _hard_end)),
- _true_end(_hard_end)
-{}
-
-// The buffer comes with its own BOT, with a shared (obviously) underlying
-// BlockOffsetSharedArray. We manipulate this BOT in the normal way
-// as we would for any contiguous space. However, on occasion we
-// need to do some buffer surgery at the extremities before we
-// start using the body of the buffer for allocations. Such surgery
-// (as explained elsewhere) is to prevent allocation on a card that
-// is in the process of being walked concurrently by another GC thread.
-// When such surgery happens at a point that is far removed (to the
-// right of the current allocation point, top), we use the "contig"
-// parameter below to directly manipulate the shared array without
-// modifying the _next_threshold state in the BOT.
-void ParGCAllocBufferWithBOT::fill_region_with_block(MemRegion mr,
- bool contig) {
- CollectedHeap::fill_with_object(mr);
- if (contig) {
- _bt.alloc_block(mr.start(), mr.end());
- } else {
- _bt.BlockOffsetArray::alloc_block(mr.start(), mr.end());
- }
-}
-
-HeapWord* ParGCAllocBufferWithBOT::allocate_slow(size_t word_sz) {
- HeapWord* res = NULL;
- if (_true_end > _hard_end) {
- assert((HeapWord*)align_size_down(intptr_t(_hard_end),
- ChunkSizeInBytes) == _hard_end,
- "or else _true_end should be equal to _hard_end");
- assert(_retained, "or else _true_end should be equal to _hard_end");
- assert(_retained_filler.end() <= _top, "INVARIANT");
- CollectedHeap::fill_with_object(_retained_filler);
- if (_top < _hard_end) {
- fill_region_with_block(MemRegion(_top, _hard_end), true);
- }
- HeapWord* next_hard_end = MIN2(_true_end, _hard_end + ChunkSizeInWords);
- _retained_filler = MemRegion(_hard_end, FillerHeaderSize);
- _bt.alloc_block(_retained_filler.start(), _retained_filler.word_size());
- _top = _retained_filler.end();
- _hard_end = next_hard_end;
- _end = _hard_end - AlignmentReserve;
- res = ParGCAllocBuffer::allocate(word_sz);
- if (res != NULL) {
- _bt.alloc_block(res, word_sz);
- }
- }
- return res;
-}
-
-void
-ParGCAllocBufferWithBOT::undo_allocation(HeapWord* obj, size_t word_sz) {
- ParGCAllocBuffer::undo_allocation(obj, word_sz);
- // This may back us up beyond the previous threshold, so reset.
- _bt.set_region(MemRegion(_top, _hard_end));
- _bt.initialize_threshold();
-}
-
-void ParGCAllocBufferWithBOT::retire(bool end_of_gc, bool retain) {
- assert(!retain || end_of_gc, "Can only retain at GC end.");
- if (_retained) {
- // We're about to make the retained_filler into a block.
- _bt.BlockOffsetArray::alloc_block(_retained_filler.start(),
- _retained_filler.end());
- }
- // Reset _hard_end to _true_end (and update _end)
- if (retain && _hard_end != NULL) {
- assert(_hard_end <= _true_end, "Invariant.");
- _hard_end = _true_end;
- _end = MAX2(_top, _hard_end - AlignmentReserve);
- assert(_end <= _hard_end, "Invariant.");
- }
- _true_end = _hard_end;
- HeapWord* pre_top = _top;
-
- ParGCAllocBuffer::retire(end_of_gc, retain);
- // Now any old _retained_filler is cut back to size, the free part is
- // filled with a filler object, and top is past the header of that
- // object.
-
- if (retain && _top < _end) {
- assert(end_of_gc && retain, "Or else retain should be false.");
- // If the lab does not start on a card boundary, we don't want to
- // allocate onto that card, since that might lead to concurrent
- // allocation and card scanning, which we don't support. So we fill
- // the first card with a garbage object.
- size_t first_card_index = _bsa->index_for(pre_top);
- HeapWord* first_card_start = _bsa->address_for_index(first_card_index);
- if (first_card_start < pre_top) {
- HeapWord* second_card_start =
- _bsa->inc_by_region_size(first_card_start);
-
- // Ensure enough room to fill with the smallest block
- second_card_start = MAX2(second_card_start, pre_top + AlignmentReserve);
-
- // If the end is already in the first card, don't go beyond it!
- // Or if the remainder is too small for a filler object, gobble it up.
- if (_hard_end < second_card_start ||
- pointer_delta(_hard_end, second_card_start) < AlignmentReserve) {
- second_card_start = _hard_end;
- }
- if (pre_top < second_card_start) {
- MemRegion first_card_suffix(pre_top, second_card_start);
- fill_region_with_block(first_card_suffix, true);
- }
- pre_top = second_card_start;
- _top = pre_top;
- _end = MAX2(_top, _hard_end - AlignmentReserve);
- }
-
- // If the lab does not end on a card boundary, we don't want to
- // allocate onto that card, since that might lead to concurrent
- // allocation and card scanning, which we don't support. So we fill
- // the last card with a garbage object.
- size_t last_card_index = _bsa->index_for(_hard_end);
- HeapWord* last_card_start = _bsa->address_for_index(last_card_index);
- if (last_card_start < _hard_end) {
-
- // Ensure enough room to fill with the smallest block
- last_card_start = MIN2(last_card_start, _hard_end - AlignmentReserve);
-
- // If the top is already in the last card, don't go back beyond it!
- // Or if the remainder is too small for a filler object, gobble it up.
- if (_top > last_card_start ||
- pointer_delta(last_card_start, _top) < AlignmentReserve) {
- last_card_start = _top;
- }
- if (last_card_start < _hard_end) {
- MemRegion last_card_prefix(last_card_start, _hard_end);
- fill_region_with_block(last_card_prefix, false);
- }
- _hard_end = last_card_start;
- _end = MAX2(_top, _hard_end - AlignmentReserve);
- _true_end = _hard_end;
- assert(_end <= _hard_end, "Invariant.");
- }
-
- // At this point:
- // 1) we had a filler object from the original top to hard_end.
- // 2) We've filled in any partial cards at the front and back.
- if (pre_top < _hard_end) {
- // Now we can reset the _bt to do allocation in the given area.
- MemRegion new_filler(pre_top, _hard_end);
- fill_region_with_block(new_filler, false);
- _top = pre_top + ParGCAllocBuffer::FillerHeaderSize;
- // If there's no space left, don't retain.
- if (_top >= _end) {
- _retained = false;
- invalidate();
- return;
- }
- _retained_filler = MemRegion(pre_top, _top);
- _bt.set_region(MemRegion(_top, _hard_end));
- _bt.initialize_threshold();
- assert(_bt.threshold() > _top, "initialize_threshold failed!");
-
- // There may be other reasons for queries into the middle of the
- // filler object. When such queries are done in parallel with
- // allocation, bad things can happen, if the query involves object
- // iteration. So we ensure that such queries do not involve object
- // iteration, by putting another filler object on the boundaries of
- // such queries. One such is the object spanning a parallel card
- // chunk boundary.
-
- // "chunk_boundary" is the address of the first chunk boundary less
- // than "hard_end".
- HeapWord* chunk_boundary =
- (HeapWord*)align_size_down(intptr_t(_hard_end-1), ChunkSizeInBytes);
- assert(chunk_boundary < _hard_end, "Or else above did not work.");
- assert(pointer_delta(_true_end, chunk_boundary) >= AlignmentReserve,
- "Consequence of last card handling above.");
-
- if (_top <= chunk_boundary) {
- assert(_true_end == _hard_end, "Invariant.");
- while (_top <= chunk_boundary) {
- assert(pointer_delta(_hard_end, chunk_boundary) >= AlignmentReserve,
- "Consequence of last card handling above.");
- _bt.BlockOffsetArray::alloc_block(chunk_boundary, _hard_end);
- CollectedHeap::fill_with_object(chunk_boundary, _hard_end);
- _hard_end = chunk_boundary;
- chunk_boundary -= ChunkSizeInWords;
- }
- _end = _hard_end - AlignmentReserve;
- assert(_top <= _end, "Invariant.");
- // Now reset the initial filler chunk so it doesn't overlap with
- // the one(s) inserted above.
- MemRegion new_filler(pre_top, _hard_end);
- fill_region_with_block(new_filler, false);
- }
- } else {
- _retained = false;
- invalidate();
- }
- } else {
- assert(!end_of_gc ||
- (!_retained && _true_end == _hard_end), "Checking.");
- }
- assert(_end <= _hard_end, "Invariant.");
- assert(_top < _end || _top == _hard_end, "Invariant");
-}
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -216,44 +216,4 @@
}
};
-class ParGCAllocBufferWithBOT: public ParGCAllocBuffer {
- BlockOffsetArrayContigSpace _bt;
- BlockOffsetSharedArray* _bsa;
- HeapWord* _true_end; // end of the whole ParGCAllocBuffer
-
- static const size_t ChunkSizeInWords;
- static const size_t ChunkSizeInBytes;
- HeapWord* allocate_slow(size_t word_sz);
-
- void fill_region_with_block(MemRegion mr, bool contig);
-
-public:
- ParGCAllocBufferWithBOT(size_t word_sz, BlockOffsetSharedArray* bsa);
-
- HeapWord* allocate(size_t word_sz) {
- HeapWord* res = ParGCAllocBuffer::allocate(word_sz);
- if (res != NULL) {
- _bt.alloc_block(res, word_sz);
- } else {
- res = allocate_slow(word_sz);
- }
- return res;
- }
-
- void undo_allocation(HeapWord* obj, size_t word_sz);
-
- virtual void set_buf(HeapWord* buf_start) {
- ParGCAllocBuffer::set_buf(buf_start);
- _true_end = _hard_end;
- _bt.set_region(MemRegion(buf_start, word_sz()));
- _bt.initialize_threshold();
- }
-
- virtual void retire(bool end_of_gc, bool retain);
-
- MemRegion range() {
- return MemRegion(_top, _true_end);
- }
-};
-
#endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -56,7 +56,7 @@
MutableSpace* m, GenerationCounters* gc);
~SpaceCounters() {
- if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+ if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
}
inline void update_capacity() {
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -54,6 +54,9 @@
case _wb_young_gc:
return "WhiteBox Initiated Young GC";
+ case _wb_conc_mark:
+ return "WhiteBox Initiated Concurrent Mark";
+
case _update_allocation_context_stats_inc:
case _update_allocation_context_stats_full:
return "Update Allocation Context Stats";
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -47,6 +47,7 @@
_heap_inspection,
_heap_dump,
_wb_young_gc,
+ _wb_conc_mark,
_update_allocation_context_stats_inc,
_update_allocation_context_stats_full,
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -334,7 +334,7 @@
if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
"This bit mask should not be in the resource area");
- FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0], mtClass);
+ FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
debug_only(_bit_mask[0] = 0;)
}
}
@@ -492,7 +492,7 @@
flush();
// Deallocate array
NOT_PRODUCT(_total_memory_usage -= sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);)
- FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array, mtClass);
+ FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array);
}
OopMapCacheEntry* OopMapCache::entry_at(int i) const {
@@ -603,5 +603,5 @@
tmp->initialize();
tmp->fill(method, bci);
entry->resource_copy(tmp);
- FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp, mtInternal);
+ FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp);
}
--- a/hotspot/src/share/vm/memory/allocation.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/allocation.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -296,7 +296,7 @@
// to avoid deadlock with NMT
while(cur != NULL) {
next = cur->next();
- os::free(cur, mtChunk);
+ os::free(cur);
cur = next;
}
}
@@ -384,7 +384,7 @@
case Chunk::medium_size: ChunkPool::medium_pool()->free(c); break;
case Chunk::init_size: ChunkPool::small_pool()->free(c); break;
case Chunk::tiny_size: ChunkPool::tiny_pool()->free(c); break;
- default: os::free(c, mtChunk);
+ default: os::free(c);
}
}
--- a/hotspot/src/share/vm/memory/allocation.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/allocation.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -101,7 +101,7 @@
// NEW_RESOURCE_OBJ(type)
// NEW_C_HEAP_ARRAY(type, size)
// NEW_C_HEAP_OBJ(type, memflags)
-// FREE_C_HEAP_ARRAY(type, old, memflags)
+// FREE_C_HEAP_ARRAY(type, old)
// FREE_C_HEAP_OBJ(objname, type, memflags)
// char* AllocateHeap(size_t size, const char* name);
// void FreeHeap(void* p);
@@ -669,8 +669,8 @@
#define REALLOC_C_HEAP_ARRAY_RETURN_NULL(type, old, size, memflags)\
(type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
-#define FREE_C_HEAP_ARRAY(type, old, memflags) \
- FreeHeap((char*)(old), memflags)
+#define FREE_C_HEAP_ARRAY(type, old) \
+ FreeHeap((char*)(old))
// allocate type in heap without calling ctor
#define NEW_C_HEAP_OBJ(type, memflags)\
@@ -680,8 +680,8 @@
NEW_C_HEAP_ARRAY_RETURN_NULL(type, 1, memflags)
// deallocate obj of type in heap without calling dtor
-#define FREE_C_HEAP_OBJ(objname, memflags)\
- FreeHeap((char*)objname, memflags);
+#define FREE_C_HEAP_OBJ(objname)\
+ FreeHeap((char*)objname);
// for statistics
#ifndef PRODUCT
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -79,11 +79,11 @@
return p;
}
-inline void FreeHeap(void* p, MEMFLAGS memflags = mtInternal) {
+inline void FreeHeap(void* p) {
#ifdef ASSERT
if (PrintMallocFree) trace_heap_free(p);
#endif
- os::free(p, memflags);
+ os::free(p);
}
@@ -136,11 +136,11 @@
}
template <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
- FreeHeap(p, F);
+ FreeHeap(p);
}
template <MEMFLAGS F> void CHeapObj<F>::operator delete [](void* p){
- FreeHeap(p, F);
+ FreeHeap(p);
}
template <class E, MEMFLAGS F>
@@ -199,7 +199,7 @@
void ArrayAllocator<E, F>::free() {
if (_addr != NULL) {
if (_use_malloc) {
- FreeHeap(_addr, F);
+ FreeHeap(_addr);
} else {
os::release_memory(_addr, _size);
}
--- a/hotspot/src/share/vm/memory/blockOffsetTable.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/blockOffsetTable.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -251,12 +251,6 @@
// Return the address indicating the start of the region corresponding to
// "index" in "_offset_array".
HeapWord* address_for_index(size_t index) const;
-
- // Return the address "p" incremented by the size of
- // a region. This method does not align the address
- // returned to the start of a region. It is a simple
- // primitive.
- HeapWord* inc_by_region_size(HeapWord* p) const { return p + N_words; }
};
//////////////////////////////////////////////////////////////////////////
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -171,19 +171,19 @@
_committed = NULL;
}
if (_lowest_non_clean) {
- FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean, mtGC);
+ FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean);
_lowest_non_clean = NULL;
}
if (_lowest_non_clean_chunk_size) {
- FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size, mtGC);
+ FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size);
_lowest_non_clean_chunk_size = NULL;
}
if (_lowest_non_clean_base_chunk_index) {
- FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index, mtGC);
+ FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index);
_lowest_non_clean_base_chunk_index = NULL;
}
if (_last_LNC_resizing_collection) {
- FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection, mtGC);
+ FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection);
_last_LNC_resizing_collection = NULL;
}
}
@@ -462,19 +462,6 @@
// equal to active_workers. When a different mechanism for shutting
// off parallelism is used, then active_workers can be used in
// place of n_par_threads.
- // This is an example of a path where n_par_threads is
- // set to 0 to turn off parallelism.
- // [7] CardTableModRefBS::non_clean_card_iterate()
- // [8] CardTableRS::younger_refs_in_space_iterate()
- // [9] Generation::younger_refs_in_space_iterate()
- // [10] OneContigSpaceCardGeneration::younger_refs_iterate()
- // [11] CompactingPermGenGen::younger_refs_iterate()
- // [12] CardTableRS::younger_refs_iterate()
- // [13] SharedHeap::process_strong_roots()
- // [14] G1CollectedHeap::verify()
- // [15] Universe::verify()
- // [16] G1CollectedHeap::do_collection_pause_at_safepoint()
- //
int n_threads = SharedHeap::heap()->n_par_threads();
bool is_par = n_threads > 0;
if (is_par) {
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -466,11 +466,6 @@
void verify_region(MemRegion mr, jbyte val, bool val_equals) PRODUCT_RETURN;
void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN;
void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
-
- static size_t par_chunk_heapword_alignment() {
- return ParGCCardsPerStrideChunk * card_size_in_words;
- }
-
};
class CardTableRS;
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -70,7 +70,7 @@
_ct_bs = NULL;
}
if (_last_cur_val_in_gen) {
- FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen, mtInternal);
+ FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
}
}
@@ -283,14 +283,14 @@
// Convert the assertion check to a warning if we are running
// CMS+ParNew until related bug is fixed.
MemRegion ur = sp->used_region();
- assert(ur.contains(urasm) || (UseConcMarkSweepGC && UseParNewGC),
+ assert(ur.contains(urasm) || (UseConcMarkSweepGC),
err_msg("Did you forget to call save_marks()? "
"[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end())));
// In the case of CMS+ParNew, issue a warning
if (!ur.contains(urasm)) {
- assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above");
+ assert(UseConcMarkSweepGC, "Tautology: see assert above");
warning("CMS+ParNew: Did you forget to call save_marks()? "
"[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
@@ -609,21 +609,3 @@
_ct_bs->verify();
}
}
-
-
-void CardTableRS::verify_aligned_region_empty(MemRegion mr) {
- if (!mr.is_empty()) {
- jbyte* cur_entry = byte_for(mr.start());
- jbyte* limit = byte_after(mr.last());
- // The region mr may not start on a card boundary so
- // the first card may reflect a write to the space
- // just prior to mr.
- if (!is_aligned(mr.start())) {
- cur_entry++;
- }
- for (;cur_entry < limit; cur_entry++) {
- guarantee(*cur_entry == CardTableModRefBS::clean_card,
- "Unexpected dirty card found");
- }
- }
-}
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/cardTableRS.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -138,7 +138,6 @@
}
void verify();
- void verify_aligned_region_empty(MemRegion mr);
void clear(MemRegion mr) { _ct_bs->clear(mr); }
void clear_into_younger(Generation* old_gen);
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -908,31 +908,14 @@
}
void MarkSweepPolicy::initialize_generations() {
- _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, CURRENT_PC,
- AllocFailStrategy::RETURN_NULL);
- if (_generations == NULL) {
- vm_exit_during_initialization("Unable to allocate gen spec");
- }
-
- if (UseParNewGC) {
- _generations[0] = new GenerationSpec(Generation::ParNew, _initial_young_size, _max_young_size);
- } else {
- _generations[0] = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size);
- }
+ _generations = NEW_C_HEAP_ARRAY(GenerationSpecPtr, number_of_generations(), mtGC);
+ _generations[0] = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size);
_generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_old_size, _max_old_size);
-
- if (_generations[0] == NULL || _generations[1] == NULL) {
- vm_exit_during_initialization("Unable to allocate gen spec");
- }
}
void MarkSweepPolicy::initialize_gc_policy_counters() {
// Initialize the policy counters - 2 collectors, 3 generations.
- if (UseParNewGC) {
- _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);
- } else {
- _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
- }
+ _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
}
/////////////// Unit tests ///////////////
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -29,7 +29,6 @@
#include "gc_implementation/shared/cSpaceCounters.hpp"
#include "gc_implementation/shared/generationCounters.hpp"
#include "gc_implementation/shared/copyFailedInfo.hpp"
-#include "memory/generation.inline.hpp"
#include "utilities/stack.hpp"
class ContiguousSpace;
@@ -340,9 +339,6 @@
virtual const char* name() const;
virtual const char* short_name() const { return "DefNew"; }
- bool must_be_youngest() const { return true; }
- bool must_be_oldest() const { return false; }
-
// PrintHeapAtGC support.
void print_on(outputStream* st) const;
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/filemap.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -331,7 +331,7 @@
n = os::read(fd, _paths_misc_info, (unsigned int)info_size);
if (n != info_size) {
fail_continue("Unable to read the shared path info header.");
- FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
+ FREE_C_HEAP_ARRAY(char, _paths_misc_info);
_paths_misc_info = NULL;
return false;
}
@@ -714,7 +714,7 @@
}
if (_paths_misc_info != NULL) {
- FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
+ FREE_C_HEAP_ARRAY(char, _paths_misc_info);
_paths_misc_info = NULL;
}
return status;
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -36,7 +36,6 @@
#include "memory/gcLocker.inline.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/genOopClosures.inline.hpp"
-#include "memory/generation.inline.hpp"
#include "memory/generationSpec.hpp"
#include "memory/resourceArea.hpp"
#include "memory/sharedHeap.hpp"
@@ -182,10 +181,10 @@
SharedHeap::post_initialize();
GenCollectorPolicy *policy = (GenCollectorPolicy *)collector_policy();
guarantee(policy->is_generation_policy(), "Illegal policy type");
- DefNewGeneration* def_new_gen = (DefNewGeneration*) get_gen(0);
- assert(def_new_gen->kind() == Generation::DefNew ||
- def_new_gen->kind() == Generation::ParNew,
- "Wrong generation kind");
+ assert((get_gen(0)->kind() == Generation::DefNew) ||
+ (get_gen(0)->kind() == Generation::ParNew),
+ "Wrong youngest generation type");
+ DefNewGeneration* def_new_gen = (DefNewGeneration*)get_gen(0);
Generation* old_gen = get_gen(1);
assert(old_gen->kind() == Generation::ConcurrentMarkSweep ||
@@ -363,7 +362,6 @@
bool complete = full && (max_level == (n_gens()-1));
const char* gc_cause_prefix = complete ? "Full GC" : "GC";
- gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
// The PrintGCDetails logging starts before we have incremented the GC id. We will do that later
// so we can assume here that the next GC id is what we want.
@@ -1118,10 +1116,8 @@
void GenCollectedHeap::print_gc_threads_on(outputStream* st) const {
#if INCLUDE_ALL_GCS
- if (UseParNewGC) {
+ if (UseConcMarkSweepGC) {
workers()->print_worker_threads_on(st);
- }
- if (UseConcMarkSweepGC) {
ConcurrentMarkSweepThread::print_all_on(st);
}
#endif // INCLUDE_ALL_GCS
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -262,12 +262,12 @@
// We don't need barriers for stores to objects in the
// young gen and, a fortiori, for initializing stores to
- // objects therein. This applies to {DefNew,ParNew}+{Tenured,CMS}
+ // objects therein. This applies to DefNew+Tenured and ParNew+CMS
// only and may need to be re-examined in case other
// kinds of collectors are implemented in the future.
virtual bool can_elide_initializing_store_barrier(oop new_obj) {
// We wanted to assert that:-
- // assert(UseParNewGC || UseSerialGC || UseConcMarkSweepGC,
+ // assert(UseSerialGC || UseConcMarkSweepGC,
// "Check can_elide_initializing_store_barrier() for this collector");
// but unfortunately the flag UseSerialGC need not necessarily always
// be set when DefNew+Tenured are being used.
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -37,7 +37,6 @@
#include "memory/genCollectedHeap.hpp"
#include "memory/genMarkSweep.hpp"
#include "memory/genOopClosures.inline.hpp"
-#include "memory/generation.inline.hpp"
#include "memory/modRefBarrierSet.hpp"
#include "memory/referencePolicy.hpp"
#include "memory/space.hpp"
--- a/hotspot/src/share/vm/memory/genRemSet.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/genRemSet.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -105,17 +105,6 @@
virtual void verify() = 0;
- // Verify that the remembered set has no entries for
- // the heap interval denoted by mr. If there are any
- // alignment constraints on the remembered set, only the
- // part of the region that is aligned is checked.
- //
- // alignment boundaries
- // +--------+-------+--------+-------+
- // [ region mr )
- // [ part checked )
- virtual void verify_aligned_region_empty(MemRegion mr) = 0;
-
// If appropriate, print some information about the remset on "tty".
virtual void print() {}
--- a/hotspot/src/share/vm/memory/generation.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/generation.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -36,7 +36,6 @@
#include "memory/genOopClosures.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "memory/generation.hpp"
-#include "memory/generation.inline.hpp"
#include "memory/space.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
@@ -152,13 +151,6 @@
return blk.sp != NULL;
}
-DefNewGeneration* Generation::as_DefNewGeneration() {
- assert((kind() == Generation::DefNew) ||
- (kind() == Generation::ParNew),
- "Wrong youngest generation type");
- return (DefNewGeneration*) this;
-}
-
Generation* Generation::next_gen() const {
GenCollectedHeap* gch = GenCollectedHeap::heap();
int next = level() + 1;
@@ -220,12 +212,6 @@
return NULL;
}
-void Generation::par_promote_alloc_undo(int thread_num,
- HeapWord* obj, size_t word_sz) {
- // Could do a bad general impl here that gets a lock. But no.
- guarantee(false, "No good general implementation.");
-}
-
Space* Generation::space_containing(const void* p) const {
GenerationIsInReservedClosure blk(p);
// Cast away const
@@ -616,252 +602,3 @@
// Currently nothing to do.
void CardGeneration::prepare_for_verify() {}
-
-void OneContigSpaceCardGeneration::collect(bool full,
- bool clear_all_soft_refs,
- size_t size,
- bool is_tlab) {
- GenCollectedHeap* gch = GenCollectedHeap::heap();
-
- SpecializationStats::clear();
- // Temporarily expand the span of our ref processor, so
- // refs discovery is over the entire heap, not just this generation
- ReferenceProcessorSpanMutator
- x(ref_processor(), gch->reserved_region());
-
- STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
- gc_timer->register_gc_start();
-
- SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
- gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
-
- GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
-
- gc_timer->register_gc_end();
-
- gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
-
- SpecializationStats::print();
-}
-
-HeapWord*
-OneContigSpaceCardGeneration::expand_and_allocate(size_t word_size,
- bool is_tlab,
- bool parallel) {
- assert(!is_tlab, "OneContigSpaceCardGeneration does not support TLAB allocation");
- if (parallel) {
- MutexLocker x(ParGCRareEvent_lock);
- HeapWord* result = NULL;
- size_t byte_size = word_size * HeapWordSize;
- while (true) {
- expand(byte_size, _min_heap_delta_bytes);
- if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
- }
- result = _the_space->par_allocate(word_size);
- if ( result != NULL) {
- return result;
- } else {
- // If there's not enough expansion space available, give up.
- if (_virtual_space.uncommitted_size() < byte_size) {
- return NULL;
- }
- // else try again
- }
- }
- } else {
- expand(word_size*HeapWordSize, _min_heap_delta_bytes);
- return _the_space->allocate(word_size);
- }
-}
-
-bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) {
- GCMutexLocker x(ExpandHeap_lock);
- return CardGeneration::expand(bytes, expand_bytes);
-}
-
-
-void OneContigSpaceCardGeneration::shrink(size_t bytes) {
- assert_locked_or_safepoint(ExpandHeap_lock);
- size_t size = ReservedSpace::page_align_size_down(bytes);
- if (size > 0) {
- shrink_by(size);
- }
-}
-
-
-size_t OneContigSpaceCardGeneration::capacity() const {
- return _the_space->capacity();
-}
-
-
-size_t OneContigSpaceCardGeneration::used() const {
- return _the_space->used();
-}
-
-
-size_t OneContigSpaceCardGeneration::free() const {
- return _the_space->free();
-}
-
-MemRegion OneContigSpaceCardGeneration::used_region() const {
- return the_space()->used_region();
-}
-
-size_t OneContigSpaceCardGeneration::unsafe_max_alloc_nogc() const {
- return _the_space->free();
-}
-
-size_t OneContigSpaceCardGeneration::contiguous_available() const {
- return _the_space->free() + _virtual_space.uncommitted_size();
-}
-
-bool OneContigSpaceCardGeneration::grow_by(size_t bytes) {
- assert_locked_or_safepoint(ExpandHeap_lock);
- bool result = _virtual_space.expand_by(bytes);
- if (result) {
- size_t new_word_size =
- heap_word_size(_virtual_space.committed_size());
- MemRegion mr(_the_space->bottom(), new_word_size);
- // Expand card table
- Universe::heap()->barrier_set()->resize_covered_region(mr);
- // Expand shared block offset array
- _bts->resize(new_word_size);
-
- // Fix for bug #4668531
- if (ZapUnusedHeapArea) {
- MemRegion mangle_region(_the_space->end(),
- (HeapWord*)_virtual_space.high());
- SpaceMangler::mangle_region(mangle_region);
- }
-
- // Expand space -- also expands space's BOT
- // (which uses (part of) shared array above)
- _the_space->set_end((HeapWord*)_virtual_space.high());
-
- // update the space and generation capacity counters
- update_counters();
-
- if (Verbose && PrintGC) {
- size_t new_mem_size = _virtual_space.committed_size();
- size_t old_mem_size = new_mem_size - bytes;
- gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
- SIZE_FORMAT "K to " SIZE_FORMAT "K",
- name(), old_mem_size/K, bytes/K, new_mem_size/K);
- }
- }
- return result;
-}
-
-
-bool OneContigSpaceCardGeneration::grow_to_reserved() {
- assert_locked_or_safepoint(ExpandHeap_lock);
- bool success = true;
- const size_t remaining_bytes = _virtual_space.uncommitted_size();
- if (remaining_bytes > 0) {
- success = grow_by(remaining_bytes);
- DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
- }
- return success;
-}
-
-void OneContigSpaceCardGeneration::shrink_by(size_t bytes) {
- assert_locked_or_safepoint(ExpandHeap_lock);
- // Shrink committed space
- _virtual_space.shrink_by(bytes);
- // Shrink space; this also shrinks the space's BOT
- _the_space->set_end((HeapWord*) _virtual_space.high());
- size_t new_word_size = heap_word_size(_the_space->capacity());
- // Shrink the shared block offset array
- _bts->resize(new_word_size);
- MemRegion mr(_the_space->bottom(), new_word_size);
- // Shrink the card table
- Universe::heap()->barrier_set()->resize_covered_region(mr);
-
- if (Verbose && PrintGC) {
- size_t new_mem_size = _virtual_space.committed_size();
- size_t old_mem_size = new_mem_size + bytes;
- gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
- name(), old_mem_size/K, new_mem_size/K);
- }
-}
-
-// Currently nothing to do.
-void OneContigSpaceCardGeneration::prepare_for_verify() {}
-
-
-// Override for a card-table generation with one contiguous
-// space. NOTE: For reasons that are lost in the fog of history,
-// this code is used when you iterate over perm gen objects,
-// even when one uses CDS, where the perm gen has a couple of
-// other spaces; this is because CompactingPermGenGen derives
-// from OneContigSpaceCardGeneration. This should be cleaned up,
-// see CR 6897789..
-void OneContigSpaceCardGeneration::object_iterate(ObjectClosure* blk) {
- _the_space->object_iterate(blk);
-}
-
-void OneContigSpaceCardGeneration::space_iterate(SpaceClosure* blk,
- bool usedOnly) {
- blk->do_space(_the_space);
-}
-
-void OneContigSpaceCardGeneration::younger_refs_iterate(OopsInGenClosure* blk) {
- blk->set_generation(this);
- younger_refs_in_space_iterate(_the_space, blk);
- blk->reset_generation();
-}
-
-void OneContigSpaceCardGeneration::save_marks() {
- _the_space->set_saved_mark();
-}
-
-
-void OneContigSpaceCardGeneration::reset_saved_marks() {
- _the_space->reset_saved_mark();
-}
-
-
-bool OneContigSpaceCardGeneration::no_allocs_since_save_marks() {
- return _the_space->saved_mark_at_top();
-}
-
-#define OneContig_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \
- \
-void OneContigSpaceCardGeneration:: \
-oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \
- blk->set_generation(this); \
- _the_space->oop_since_save_marks_iterate##nv_suffix(blk); \
- blk->reset_generation(); \
- save_marks(); \
-}
-
-ALL_SINCE_SAVE_MARKS_CLOSURES(OneContig_SINCE_SAVE_MARKS_ITERATE_DEFN)
-
-#undef OneContig_SINCE_SAVE_MARKS_ITERATE_DEFN
-
-
-void OneContigSpaceCardGeneration::gc_epilogue(bool full) {
- _last_gc = WaterMark(the_space(), the_space()->top());
-
- // update the generation and space performance counters
- update_counters();
- if (ZapUnusedHeapArea) {
- the_space()->check_mangled_unused_area_complete();
- }
-}
-
-void OneContigSpaceCardGeneration::record_spaces_top() {
- assert(ZapUnusedHeapArea, "Not mangling unused space");
- the_space()->set_top_for_allocations();
-}
-
-void OneContigSpaceCardGeneration::verify() {
- the_space()->verify();
-}
-
-void OneContigSpaceCardGeneration::print_on(outputStream* st) const {
- Generation::print_on(st);
- st->print(" the");
- the_space()->print_on(st);
-}
--- a/hotspot/src/share/vm/memory/generation.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/generation.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -45,9 +45,7 @@
// - ParNewGeneration - a DefNewGeneration that is collected by
// several threads
// - CardGeneration - abstract class adding offset array behavior
-// - OneContigSpaceCardGeneration - abstract class holding a single
-// contiguous space with card marking
-// - TenuredGeneration - tenured (old object) space (markSweepCompact)
+// - TenuredGeneration - tenured (old object) space (markSweepCompact)
// - ConcurrentMarkSweepGeneration - Mostly Concurrent Mark Sweep Generation
// (Detlefs-Printezis refinement of
// Boehm-Demers-Schenker)
@@ -55,9 +53,7 @@
// The system configurations currently allowed are:
//
// DefNewGeneration + TenuredGeneration
-// DefNewGeneration + ConcurrentMarkSweepGeneration
//
-// ParNewGeneration + TenuredGeneration
// ParNewGeneration + ConcurrentMarkSweepGeneration
//
@@ -229,10 +225,6 @@
return _reserved.contains(p);
}
- // Check that the generation kind is DefNewGeneration or a sub
- // class of DefNewGeneration and return a DefNewGeneration*
- DefNewGeneration* as_DefNewGeneration();
-
// If some space in the generation contains the given "addr", return a
// pointer to that space, else return "NULL".
virtual Space* space_containing(const void* addr) const;
@@ -317,11 +309,6 @@
virtual oop par_promote(int thread_num,
oop obj, markOop m, size_t word_sz);
- // Undo, if possible, the most recent par_promote_alloc allocation by
- // "thread_num" ("obj", of "word_sz").
- virtual void par_promote_alloc_undo(int thread_num,
- HeapWord* obj, size_t word_sz);
-
// Informs the current generation that all par_promote_alloc's in the
// collection have been completed; any supporting data structures can be
// reset. Default is to do nothing.
@@ -517,13 +504,6 @@
int level() const { return _level; }
- // Attributes
-
- // True iff the given generation may only be the youngest generation.
- virtual bool must_be_youngest() const = 0;
- // True iff the given generation may only be the oldest generation.
- virtual bool must_be_oldest() const = 0;
-
// Reference Processing accessor
ReferenceProcessor* const ref_processor() { return _ref_processor; }
@@ -657,99 +637,4 @@
virtual bool grow_to_reserved() = 0;
};
-// OneContigSpaceCardGeneration models a heap of old objects contained in a single
-// contiguous space.
-//
-// Garbage collection is performed using mark-compact.
-
-class OneContigSpaceCardGeneration: public CardGeneration {
- friend class VMStructs;
- // Abstractly, this is a subtype that gets access to protected fields.
- friend class VM_PopulateDumpSharedSpace;
-
- protected:
- ContiguousSpace* _the_space; // actual space holding objects
- WaterMark _last_gc; // watermark between objects allocated before
- // and after last GC.
-
- // Grow generation with specified size (returns false if unable to grow)
- virtual bool grow_by(size_t bytes);
- // Grow generation to reserved size.
- virtual bool grow_to_reserved();
- // Shrink generation with specified size (returns false if unable to shrink)
- void shrink_by(size_t bytes);
-
- // Allocation failure
- virtual bool expand(size_t bytes, size_t expand_bytes);
- void shrink(size_t bytes);
-
- // Accessing spaces
- ContiguousSpace* the_space() const { return _the_space; }
-
- public:
- OneContigSpaceCardGeneration(ReservedSpace rs, size_t initial_byte_size,
- int level, GenRemSet* remset,
- ContiguousSpace* space) :
- CardGeneration(rs, initial_byte_size, level, remset),
- _the_space(space)
- {}
-
- inline bool is_in(const void* p) const;
-
- // Space enquiries
- size_t capacity() const;
- size_t used() const;
- size_t free() const;
-
- MemRegion used_region() const;
-
- size_t unsafe_max_alloc_nogc() const;
- size_t contiguous_available() const;
-
- // Iteration
- void object_iterate(ObjectClosure* blk);
- void space_iterate(SpaceClosure* blk, bool usedOnly = false);
-
- void younger_refs_iterate(OopsInGenClosure* blk);
-
- inline CompactibleSpace* first_compaction_space() const;
-
- virtual inline HeapWord* allocate(size_t word_size, bool is_tlab);
- virtual inline HeapWord* par_allocate(size_t word_size, bool is_tlab);
-
- // Accessing marks
- inline WaterMark top_mark();
- inline WaterMark bottom_mark();
-
-#define OneContig_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
- void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
- OneContig_SINCE_SAVE_MARKS_DECL(OopsInGenClosure,_v)
- SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(OneContig_SINCE_SAVE_MARKS_DECL)
-
- void save_marks();
- void reset_saved_marks();
- bool no_allocs_since_save_marks();
-
- inline size_t block_size(const HeapWord* addr) const;
-
- inline bool block_is_obj(const HeapWord* addr) const;
-
- virtual void collect(bool full,
- bool clear_all_soft_refs,
- size_t size,
- bool is_tlab);
- HeapWord* expand_and_allocate(size_t size,
- bool is_tlab,
- bool parallel = false);
-
- virtual void prepare_for_verify();
-
- virtual void gc_epilogue(bool full);
-
- virtual void record_spaces_top();
-
- virtual void verify();
- virtual void print_on(outputStream* st) const;
-};
-
#endif // SHARE_VM_MEMORY_GENERATION_HPP
--- a/hotspot/src/share/vm/memory/generation.inline.hpp Thu Dec 11 11:44:00 2014 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2000, 2010, 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_GENERATION_INLINE_HPP
-#define SHARE_VM_MEMORY_GENERATION_INLINE_HPP
-
-#include "memory/genCollectedHeap.hpp"
-#include "memory/generation.hpp"
-#include "memory/space.hpp"
-
-bool OneContigSpaceCardGeneration::is_in(const void* p) const {
- return the_space()->is_in(p);
-}
-
-
-WaterMark OneContigSpaceCardGeneration::top_mark() {
- return the_space()->top_mark();
-}
-
-CompactibleSpace*
-OneContigSpaceCardGeneration::first_compaction_space() const {
- return the_space();
-}
-
-HeapWord* OneContigSpaceCardGeneration::allocate(size_t word_size,
- bool is_tlab) {
- assert(!is_tlab, "OneContigSpaceCardGeneration does not support TLAB allocation");
- return the_space()->allocate(word_size);
-}
-
-HeapWord* OneContigSpaceCardGeneration::par_allocate(size_t word_size,
- bool is_tlab) {
- assert(!is_tlab, "OneContigSpaceCardGeneration does not support TLAB allocation");
- return the_space()->par_allocate(word_size);
-}
-
-WaterMark OneContigSpaceCardGeneration::bottom_mark() {
- return the_space()->bottom_mark();
-}
-
-size_t OneContigSpaceCardGeneration::block_size(const HeapWord* addr) const {
- if (addr < the_space()->top()) return oop(addr)->size();
- else {
- assert(addr == the_space()->top(), "non-block head arg to block_size");
- return the_space()->_end - the_space()->top();
- }
-}
-
-bool OneContigSpaceCardGeneration::block_is_obj(const HeapWord* addr) const {
- return addr < the_space()->top();
-}
-
-#endif // SHARE_VM_MEMORY_GENERATION_INLINE_HPP
--- a/hotspot/src/share/vm/memory/heapInspection.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -153,7 +153,7 @@
for (int index = 0; index < _size; index++) {
_buckets[index].empty();
}
- FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal);
+ FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
_size = 0;
}
}
--- a/hotspot/src/share/vm/memory/memRegion.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/memRegion.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -112,10 +112,10 @@
AllocFailStrategy::RETURN_NULL);
}
void MemRegion::operator delete(void* p) {
- FreeHeap(p, mtGC);
+ FreeHeap(p);
}
void MemRegion::operator delete [](void* p) {
- FreeHeap(p, mtGC);
+ FreeHeap(p);
}
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -68,9 +68,7 @@
vm_exit_during_initialization("Failed necessary allocation.");
}
_sh = this; // ch is static, should be set only once.
- if (UseParNewGC ||
- UseG1GC ||
- (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled || CMSParallelRemarkEnabled) && use_parallel_gc_threads())) {
+ if (UseConcMarkSweepGC || UseG1GC) {
_workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);
--- a/hotspot/src/share/vm/memory/space.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/space.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -70,15 +70,13 @@
// Used in support of save_marks()
HeapWord* _saved_mark_word;
- MemRegionClosure* _preconsumptionDirtyCardClosure;
-
// A sequential tasks done structure. This supports
// parallel GC, where we have threads dynamically
// claiming sub-tasks from a larger parallel task.
SequentialSubTasksDone _par_seq_tasks;
Space():
- _bottom(NULL), _end(NULL), _preconsumptionDirtyCardClosure(NULL) { }
+ _bottom(NULL), _end(NULL) { }
public:
// Accessors
@@ -97,11 +95,8 @@
return (HeapWord*)obj >= saved_mark_word();
}
- MemRegionClosure* preconsumptionDirtyCardClosure() const {
- return _preconsumptionDirtyCardClosure;
- }
- void setPreconsumptionDirtyCardClosure(MemRegionClosure* cl) {
- _preconsumptionDirtyCardClosure = cl;
+ virtual MemRegionClosure* preconsumptionDirtyCardClosure() const {
+ return NULL;
}
// Returns a subregion of the space containing only the allocated objects in
@@ -500,7 +495,6 @@
// A space in which the free area is contiguous. It therefore supports
// faster allocation, and compaction.
class ContiguousSpace: public CompactibleSpace {
- friend class OneContigSpaceCardGeneration;
friend class VMStructs;
// Allow scan_and_forward function to call (private) overrides for auxiliary functions on this class
template <typename SpaceType>
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -24,13 +24,15 @@
#include "precompiled.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/blockOffsetTable.inline.hpp"
-#include "memory/generation.inline.hpp"
#include "memory/generationSpec.hpp"
+#include "memory/genMarkSweep.hpp"
+#include "memory/genOopClosures.inline.hpp"
#include "memory/space.hpp"
-#include "memory/tenuredGeneration.hpp"
+#include "memory/tenuredGeneration.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
#include "utilities/macros.hpp"
@@ -38,8 +40,7 @@
TenuredGeneration::TenuredGeneration(ReservedSpace rs,
size_t initial_byte_size, int level,
GenRemSet* remset) :
- OneContigSpaceCardGeneration(rs, initial_byte_size,
- level, remset, NULL)
+ CardGeneration(rs, initial_byte_size, level, remset)
{
HeapWord* bottom = (HeapWord*) _virtual_space.low();
HeapWord* end = (HeapWord*) _virtual_space.high();
@@ -64,46 +65,13 @@
_space_counters = new CSpaceCounters(gen_name, 0,
_virtual_space.reserved_size(),
_the_space, _gen_counters);
-#if INCLUDE_ALL_GCS
- if (UseParNewGC) {
- typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr;
- _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr,
- ParallelGCThreads, mtGC);
- if (_alloc_buffers == NULL)
- vm_exit_during_initialization("Could not allocate alloc_buffers");
- for (uint i = 0; i < ParallelGCThreads; i++) {
- _alloc_buffers[i] =
- new ParGCAllocBufferWithBOT(OldPLABSize, _bts);
- if (_alloc_buffers[i] == NULL)
- vm_exit_during_initialization("Could not allocate alloc_buffers");
- }
- } else {
- _alloc_buffers = NULL;
- }
-#endif // INCLUDE_ALL_GCS
-}
-
-
-const char* TenuredGeneration::name() const {
- return "tenured generation";
}
void TenuredGeneration::gc_prologue(bool full) {
_capacity_at_prologue = capacity();
_used_at_prologue = used();
- if (VerifyBeforeGC) {
- verify_alloc_buffers_clean();
- }
}
-void TenuredGeneration::gc_epilogue(bool full) {
- if (VerifyAfterGC) {
- verify_alloc_buffers_clean();
- }
- OneContigSpaceCardGeneration::gc_epilogue(full);
-}
-
-
bool TenuredGeneration::should_collect(bool full,
size_t size,
bool is_tlab) {
@@ -149,15 +117,6 @@
return result;
}
-void TenuredGeneration::collect(bool full,
- bool clear_all_soft_refs,
- size_t size,
- bool is_tlab) {
- retire_alloc_buffers_before_full_gc();
- OneContigSpaceCardGeneration::collect(full, clear_all_soft_refs,
- size, is_tlab);
-}
-
void TenuredGeneration::compute_new_size() {
assert_locked_or_safepoint(Heap_lock);
@@ -171,6 +130,7 @@
err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT
" capacity: " SIZE_FORMAT, used(), used_after_gc, capacity()));
}
+
void TenuredGeneration::update_gc_stats(int current_level,
bool full) {
// If the next lower level(s) has been collected, gather any statistics
@@ -198,96 +158,6 @@
}
}
-
-#if INCLUDE_ALL_GCS
-oop TenuredGeneration::par_promote(int thread_num,
- oop old, markOop m, size_t word_sz) {
-
- ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num];
- HeapWord* obj_ptr = buf->allocate(word_sz);
- bool is_lab = true;
- if (obj_ptr == NULL) {
-#ifndef PRODUCT
- if (Universe::heap()->promotion_should_fail()) {
- return NULL;
- }
-#endif // #ifndef PRODUCT
-
- // Slow path:
- if (word_sz * 100 < ParallelGCBufferWastePct * buf->word_sz()) {
- // Is small enough; abandon this buffer and start a new one.
- size_t buf_size = buf->word_sz();
- HeapWord* buf_space =
- TenuredGeneration::par_allocate(buf_size, false);
- if (buf_space == NULL) {
- buf_space = expand_and_allocate(buf_size, false, true /* parallel*/);
- }
- if (buf_space != NULL) {
- buf->retire(false, false);
- buf->set_buf(buf_space);
- obj_ptr = buf->allocate(word_sz);
- assert(obj_ptr != NULL, "Buffer was definitely big enough...");
- }
- };
- // Otherwise, buffer allocation failed; try allocating object
- // individually.
- if (obj_ptr == NULL) {
- obj_ptr = TenuredGeneration::par_allocate(word_sz, false);
- if (obj_ptr == NULL) {
- obj_ptr = expand_and_allocate(word_sz, false, true /* parallel */);
- }
- }
- if (obj_ptr == NULL) return NULL;
- }
- assert(obj_ptr != NULL, "program logic");
- Copy::aligned_disjoint_words((HeapWord*)old, obj_ptr, word_sz);
- oop obj = oop(obj_ptr);
- // Restore the mark word copied above.
- obj->set_mark(m);
- return obj;
-}
-
-void TenuredGeneration::par_promote_alloc_undo(int thread_num,
- HeapWord* obj,
- size_t word_sz) {
- ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num];
- if (buf->contains(obj)) {
- guarantee(buf->contains(obj + word_sz - 1),
- "should contain whole object");
- buf->undo_allocation(obj, word_sz);
- } else {
- CollectedHeap::fill_with_object(obj, word_sz);
- }
-}
-
-void TenuredGeneration::par_promote_alloc_done(int thread_num) {
- ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num];
- buf->retire(true, ParallelGCRetainPLAB);
-}
-
-void TenuredGeneration::retire_alloc_buffers_before_full_gc() {
- if (UseParNewGC) {
- for (uint i = 0; i < ParallelGCThreads; i++) {
- _alloc_buffers[i]->retire(true /*end_of_gc*/, false /*retain*/);
- }
- }
-}
-
-// Verify that any retained parallel allocation buffers do not
-// intersect with dirty cards.
-void TenuredGeneration::verify_alloc_buffers_clean() {
- if (UseParNewGC) {
- for (uint i = 0; i < ParallelGCThreads; i++) {
- _rs->verify_aligned_region_empty(_alloc_buffers[i]->range());
- }
- }
-}
-
-#else // INCLUDE_ALL_GCS
-void TenuredGeneration::retire_alloc_buffers_before_full_gc() {}
-void TenuredGeneration::verify_alloc_buffers_clean() {}
-#endif // INCLUDE_ALL_GCS
-
bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
size_t available = max_contiguous_available();
size_t av_promo = (size_t)gc_stats()->avg_promoted()->padded_average();
@@ -301,3 +171,244 @@
}
return res;
}
+
+void TenuredGeneration::collect(bool full,
+ bool clear_all_soft_refs,
+ size_t size,
+ bool is_tlab) {
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+ SpecializationStats::clear();
+ // Temporarily expand the span of our ref processor, so
+ // refs discovery is over the entire heap, not just this generation
+ ReferenceProcessorSpanMutator
+ x(ref_processor(), gch->reserved_region());
+
+ STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
+ gc_timer->register_gc_start();
+
+ SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
+ gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
+
+ GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
+
+ gc_timer->register_gc_end();
+
+ gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
+
+ SpecializationStats::print();
+}
+
+HeapWord*
+TenuredGeneration::expand_and_allocate(size_t word_size,
+ bool is_tlab,
+ bool parallel) {
+ assert(!is_tlab, "TenuredGeneration does not support TLAB allocation");
+ if (parallel) {
+ MutexLocker x(ParGCRareEvent_lock);
+ HeapWord* result = NULL;
+ size_t byte_size = word_size * HeapWordSize;
+ while (true) {
+ expand(byte_size, _min_heap_delta_bytes);
+ if (GCExpandToAllocateDelayMillis > 0) {
+ os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ }
+ result = _the_space->par_allocate(word_size);
+ if ( result != NULL) {
+ return result;
+ } else {
+ // If there's not enough expansion space available, give up.
+ if (_virtual_space.uncommitted_size() < byte_size) {
+ return NULL;
+ }
+ // else try again
+ }
+ }
+ } else {
+ expand(word_size*HeapWordSize, _min_heap_delta_bytes);
+ return _the_space->allocate(word_size);
+ }
+}
+
+bool TenuredGeneration::expand(size_t bytes, size_t expand_bytes) {
+ GCMutexLocker x(ExpandHeap_lock);
+ return CardGeneration::expand(bytes, expand_bytes);
+}
+
+
+void TenuredGeneration::shrink(size_t bytes) {
+ assert_locked_or_safepoint(ExpandHeap_lock);
+ size_t size = ReservedSpace::page_align_size_down(bytes);
+ if (size > 0) {
+ shrink_by(size);
+ }
+}
+
+
+size_t TenuredGeneration::capacity() const {
+ return _the_space->capacity();
+}
+
+
+size_t TenuredGeneration::used() const {
+ return _the_space->used();
+}
+
+
+size_t TenuredGeneration::free() const {
+ return _the_space->free();
+}
+
+MemRegion TenuredGeneration::used_region() const {
+ return the_space()->used_region();
+}
+
+size_t TenuredGeneration::unsafe_max_alloc_nogc() const {
+ return _the_space->free();
+}
+
+size_t TenuredGeneration::contiguous_available() const {
+ return _the_space->free() + _virtual_space.uncommitted_size();
+}
+
+bool TenuredGeneration::grow_by(size_t bytes) {
+ assert_locked_or_safepoint(ExpandHeap_lock);
+ bool result = _virtual_space.expand_by(bytes);
+ if (result) {
+ size_t new_word_size =
+ heap_word_size(_virtual_space.committed_size());
+ MemRegion mr(_the_space->bottom(), new_word_size);
+ // Expand card table
+ Universe::heap()->barrier_set()->resize_covered_region(mr);
+ // Expand shared block offset array
+ _bts->resize(new_word_size);
+
+ // Fix for bug #4668531
+ if (ZapUnusedHeapArea) {
+ MemRegion mangle_region(_the_space->end(),
+ (HeapWord*)_virtual_space.high());
+ SpaceMangler::mangle_region(mangle_region);
+ }
+
+ // Expand space -- also expands space's BOT
+ // (which uses (part of) shared array above)
+ _the_space->set_end((HeapWord*)_virtual_space.high());
+
+ // update the space and generation capacity counters
+ update_counters();
+
+ if (Verbose && PrintGC) {
+ size_t new_mem_size = _virtual_space.committed_size();
+ size_t old_mem_size = new_mem_size - bytes;
+ gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
+ SIZE_FORMAT "K to " SIZE_FORMAT "K",
+ name(), old_mem_size/K, bytes/K, new_mem_size/K);
+ }
+ }
+ return result;
+}
+
+
+bool TenuredGeneration::grow_to_reserved() {
+ assert_locked_or_safepoint(ExpandHeap_lock);
+ bool success = true;
+ const size_t remaining_bytes = _virtual_space.uncommitted_size();
+ if (remaining_bytes > 0) {
+ success = grow_by(remaining_bytes);
+ DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
+ }
+ return success;
+}
+
+void TenuredGeneration::shrink_by(size_t bytes) {
+ assert_locked_or_safepoint(ExpandHeap_lock);
+ // Shrink committed space
+ _virtual_space.shrink_by(bytes);
+ // Shrink space; this also shrinks the space's BOT
+ _the_space->set_end((HeapWord*) _virtual_space.high());
+ size_t new_word_size = heap_word_size(_the_space->capacity());
+ // Shrink the shared block offset array
+ _bts->resize(new_word_size);
+ MemRegion mr(_the_space->bottom(), new_word_size);
+ // Shrink the card table
+ Universe::heap()->barrier_set()->resize_covered_region(mr);
+
+ if (Verbose && PrintGC) {
+ size_t new_mem_size = _virtual_space.committed_size();
+ size_t old_mem_size = new_mem_size + bytes;
+ gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+ name(), old_mem_size/K, new_mem_size/K);
+ }
+}
+
+// Currently nothing to do.
+void TenuredGeneration::prepare_for_verify() {}
+
+void TenuredGeneration::object_iterate(ObjectClosure* blk) {
+ _the_space->object_iterate(blk);
+}
+
+void TenuredGeneration::space_iterate(SpaceClosure* blk,
+ bool usedOnly) {
+ blk->do_space(_the_space);
+}
+
+void TenuredGeneration::younger_refs_iterate(OopsInGenClosure* blk) {
+ blk->set_generation(this);
+ younger_refs_in_space_iterate(_the_space, blk);
+ blk->reset_generation();
+}
+
+void TenuredGeneration::save_marks() {
+ _the_space->set_saved_mark();
+}
+
+
+void TenuredGeneration::reset_saved_marks() {
+ _the_space->reset_saved_mark();
+}
+
+
+bool TenuredGeneration::no_allocs_since_save_marks() {
+ return _the_space->saved_mark_at_top();
+}
+
+#define TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \
+ \
+void TenuredGeneration:: \
+oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \
+ blk->set_generation(this); \
+ _the_space->oop_since_save_marks_iterate##nv_suffix(blk); \
+ blk->reset_generation(); \
+ save_marks(); \
+}
+
+ALL_SINCE_SAVE_MARKS_CLOSURES(TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN)
+
+#undef TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN
+
+
+void TenuredGeneration::gc_epilogue(bool full) {
+ _last_gc = WaterMark(the_space(), the_space()->top());
+
+ // update the generation and space performance counters
+ update_counters();
+ if (ZapUnusedHeapArea) {
+ the_space()->check_mangled_unused_area_complete();
+ }
+}
+
+void TenuredGeneration::record_spaces_top() {
+ assert(ZapUnusedHeapArea, "Not mangling unused space");
+ the_space()->set_top_for_allocations();
+}
+
+void TenuredGeneration::verify() {
+ the_space()->verify();
+}
+
+void TenuredGeneration::print_on(outputStream* st) const {
+ Generation::print_on(st);
+ st->print(" the");
+ the_space()->print_on(st);
+}
--- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -31,38 +31,47 @@
#include "memory/generation.hpp"
#include "utilities/macros.hpp"
-// TenuredGeneration models the heap containing old (promoted/tenured) objects.
-
-class ParGCAllocBufferWithBOT;
-
-class TenuredGeneration: public OneContigSpaceCardGeneration {
- friend class VMStructs;
- protected:
+// TenuredGeneration models the heap containing old (promoted/tenured) objects
+// contained in a single contiguous space.
+//
+// Garbage collection is performed using mark-compact.
-#if INCLUDE_ALL_GCS
- // To support parallel promotion: an array of parallel allocation
- // buffers, one per thread, initially NULL.
- ParGCAllocBufferWithBOT** _alloc_buffers;
-#endif // INCLUDE_ALL_GCS
+class TenuredGeneration: public CardGeneration {
+ friend class VMStructs;
+ // Abstractly, this is a subtype that gets access to protected fields.
+ friend class VM_PopulateDumpSharedSpace;
- // Retire all alloc buffers before a full GC, so that they will be
- // re-allocated at the start of the next young GC.
- void retire_alloc_buffers_before_full_gc();
+ protected:
+ ContiguousSpace* _the_space; // actual space holding objects
+ WaterMark _last_gc; // watermark between objects allocated before
+ // and after last GC.
GenerationCounters* _gen_counters;
CSpaceCounters* _space_counters;
+ // Grow generation with specified size (returns false if unable to grow)
+ virtual bool grow_by(size_t bytes);
+ // Grow generation to reserved size.
+ virtual bool grow_to_reserved();
+ // Shrink generation with specified size (returns false if unable to shrink)
+ void shrink_by(size_t bytes);
+
+ // Allocation failure
+ virtual bool expand(size_t bytes, size_t expand_bytes);
+ void shrink(size_t bytes);
+
+ // Accessing spaces
+ ContiguousSpace* the_space() const { return _the_space; }
+
public:
- TenuredGeneration(ReservedSpace rs, size_t initial_byte_size, int level,
- GenRemSet* remset);
+ TenuredGeneration(ReservedSpace rs, size_t initial_byte_size,
+ int level, GenRemSet* remset);
Generation::Name kind() { return Generation::MarkSweepCompact; }
// Printing
- const char* name() const;
+ const char* name() const { return "tenured generation"; }
const char* short_name() const { return "Tenured"; }
- bool must_be_youngest() const { return false; }
- bool must_be_oldest() const { return true; }
// Does a "full" (forced) collection invoked on this generation collect
// all younger generations as well? Note that this is a
@@ -72,37 +81,78 @@
return !ScavengeBeforeFullGC;
}
+ inline bool is_in(const void* p) const;
+
+ // Space enquiries
+ size_t capacity() const;
+ size_t used() const;
+ size_t free() const;
+
+ MemRegion used_region() const;
+
+ size_t unsafe_max_alloc_nogc() const;
+ size_t contiguous_available() const;
+
+ // Iteration
+ void object_iterate(ObjectClosure* blk);
+ void space_iterate(SpaceClosure* blk, bool usedOnly = false);
+
+ void younger_refs_iterate(OopsInGenClosure* blk);
+
+ inline CompactibleSpace* first_compaction_space() const;
+
+ virtual inline HeapWord* allocate(size_t word_size, bool is_tlab);
+ virtual inline HeapWord* par_allocate(size_t word_size, bool is_tlab);
+
+ // Accessing marks
+ inline WaterMark top_mark();
+ inline WaterMark bottom_mark();
+
+#define TenuredGen_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
+ void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
+ TenuredGen_SINCE_SAVE_MARKS_DECL(OopsInGenClosure,_v)
+ SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(TenuredGen_SINCE_SAVE_MARKS_DECL)
+
+ void save_marks();
+ void reset_saved_marks();
+ bool no_allocs_since_save_marks();
+
+ inline size_t block_size(const HeapWord* addr) const;
+
+ inline bool block_is_obj(const HeapWord* addr) const;
+
+ virtual void collect(bool full,
+ bool clear_all_soft_refs,
+ size_t size,
+ bool is_tlab);
+ HeapWord* expand_and_allocate(size_t size,
+ bool is_tlab,
+ bool parallel = false);
+
+ virtual void prepare_for_verify();
+
+
virtual void gc_prologue(bool full);
virtual void gc_epilogue(bool full);
bool should_collect(bool full,
size_t word_size,
bool is_tlab);
- virtual void collect(bool full,
- bool clear_all_soft_refs,
- size_t size,
- bool is_tlab);
virtual void compute_new_size();
-#if INCLUDE_ALL_GCS
- // Overrides.
- virtual oop par_promote(int thread_num,
- oop obj, markOop m, size_t word_sz);
- virtual void par_promote_alloc_undo(int thread_num,
- HeapWord* obj, size_t word_sz);
- virtual void par_promote_alloc_done(int thread_num);
-#endif // INCLUDE_ALL_GCS
-
// Performance Counter support
void update_counters();
+ virtual void record_spaces_top();
+
// Statistics
virtual void update_gc_stats(int level, bool full);
virtual bool promotion_attempt_is_safe(size_t max_promoted_in_bytes) const;
- void verify_alloc_buffers_clean();
+ virtual void verify();
+ virtual void print_on(outputStream* st) const;
};
#endif // SHARE_VM_MEMORY_TENUREDGENERATION_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.inline.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2000, 2010, 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_GENERATION_INLINE_HPP
+#define SHARE_VM_MEMORY_GENERATION_INLINE_HPP
+
+#include "memory/genCollectedHeap.hpp"
+#include "memory/space.hpp"
+#include "memory/tenuredGeneration.hpp"
+
+bool TenuredGeneration::is_in(const void* p) const {
+ return the_space()->is_in(p);
+}
+
+
+WaterMark TenuredGeneration::top_mark() {
+ return the_space()->top_mark();
+}
+
+CompactibleSpace*
+TenuredGeneration::first_compaction_space() const {
+ return the_space();
+}
+
+HeapWord* TenuredGeneration::allocate(size_t word_size,
+ bool is_tlab) {
+ assert(!is_tlab, "TenuredGeneration does not support TLAB allocation");
+ return the_space()->allocate(word_size);
+}
+
+HeapWord* TenuredGeneration::par_allocate(size_t word_size,
+ bool is_tlab) {
+ assert(!is_tlab, "TenuredGeneration does not support TLAB allocation");
+ return the_space()->par_allocate(word_size);
+}
+
+WaterMark TenuredGeneration::bottom_mark() {
+ return the_space()->bottom_mark();
+}
+
+size_t TenuredGeneration::block_size(const HeapWord* addr) const {
+ if (addr < the_space()->top()) return oop(addr)->size();
+ else {
+ assert(addr == the_space()->top(), "non-block head arg to block_size");
+ return the_space()->end() - the_space()->top();
+ }
+}
+
+bool TenuredGeneration::block_is_obj(const HeapWord* addr) const {
+ return addr < the_space()->top();
+}
+
+#endif // SHARE_VM_MEMORY_GENERATION_INLINE_HPP
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -76,7 +76,7 @@
#include "gc_implementation/shared/adaptiveSizePolicy.hpp"
#include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1CollectorPolicy_ext.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#endif // INCLUDE_ALL_GCS
#if INCLUDE_CDS
@@ -799,7 +799,7 @@
} else if (UseG1GC) {
#if INCLUDE_ALL_GCS
- G1CollectorPolicy* g1p = new G1CollectorPolicy();
+ G1CollectorPolicyExt* g1p = new G1CollectorPolicyExt();
g1p->initialize_all();
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
Universe::_collectedHeap = g1h;
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1365,7 +1365,7 @@
cl->do_field(&fd);
}
}
- FREE_C_HEAP_ARRAY(int, fields_sorted, mtClass);
+ FREE_C_HEAP_ARRAY(int, fields_sorted);
}
@@ -2473,7 +2473,7 @@
// deallocate the cached class file
if (_cached_class_file != NULL) {
- os::free(_cached_class_file, mtClass);
+ os::free(_cached_class_file);
_cached_class_file = NULL;
}
@@ -2482,7 +2482,7 @@
// unreference array name derived from this class name (arrays of an unloaded
// class can't be referenced anymore).
if (_array_name != NULL) _array_name->decrement_refcount();
- if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
+ if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension);
assert(_total_instanceKlass_count >= 1, "Sanity check");
Atomic::dec(&_total_instanceKlass_count);
--- a/hotspot/src/share/vm/oops/method.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -936,7 +936,7 @@
// so making them eagerly shouldn't be too expensive.
AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh);
if (adapter == NULL ) {
- THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "out of space in CodeCache for adapters");
+ THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
}
mh->set_adapter_entry(adapter);
@@ -1757,7 +1757,7 @@
JNIMethodBlockNode(int num_methods = min_block_size);
- ~JNIMethodBlockNode() { FREE_C_HEAP_ARRAY(Method*, _methods, mtInternal); }
+ ~JNIMethodBlockNode() { FREE_C_HEAP_ARRAY(Method*, _methods); }
void ensure_methods(int num_addl_methods) {
if (_top < _number_of_methods) {
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -441,12 +441,12 @@
s = (int)((size_t)round_to(size_in_bytes, MinObjAlignmentInBytes) /
HeapWordSize);
- // UseParNewGC, UseParallelGC and UseG1GC can change the length field
+ // ParNew (used by CMS), UseParallelGC and UseG1GC can change the length field
// of an "old copy" of an object array in the young gen so it indicates
// the grey portion of an already copied array. This will cause the first
// disjunct below to fail if the two comparands are computed across such
// a concurrent change.
- // UseParNewGC also runs with promotion labs (which look like int
+ // ParNew also runs with promotion labs (which look like int
// filler arrays) which are subject to changing their declared size
// when finally retiring a PLAB; this also can cause the first disjunct
// to fail for another worker thread that is concurrently walking the block
@@ -458,8 +458,8 @@
// technique, we will need to suitably modify the assertion.
assert((s == klass->oop_size(this)) ||
(Universe::heap()->is_gc_active() &&
- ((is_typeArray() && UseParNewGC) ||
- (is_objArray() && is_forwarded() && (UseParNewGC || UseParallelGC || UseG1GC)))),
+ ((is_typeArray() && UseConcMarkSweepGC) ||
+ (is_objArray() && is_forwarded() && (UseConcMarkSweepGC || UseParallelGC || UseG1GC)))),
"wrong array object size");
} else {
// Must be zero, so bite the bullet and take the virtual call.
--- a/hotspot/src/share/vm/opto/escape.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1115,6 +1115,9 @@
// Each 4 iterations calculate how much time it will take
// to complete graph construction.
time.stop();
+ // Poll for requests from shutdown mechanism to quiesce compiler
+ // because Connection graph construction may take long time.
+ CompileBroker::maybe_block();
double stop_time = time.seconds();
double time_per_iter = (stop_time - start_time) / (double)SAMPLE_SIZE;
double time_until_end = time_per_iter * (double)(java_objects_length - next);
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -2809,7 +2809,8 @@
*/
Node* GraphKit::maybe_cast_profiled_obj(Node* obj,
ciKlass* type,
- bool not_null) {
+ bool not_null,
+ SafePointNode* sfpt) {
// type == NULL if profiling tells us this object is always null
if (type != NULL) {
Deoptimization::DeoptReason class_reason = Deoptimization::Reason_speculate_class_check;
@@ -2831,7 +2832,13 @@
ciKlass* exact_kls = type;
Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0,
&exact_obj);
- {
+ if (sfpt != NULL) {
+ GraphKit kit(sfpt->jvms());
+ PreserveJVMState pjvms(&kit);
+ kit.set_control(slow_ctl);
+ kit.uncommon_trap(class_reason,
+ Deoptimization::Action_maybe_recompile);
+ } else {
PreserveJVMState pjvms(this);
set_control(slow_ctl);
uncommon_trap(class_reason,
--- a/hotspot/src/share/vm/opto/graphKit.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -418,7 +418,8 @@
// Cast obj to type and emit guard unless we had too many traps here already
Node* maybe_cast_profiled_obj(Node* obj,
ciKlass* type,
- bool not_null = false);
+ bool not_null = false,
+ SafePointNode* sfpt = NULL);
// Cast obj to not-null on this path
Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
--- a/hotspot/src/share/vm/opto/library_call.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -4697,10 +4697,6 @@
Node* dest_offset = argument(3); // type: int
Node* length = argument(4); // type: int
- // Check for allocation before we add nodes that would confuse
- // tightly_coupled_allocation()
- AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
-
// The following tests must be performed
// (1) src and dest are arrays.
// (2) src and dest arrays must have elements of the same BasicType
@@ -4717,6 +4713,36 @@
src = null_check(src, T_ARRAY);
dest = null_check(dest, T_ARRAY);
+ // Check for allocation before we add nodes that would confuse
+ // tightly_coupled_allocation()
+ AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
+
+ SafePointNode* sfpt = NULL;
+ if (alloc != NULL) {
+ // The JVM state for uncommon traps between the allocation and
+ // arraycopy is set to the state before the allocation: if the
+ // initialization is performed by the array copy, we don't want to
+ // go back to the interpreter with an unitialized array.
+ JVMState* old_jvms = alloc->jvms();
+ JVMState* jvms = old_jvms->clone_shallow(C);
+ uint size = alloc->req();
+ sfpt = new SafePointNode(size, jvms);
+ jvms->set_map(sfpt);
+ for (uint i = 0; i < size; i++) {
+ sfpt->init_req(i, alloc->in(i));
+ }
+ // re-push array length for deoptimization
+ sfpt->ins_req(jvms->stkoff() + jvms->sp(), alloc->in(AllocateNode::ALength));
+ jvms->set_sp(jvms->sp()+1);
+ jvms->set_monoff(jvms->monoff()+1);
+ jvms->set_scloff(jvms->scloff()+1);
+ jvms->set_endoff(jvms->endoff()+1);
+ jvms->set_should_reexecute(true);
+
+ sfpt->set_i_o(map()->i_o());
+ sfpt->set_memory(map()->memory());
+ }
+
bool notest = false;
const Type* src_type = _gvn.type(src);
@@ -4762,14 +4788,14 @@
if (could_have_src && could_have_dest) {
// This is going to pay off so emit the required guards
if (!has_src) {
- src = maybe_cast_profiled_obj(src, src_k);
+ src = maybe_cast_profiled_obj(src, src_k, true, sfpt);
src_type = _gvn.type(src);
top_src = src_type->isa_aryptr();
has_src = (top_src != NULL && top_src->klass() != NULL);
src_spec = true;
}
if (!has_dest) {
- dest = maybe_cast_profiled_obj(dest, dest_k);
+ dest = maybe_cast_profiled_obj(dest, dest_k, true);
dest_type = _gvn.type(dest);
top_dest = dest_type->isa_aryptr();
has_dest = (top_dest != NULL && top_dest->klass() != NULL);
@@ -4810,10 +4836,10 @@
if (could_have_src && could_have_dest) {
// If we can have both exact types, emit the missing guards
if (could_have_src && !src_spec) {
- src = maybe_cast_profiled_obj(src, src_k);
+ src = maybe_cast_profiled_obj(src, src_k, true, sfpt);
}
if (could_have_dest && !dest_spec) {
- dest = maybe_cast_profiled_obj(dest, dest_k);
+ dest = maybe_cast_profiled_obj(dest, dest_k, true);
}
}
}
@@ -4855,13 +4881,28 @@
Node* not_subtype_ctrl = gen_subtype_check(src_klass, dest_klass);
if (not_subtype_ctrl != top()) {
- PreserveJVMState pjvms(this);
- set_control(not_subtype_ctrl);
- uncommon_trap(Deoptimization::Reason_intrinsic,
- Deoptimization::Action_make_not_entrant);
- assert(stopped(), "Should be stopped");
+ if (sfpt != NULL) {
+ GraphKit kit(sfpt->jvms());
+ PreserveJVMState pjvms(&kit);
+ kit.set_control(not_subtype_ctrl);
+ kit.uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_make_not_entrant);
+ assert(kit.stopped(), "Should be stopped");
+ } else {
+ PreserveJVMState pjvms(this);
+ set_control(not_subtype_ctrl);
+ uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_make_not_entrant);
+ assert(stopped(), "Should be stopped");
+ }
}
- {
+ if (sfpt != NULL) {
+ GraphKit kit(sfpt->jvms());
+ kit.set_control(_gvn.transform(slow_region));
+ kit.uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_make_not_entrant);
+ assert(kit.stopped(), "Should be stopped");
+ } else {
PreserveJVMState pjvms(this);
set_control(_gvn.transform(slow_region));
uncommon_trap(Deoptimization::Reason_intrinsic,
--- a/hotspot/src/share/vm/opto/phaseX.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1431,7 +1431,7 @@
Node* castii = in1->raw_out(i);
if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) {
Node* ifnode = castii->in(0)->in(0);
- if (ifnode->in(1) != NULL && ifnode->in(1)->in(1) == use) {
+ if (ifnode->in(1) != NULL && ifnode->in(1)->is_Bool() && ifnode->in(1)->in(1) == use) {
// Reprocess a CastII node that may depend on an
// opaque node value when the opaque node is
// removed. In case it carries a dependency we can do
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -127,7 +127,6 @@
# include "memory/genOopClosures.hpp"
# include "memory/genRemSet.hpp"
# include "memory/generation.hpp"
-# include "memory/generation.inline.hpp"
# include "memory/heap.hpp"
# include "memory/iterator.hpp"
# include "memory/memRegion.hpp"
--- a/hotspot/src/share/vm/prims/jniCheck.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1554,7 +1554,7 @@
}
// 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);
+ FreeHeap((char*)result);
}
functionExit(thr);
return new_result;
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -68,11 +68,11 @@
~JvmtiConstantPoolReconstituter() {
if (_symmap != NULL) {
- os::free(_symmap, mtClass);
+ os::free(_symmap);
_symmap = NULL;
}
if (_classmap != NULL) {
- os::free(_classmap, mtClass);
+ os::free(_classmap);
_classmap = NULL;
}
}
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -192,7 +192,7 @@
jvmtiError deallocate(unsigned char* mem) {
if (mem != NULL) {
- os::free(mem, mtInternal);
+ os::free(mem);
}
return JVMTI_ERROR_NONE;
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -727,7 +727,7 @@
JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
}
~JvmtiCompiledMethodLoadEventMark() {
- FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map, mtInternal);
+ FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
}
jint code_size() { return _code_size; }
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -88,7 +88,7 @@
void GrowableCache::recache() {
int len = _elements->length();
- FREE_C_HEAP_ARRAY(address, _cache, mtInternal);
+ FREE_C_HEAP_ARRAY(address, _cache);
_cache = NEW_C_HEAP_ARRAY(address,len+1, mtInternal);
for (int i=0; i<len; i++) {
@@ -132,7 +132,7 @@
GrowableCache::~GrowableCache() {
clear();
delete _elements;
- FREE_C_HEAP_ARRAY(address, _cache, mtInternal);
+ FREE_C_HEAP_ARRAY(address, _cache);
}
void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {
--- a/hotspot/src/share/vm/prims/unsafe.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -262,10 +262,33 @@
UNSAFE_END
#ifndef SUPPORTS_NATIVE_CX8
-// Keep old code for platforms which may not have atomic jlong (8 bytes) instructions
-// Volatile long versions must use locks if !VM_Version::supports_cx8().
-// support_cx8 is a surrogate for 'supports atomic long memory ops'.
+// VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'.
+//
+// On platforms which do not support atomic compare-and-swap of jlong (8 byte)
+// values we have to use a lock-based scheme to enforce atomicity. This has to be
+// applied to all Unsafe operations that set the value of a jlong field. Even so
+// the compareAndSwapLong operation will not be atomic with respect to direct stores
+// to the field from Java code. It is important therefore that any Java code that
+// utilizes these Unsafe jlong operations does not perform direct stores. To permit
+// direct loads of the field from Java code we must also use Atomic::store within the
+// locked regions. And for good measure, in case there are direct stores, we also
+// employ Atomic::load within those regions. Note that the field in question must be
+// volatile and so must have atomic load/store accesses applied at the Java level.
+//
+// The locking scheme could utilize a range of strategies for controlling the locking
+// granularity: from a lock per-field through to a single global lock. The latter is
+// the simplest and is used for the current implementation. Note that the Java object
+// that contains the field, can not, in general, be used for locking. To do so can lead
+// to deadlocks as we may introduce locking into what appears to the Java code to be a
+// lock-free path.
+//
+// As all the locked-regions are very short and themselves non-blocking we can treat
+// them as leaf routines and elide safepoint checks (ie we don't perform any thread
+// state transitions even when blocking for the lock). Note that if we do choose to
+// add safepoint checks and thread state transitions, we must ensure that we calculate
+// the address of the field _after_ we have acquired the lock, else the object may have
+// been moved by the GC
UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
UnsafeWrapper("Unsafe_GetLongVolatile");
@@ -277,8 +300,8 @@
else {
Handle p (THREAD, JNIHandles::resolve(obj));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
- ObjectLocker ol(p, THREAD);
- jlong value = *addr;
+ MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+ jlong value = Atomic::load(addr);
return value;
}
}
@@ -293,8 +316,8 @@
else {
Handle p (THREAD, JNIHandles::resolve(obj));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
- ObjectLocker ol(p, THREAD);
- *addr = x;
+ MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+ Atomic::store(x, addr);
}
}
UNSAFE_END
@@ -403,8 +426,8 @@
else {
Handle p (THREAD, JNIHandles::resolve(obj));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
- ObjectLocker ol(p, THREAD);
- *addr = x;
+ MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+ Atomic::store(x, addr);
}
}
#endif
@@ -875,10 +898,10 @@
result = JVM_DefineClass(env, utfName, loader, body, length, pd);
if (utfName && utfName != buf)
- FREE_C_HEAP_ARRAY(char, utfName, mtInternal);
+ FREE_C_HEAP_ARRAY(char, utfName);
free_body:
- FREE_C_HEAP_ARRAY(jbyte, body, mtInternal);
+ FREE_C_HEAP_ARRAY(jbyte, body);
return result;
}
}
@@ -1063,7 +1086,7 @@
// try/finally clause:
if (temp_alloc != NULL) {
- FREE_C_HEAP_ARRAY(HeapWord, temp_alloc, mtInternal);
+ FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
}
// The anonymous class loader data has been artificially been kept alive to
@@ -1152,14 +1175,19 @@
UnsafeWrapper("Unsafe_CompareAndSwapLong");
Handle p (THREAD, JNIHandles::resolve(obj));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
+#ifdef SUPPORTS_NATIVE_CX8
+ return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
+#else
if (VM_Version::supports_cx8())
return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
else {
jboolean success = false;
- ObjectLocker ol(p, THREAD);
- if (*addr == e) { *addr = x; success = true; }
+ MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+ jlong val = Atomic::load(addr);
+ if (val == e) { Atomic::store(x, addr); success = true; }
return success;
}
+#endif
UNSAFE_END
UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
--- a/hotspot/src/share/vm/prims/wbtestmethods/parserTests.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -70,38 +70,63 @@
const char* desc = WhiteBox::lookup_jstring("desc", argument);
const char* default_value = WhiteBox::lookup_jstring("defaultValue", argument);
bool mandatory = WhiteBox::lookup_bool("mandatory", argument);
+ bool isarg = WhiteBox::lookup_bool("argument", argument);
const char* type = lookup_diagnosticArgumentEnum("type", argument);
if (strcmp(type, "STRING") == 0) {
DCmdArgument<char*>* argument = new DCmdArgument<char*>(
name, desc,
"STRING", mandatory, default_value);
- parser->add_dcmd_option(argument);
+ if (isarg) {
+ parser->add_dcmd_argument(argument);
+ } else {
+ parser->add_dcmd_option(argument);
+ }
} else if (strcmp(type, "NANOTIME") == 0) {
DCmdArgument<NanoTimeArgument>* argument = new DCmdArgument<NanoTimeArgument>(
name, desc,
"NANOTIME", mandatory, default_value);
- parser->add_dcmd_option(argument);
+ if (isarg) {
+ parser->add_dcmd_argument(argument);
+ } else {
+ parser->add_dcmd_option(argument);
+ }
} else if (strcmp(type, "JLONG") == 0) {
DCmdArgument<jlong>* argument = new DCmdArgument<jlong>(
name, desc,
"JLONG", mandatory, default_value);
- parser->add_dcmd_option(argument);
+ if (isarg) {
+ parser->add_dcmd_argument(argument);
+ } else {
+ parser->add_dcmd_option(argument);
+ }
} else if (strcmp(type, "BOOLEAN") == 0) {
DCmdArgument<bool>* argument = new DCmdArgument<bool>(
name, desc,
"BOOLEAN", mandatory, default_value);
- parser->add_dcmd_option(argument);
+ if (isarg) {
+ parser->add_dcmd_argument(argument);
+ } else {
+ parser->add_dcmd_option(argument);
+ }
} else if (strcmp(type, "MEMORYSIZE") == 0) {
DCmdArgument<MemorySizeArgument>* argument = new DCmdArgument<MemorySizeArgument>(
name, desc,
"MEMORY SIZE", mandatory, default_value);
- parser->add_dcmd_option(argument);
+ if (isarg) {
+ parser->add_dcmd_argument(argument);
+ } else {
+ parser->add_dcmd_option(argument);
+ }
} else if (strcmp(type, "STRINGARRAY") == 0) {
DCmdArgument<StringArrayArgument*>* argument = new DCmdArgument<StringArrayArgument*>(
name, desc,
"STRING SET", mandatory);
- parser->add_dcmd_option(argument);
+ if (isarg) {
+ parser->add_dcmd_argument(argument);
+ } else {
+ parser->add_dcmd_option(argument);
+ }
}
}
@@ -111,11 +136,12 @@
* { name, value, name, value ... }
* This can then be checked from java.
*/
-WB_ENTRY(jobjectArray, WB_ParseCommandLine(JNIEnv* env, jobject o, jstring j_cmdline, jobjectArray arguments))
+WB_ENTRY(jobjectArray, WB_ParseCommandLine(JNIEnv* env, jobject o, jstring j_cmdline, jchar j_delim, jobjectArray arguments))
ResourceMark rm;
DCmdParser parser;
const char* c_cmdline = java_lang_String::as_utf8_string(JNIHandles::resolve(j_cmdline));
+ const char c_delim = j_delim & 0xff;
objArrayOop argumentArray = objArrayOop(JNIHandles::resolve_non_null(arguments));
objArrayHandle argumentArray_ah(THREAD, argumentArray);
@@ -127,20 +153,29 @@
}
CmdLine cmdline(c_cmdline, strlen(c_cmdline), true);
- parser.parse(&cmdline,',',CHECK_NULL);
+ parser.parse(&cmdline,c_delim,CHECK_NULL);
Klass* k = SystemDictionary::Object_klass();
objArrayOop returnvalue_array = oopFactory::new_objArray(k, parser.num_arguments() * 2, CHECK_NULL);
objArrayHandle returnvalue_array_ah(THREAD, returnvalue_array);
GrowableArray<const char *>*parsedArgNames = parser.argument_name_array();
+ GenDCmdArgument* arglist = parser.arguments_list();
for (int i = 0; i < parser.num_arguments(); i++) {
oop parsedName = java_lang_String::create_oop_from_str(parsedArgNames->at(i), CHECK_NULL);
returnvalue_array_ah->obj_at_put(i*2, parsedName);
GenDCmdArgument* arg = parser.lookup_dcmd_option(parsedArgNames->at(i), strlen(parsedArgNames->at(i)));
+ if (!arg) {
+ arg = arglist;
+ arglist = arglist->next();
+ }
char buf[VALUE_MAXLEN];
- arg->value_as_str(buf, sizeof(buf));
+ if (arg) {
+ arg->value_as_str(buf, sizeof(buf));
+ } else {
+ sprintf(buf, "<null>");
+ }
oop parsedValue = java_lang_String::create_oop_from_str(buf, CHECK_NULL);
returnvalue_array_ah->obj_at_put(i*2+1, parsedValue);
}
--- a/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -27,6 +27,6 @@
#include "prims/jni.h"
#include "prims/whitebox.hpp"
-WB_METHOD_DECLARE(jobjectArray) WB_ParseCommandLine(JNIEnv* env, jobject o, jstring args, jobjectArray arguments);
+WB_METHOD_DECLARE(jobjectArray) WB_ParseCommandLine(JNIEnv* env, jobject o, jstring args, jchar delim, jobjectArray arguments);
#endif //SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
--- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -41,6 +41,7 @@
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
#include "runtime/sweeper.hpp"
+#include "runtime/javaCalls.hpp"
#include "runtime/thread.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/array.hpp"
@@ -50,6 +51,7 @@
#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
#include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/concurrentMarkThread.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#endif // INCLUDE_ALL_GCS
@@ -75,6 +77,9 @@
return heapOopSize;
WB_END
+WB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o))
+ return os::vm_page_size();
+WB_END
class WBIsKlassAliveClosure : public KlassClosure {
Symbol* _name;
@@ -290,8 +295,16 @@
WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
G1CollectedHeap* g1 = G1CollectedHeap::heap();
- ConcurrentMark* cm = g1->concurrent_mark();
- return cm->concurrent_marking_in_progress();
+ return g1->concurrent_mark()->cmThread()->during_cycle();
+WB_END
+
+WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o))
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ if (!g1h->concurrent_mark()->cmThread()->during_cycle()) {
+ g1h->collect(GCCause::_wb_conc_mark);
+ return true;
+ }
+ return false;
WB_END
WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
@@ -318,7 +331,7 @@
// Free the memory allocated by NMTAllocTest
WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem))
- os::free((void*)(uintptr_t)mem, mtTest);
+ os::free((void*)(uintptr_t)mem);
WB_END
WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
@@ -744,7 +757,7 @@
env->ReleaseStringUTFChars(value, ccstrValue);
}
if (needFree) {
- FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal);
+ FREE_C_HEAP_ARRAY(char, ccstrResult);
}
WB_END
@@ -759,8 +772,8 @@
mo.notify_all();
WB_END
-void WhiteBox::force_sweep() {
- guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+void WhiteBox::sweeper_thread_entry(JavaThread* thread, TRAPS) {
+ guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
NMethodSweeper::_should_sweep = true;
@@ -768,8 +781,37 @@
NMethodSweeper::possibly_sweep();
}
-WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
- WhiteBox::force_sweep();
+JavaThread* WhiteBox::create_sweeper_thread(TRAPS) {
+ // create sweeper thread w/ custom entry -- one iteration instead of loop
+ CodeCacheSweeperThread* sweeper_thread = new CodeCacheSweeperThread();
+ sweeper_thread->set_entry_point(&WhiteBox::sweeper_thread_entry);
+
+ // create j.l.Thread object and associate it w/ sweeper thread
+ {
+ // inherit deamon property from current thread
+ bool is_daemon = java_lang_Thread::is_daemon(JavaThread::current()->threadObj());
+
+ HandleMark hm(THREAD);
+ Handle thread_group(THREAD, Universe::system_thread_group());
+ const char* name = "WB Sweeper thread";
+ sweeper_thread->allocate_threadObj(thread_group, name, is_daemon, THREAD);
+ }
+
+ {
+ MutexLocker mu(Threads_lock, THREAD);
+ Threads::add(sweeper_thread);
+ }
+ return sweeper_thread;
+}
+
+WB_ENTRY(jobject, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
+ JavaThread* sweeper_thread = WhiteBox::create_sweeper_thread(Thread::current());
+ if (sweeper_thread == NULL) {
+ return NULL;
+ }
+ jobject result = JNIHandles::make_local(env, sweeper_thread->threadObj());
+ Thread::start(sweeper_thread);
+ return result;
WB_END
WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
@@ -819,12 +861,12 @@
WB_END
int WhiteBox::get_blob_type(const CodeBlob* code) {
- guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+ guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
return CodeCache::get_code_heap(code)->code_blob_type();
}
CodeHeap* WhiteBox::get_code_heap(int blob_type) {
- guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+ guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
return CodeCache::get_code_heap(blob_type);
}
@@ -900,7 +942,7 @@
WB_END
CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
- guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+ guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
BufferBlob* blob;
int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
if (full_size < size) {
@@ -909,10 +951,10 @@
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
+ ::new (blob) BufferBlob("WB::DummyBlob", full_size);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();
- ::new (blob) BufferBlob("WB::DummyBlob", full_size);
return blob;
}
@@ -1124,9 +1166,10 @@
{CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize },
{CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen },
{CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
+ {CC"getVMPageSize", CC"()I", (void*)&WB_GetVMPageSize },
{CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive },
{CC"parseCommandLine",
- CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
+ CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine
},
{CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V",
@@ -1144,6 +1187,7 @@
{CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
{CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
{CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
+ {CC"g1StartConcMarkCycle", CC"()Z", (void*)&WB_G1StartMarkCycle },
#endif // INCLUDE_ALL_GCS
#if INCLUDE_NMT
{CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc },
@@ -1221,7 +1265,7 @@
{CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures },
{CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
(void*)&WB_GetNMethod },
- {CC"forceNMethodSweep", CC"()V", (void*)&WB_ForceNMethodSweep },
+ {CC"forceNMethodSweep0", CC"()Ljava/lang/Thread;", (void*)&WB_ForceNMethodSweep },
{CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob },
{CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob },
{CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
--- a/hotspot/src/share/vm/prims/whitebox.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/prims/whitebox.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -27,6 +27,7 @@
#include "prims/jni.h"
+#include "utilities/exceptions.hpp"
#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
#include "oops/symbol.hpp"
@@ -56,6 +57,7 @@
class CodeBlob;
class CodeHeap;
+class JavaThread;
class WhiteBox : public AllStatic {
private:
@@ -68,7 +70,8 @@
Symbol* signature_symbol);
static const char* lookup_jstring(const char* field_name, oop object);
static bool lookup_bool(const char* field_name, oop object);
- static void force_sweep();
+ static void sweeper_thread_entry(JavaThread* thread, TRAPS);
+ static JavaThread* create_sweeper_thread(TRAPS);
static int get_blob_type(const CodeBlob* code);
static CodeHeap* get_code_heap(int blob_type);
static CodeBlob* allocate_code_blob(int blob_type, int size);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -417,7 +417,7 @@
inline void SysClassPath::reset_item_at(int index) {
assert(index < _scp_nitems && index != _scp_base, "just checking");
if (_items[index] != NULL) {
- FREE_C_HEAP_ARRAY(char, _items[index], mtInternal);
+ FREE_C_HEAP_ARRAY(char, _items[index]);
_items[index] = NULL;
}
}
@@ -490,7 +490,7 @@
cp_tmp += str_len;
*cp_tmp = separator;
memcpy(++cp_tmp, path, old_len + 1); // copy the trailing null
- FREE_C_HEAP_ARRAY(char, path, mtInternal);
+ FREE_C_HEAP_ARRAY(char, path);
} else {
cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtInternal);
char* cp_tmp = cp + old_len;
@@ -525,10 +525,10 @@
char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtInternal);
sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
path = add_to_path(path, jarpath, false);
- FREE_C_HEAP_ARRAY(char, jarpath, mtInternal);
+ FREE_C_HEAP_ARRAY(char, jarpath);
}
}
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
os::closedir(dir);
return path;
}
@@ -663,7 +663,7 @@
static bool set_string_flag(char* name, const char* value, Flag::Flags origin) {
if (!CommandLineFlags::ccstrAtPut(name, &value, origin)) return false;
// Contract: CommandLineFlags always returns a pointer that needs freeing.
- FREE_C_HEAP_ARRAY(char, value, mtInternal);
+ FREE_C_HEAP_ARRAY(char, value);
return true;
}
@@ -687,10 +687,10 @@
}
(void) CommandLineFlags::ccstrAtPut(name, &value, origin);
// CommandLineFlags always returns a pointer that needs freeing.
- FREE_C_HEAP_ARRAY(char, value, mtInternal);
+ FREE_C_HEAP_ARRAY(char, value);
if (free_this_too != NULL) {
// CommandLineFlags made its own copy, so I must delete my own temp. buffer.
- FREE_C_HEAP_ARRAY(char, free_this_too, mtInternal);
+ FREE_C_HEAP_ARRAY(char, free_this_too);
}
return true;
}
@@ -1222,10 +1222,8 @@
void Arguments::set_parnew_gc_flags() {
assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC && !UseG1GC,
"control point invariant");
- assert(UseParNewGC, "Error");
-
- // Turn off AdaptiveSizePolicy for parnew until it is complete.
- disable_adaptive_size_policy("UseParNewGC");
+ assert(UseConcMarkSweepGC, "CMS is expected to be on here");
+ assert(UseParNewGC, "ParNew should always be used with CMS");
if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads());
@@ -1266,21 +1264,12 @@
void Arguments::set_cms_and_parnew_gc_flags() {
assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC, "Error");
assert(UseConcMarkSweepGC, "CMS is expected to be on here");
-
- // If we are using CMS, we prefer to UseParNewGC,
- // unless explicitly forbidden.
- if (FLAG_IS_DEFAULT(UseParNewGC)) {
- FLAG_SET_ERGO(bool, UseParNewGC, true);
- }
+ assert(UseParNewGC, "ParNew should always be used with CMS");
// Turn off AdaptiveSizePolicy by default for cms until it is complete.
disable_adaptive_size_policy("UseConcMarkSweepGC");
- // In either case, adjust ParallelGCThreads and/or UseParNewGC
- // as needed.
- if (UseParNewGC) {
- set_parnew_gc_flags();
- }
+ set_parnew_gc_flags();
size_t max_heap = align_size_down(MaxHeapSize,
CardTableRS::ct_max_alignment_constraint());
@@ -1750,14 +1739,11 @@
// Set per-collector flags
if (UseParallelGC || UseParallelOldGC) {
set_parallel_gc_flags();
- } else if (UseConcMarkSweepGC) { // Should be done before ParNew check below
+ } else if (UseConcMarkSweepGC) {
set_cms_and_parnew_gc_flags();
- } else if (UseParNewGC) { // Skipped if CMS is set above
- set_parnew_gc_flags();
} else if (UseG1GC) {
set_g1_gc_flags();
}
- check_deprecated_gcs();
check_deprecated_gc_flags();
if (AssumeMP && !UseSerialGC) {
if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
@@ -2118,17 +2104,11 @@
// Check consistency of GC selection
bool Arguments::check_gc_consistency_user() {
check_gclog_consistency();
- bool status = true;
// Ensure that the user has not selected conflicting sets
- // of collectors. [Note: this check is merely a user convenience;
- // collectors over-ride each other so that only a non-conflicting
- // set is selected; however what the user gets is not what they
- // may have expected from the combination they asked for. It's
- // better to reduce user confusion by not allowing them to
- // select conflicting combinations.
+ // of collectors.
uint i = 0;
if (UseSerialGC) i++;
- if (UseConcMarkSweepGC || UseParNewGC) i++;
+ if (UseConcMarkSweepGC) i++;
if (UseParallelGC || UseParallelOldGC) i++;
if (UseG1GC) i++;
if (i > 1) {
@@ -2136,26 +2116,30 @@
"Conflicting collector combinations in option list; "
"please refer to the release notes for the combinations "
"allowed\n");
- status = false;
+ return false;
}
- return status;
-}
-
-void Arguments::check_deprecated_gcs() {
+
if (UseConcMarkSweepGC && !UseParNewGC) {
- warning("Using the DefNew young collector with the CMS collector is deprecated "
- "and will likely be removed in a future release");
+ jio_fprintf(defaultStream::error_stream(),
+ "It is not possible to combine the DefNew young collector with the CMS collector.\n");
+ return false;
}
if (UseParNewGC && !UseConcMarkSweepGC) {
// !UseConcMarkSweepGC means that we are using serial old gc. Unfortunately we don't
// set up UseSerialGC properly, so that can't be used in the check here.
- warning("Using the ParNew young collector with the Serial old collector is deprecated "
- "and will likely be removed in a future release");
+ jio_fprintf(defaultStream::error_stream(),
+ "It is not possible to combine the ParNew young collector with the Serial old collector.\n");
+ return false;
}
+
+ return true;
}
void Arguments::check_deprecated_gc_flags() {
+ if (FLAG_IS_CMDLINE(UseParNewGC)) {
+ warning("The UseParNewGC flag is deprecated and will likely be removed in a future release");
+ }
if (FLAG_IS_CMDLINE(MaxGCMinorPauseMillis)) {
warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
"and will likely be removed in future release");
@@ -2262,7 +2246,7 @@
FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
}
- status = status && ArgumentsExt::check_gc_consistency_user();
+ status = status && check_gc_consistency_user();
status = status && check_stack_pages();
status = status && verify_percentage(CMSIncrementalSafetyFactor,
@@ -3473,7 +3457,7 @@
const char* ext = name + strlen(name) - 4;
hasJarFile = ext > name && (os::file_name_strcmp(ext, ".jar") == 0);
}
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
os::closedir(dir);
return hasJarFile ;
}
@@ -3500,7 +3484,7 @@
jio_fprintf(defaultStream::output_stream(),
"Non-empty directory: %s\n", dirpath);
}
- FREE_C_HEAP_ARRAY(char, dirpath, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirpath);
path = tmp_end + 1;
}
}
@@ -3610,7 +3594,12 @@
}
}
- if (!ArgumentsExt::check_vm_args_consistency()) {
+ if (UseConcMarkSweepGC && FLAG_IS_DEFAULT(UseParNewGC) && !UseParNewGC) {
+ // CMS can only be used with ParNew
+ FLAG_SET_ERGO(bool, UseParNewGC, true);
+ }
+
+ if (!check_vm_args_consistency()) {
return JNI_ERR;
}
@@ -4008,7 +3997,7 @@
// Set heap size based on available physical memory
set_heap_size();
- set_gc_specific_flags();
+ ArgumentsExt::set_gc_specific_flags();
// Initialize Metaspace flags and alignments
Metaspace::ergo_initialize();
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -348,7 +348,6 @@
static void select_gc();
static void set_ergonomics_flags();
static void set_shared_spaces_flags();
- static void set_gc_specific_flags();
// limits the given memory size by the maximum amount of memory this process is
// currently allowed to allocate or reserve.
static julong limit_by_allocatable_memory(julong size);
@@ -460,6 +459,7 @@
// Adjusts the arguments after the OS have adjusted the arguments
static jint adjust_after_os();
+ static void set_gc_specific_flags();
static inline bool gc_selected(); // whether a gc has been selected
static void select_gc_ergonomically();
@@ -474,7 +474,6 @@
// Check for consistency in the selection of the garbage collector.
static bool check_gc_consistency_user(); // Check user-selected gc
static inline bool check_gc_consistency_ergo(); // Check ergonomic-selected gc
- static void check_deprecated_gcs();
static void check_deprecated_gc_flags();
// Check consistency or otherwise of VM argument settings
static bool check_vm_args_consistency();
@@ -616,8 +615,7 @@
};
bool Arguments::gc_selected() {
- return UseConcMarkSweepGC || UseG1GC || UseParallelGC || UseParallelOldGC ||
- UseParNewGC || UseSerialGC;
+ return UseConcMarkSweepGC || UseG1GC || UseParallelGC || UseParallelOldGC || UseSerialGC;
}
bool Arguments::check_gc_consistency_ergo() {
--- a/hotspot/src/share/vm/runtime/arguments_ext.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/arguments_ext.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -31,9 +31,8 @@
class ArgumentsExt: AllStatic {
public:
static inline void select_gc_ergonomically();
- static inline bool check_gc_consistency_user();
+ static inline void set_gc_specific_flags();
static inline bool check_gc_consistency_ergo();
- static inline bool check_vm_args_consistency();
// The argument processing extension. Returns true if there is
// no additional parsing needed in Arguments::parse() for the option.
// Otherwise returns false.
@@ -44,16 +43,12 @@
Arguments::select_gc_ergonomically();
}
-bool ArgumentsExt::check_gc_consistency_user() {
- return Arguments::check_gc_consistency_user();
+void ArgumentsExt::set_gc_specific_flags() {
+ Arguments::set_gc_specific_flags();
}
bool ArgumentsExt::check_gc_consistency_ergo() {
return Arguments::check_gc_consistency_ergo();
}
-bool ArgumentsExt::check_vm_args_consistency() {
- return Arguments::check_vm_args_consistency();
-}
-
#endif // SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -82,9 +82,9 @@
Deoptimization::UnrollBlock::~UnrollBlock() {
- FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes, mtCompiler);
- FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs, mtCompiler);
- FREE_C_HEAP_ARRAY(intptr_t, _register_block, mtCompiler);
+ FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes);
+ FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs);
+ FREE_C_HEAP_ARRAY(intptr_t, _register_block);
}
--- a/hotspot/src/share/vm/runtime/dtraceJSDT.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/dtraceJSDT.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -66,7 +66,7 @@
_nmethods[i]->make_not_entrant();
_nmethods[i]->method()->clear_code();
}
- FREE_C_HEAP_ARRAY(nmethod*, _nmethods, mtInternal);
+ FREE_C_HEAP_ARRAY(nmethod*, _nmethods);
_nmethods = NULL;
_count = 0;
}
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -936,7 +936,7 @@
FlatProfiler::interval_reset();
}
- FREE_C_HEAP_ARRAY(JavaThread *, threadsList, mtInternal);
+ FREE_C_HEAP_ARRAY(JavaThread *, threadsList);
} else {
// Couldn't get the threads lock, just record that rather than blocking
FlatProfiler::threads_lock_ticks += 1;
--- a/hotspot/src/share/vm/runtime/globals.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/globals.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -840,7 +840,7 @@
faddr->set_ccstr(new_value);
if (!faddr->is_default() && old_value != NULL) {
// Prior value is heap allocated so free it.
- FREE_C_HEAP_ARRAY(char, old_value, mtInternal);
+ FREE_C_HEAP_ARRAY(char, old_value);
}
faddr->set_origin(origin);
}
@@ -874,7 +874,7 @@
}
}
out->cr();
- FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
+ FREE_C_HEAP_ARRAY(Flag*, array);
}
#ifndef PRODUCT
@@ -908,5 +908,5 @@
array[i]->print_on(out, withComments);
}
}
- FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
+ FREE_C_HEAP_ARRAY(Flag*, array);
}
--- a/hotspot/src/share/vm/runtime/handles.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/handles.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -179,11 +179,11 @@
}
void HandleMark::operator delete(void* p) {
- FreeHeap(p, mtThread);
+ FreeHeap(p);
}
void HandleMark::operator delete[](void* p) {
- FreeHeap(p, mtThread);
+ FreeHeap(p);
}
#ifdef ASSERT
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -136,6 +136,10 @@
Mutex* JfrThreadGroups_lock = NULL;
#endif
+#ifndef SUPPORTS_NATIVE_CX8
+Mutex* UnsafeJlong_lock = NULL;
+#endif
+
#define MAX_NUM_MUTEX 128
static Monitor * _mutex_array[MAX_NUM_MUTEX];
static int _num_mutex;
@@ -286,6 +290,9 @@
def(JfrStacktrace_lock , Mutex, special, true);
#endif
+#ifndef SUPPORTS_NATIVE_CX8
+ def(UnsafeJlong_lock , Mutex, special, false);
+#endif
}
GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -136,6 +136,10 @@
extern Mutex* JfrThreadGroups_lock; // protects JFR access to Thread Groups
#endif
+#ifndef SUPPORTS_NATIVE_CX8
+extern Mutex* UnsafeJlong_lock; // provides Unsafe atomic updates to jlongs on platforms that don't support cx8
+#endif
+
// A MutexLocker provides mutual exclusion with respect to a given mutex
// for the scope which contains the locker. The lock is an OS lock, not
// an object lock, and the two do not interoperate. Do not use Mutex-based
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -207,7 +207,7 @@
return operator new (size);
}
void operator delete(void* p) {
- FreeHeap(p, mtInternal);
+ FreeHeap(p);
}
void operator delete[] (void *p) {
operator delete(p);
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/os.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -473,7 +473,7 @@
break;
}
entryName = dll_lookup(handle, agent_function_name);
- FREE_C_HEAP_ARRAY(char, agent_function_name, mtThread);
+ FREE_C_HEAP_ARRAY(char, agent_function_name);
if (entryName != NULL) {
break;
}
@@ -689,7 +689,7 @@
}
-void os::free(void *memblock, MEMFLAGS memflags) {
+void os::free(void *memblock) {
NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
#ifdef ASSERT
if (memblock == NULL) return;
@@ -1211,7 +1211,7 @@
path_len = new_len;
}
- FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dbuf);
os::closedir(dir);
return path;
@@ -1240,13 +1240,13 @@
Arguments::set_sysclasspath(jimage);
return true;
}
- FREE_C_HEAP_ARRAY(char, jimage, mtInternal);
+ FREE_C_HEAP_ARRAY(char, jimage);
// images build if rt.jar exists
char* rt_jar = format_boot_path("%/lib/rt.jar", home, home_len, fileSep, pathSep);
if (rt_jar == NULL) return false;
bool has_rt_jar = (os::stat(rt_jar, &st) == 0);
- FREE_C_HEAP_ARRAY(char, rt_jar, mtInternal);
+ FREE_C_HEAP_ARRAY(char, rt_jar);
if (has_rt_jar) {
// Any modification to the JAR-file list, for the boot classpath must be
@@ -1330,7 +1330,7 @@
opath[i] = s;
p += len + 1;
}
- FREE_C_HEAP_ARRAY(char, inpath, mtInternal);
+ FREE_C_HEAP_ARRAY(char, inpath);
*n = count;
return opath;
}
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -664,7 +664,7 @@
static void* realloc (void *memblock, size_t size, MEMFLAGS flag, const NativeCallStack& stack);
static void* realloc (void *memblock, size_t size, MEMFLAGS flag);
- static void free (void *memblock, MEMFLAGS flags = mtNone);
+ static void free (void *memblock);
static bool check_heap(bool force = false); // verify C heap integrity
static char* strdup(const char *, MEMFLAGS flags = mtInternal); // Like strdup
// Like strdup, but exit VM when strdup() returns NULL
--- a/hotspot/src/share/vm/runtime/perfData.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/perfData.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -113,10 +113,10 @@
PerfData::~PerfData() {
if (_name != NULL) {
- FREE_C_HEAP_ARRAY(char, _name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, _name);
}
if (is_on_c_heap()) {
- FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep, mtInternal);
+ FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep);
}
}
--- a/hotspot/src/share/vm/runtime/perfMemory.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/perfMemory.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -250,7 +250,7 @@
dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN, mtInternal);
if(!Arguments::copy_expand_pid(PerfDataSaveFile, strlen(PerfDataSaveFile),
dest_file, JVM_MAXPATHLEN)) {
- FREE_C_HEAP_ARRAY(char, dest_file, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dest_file);
if (PrintMiscellaneous && Verbose) {
warning("Invalid performance data file path name specified, "\
"fall back to a default name");
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -2084,7 +2084,7 @@
~AdapterFingerPrint() {
if (_length > 0) {
- FREE_C_HEAP_ARRAY(int, _value._fingerprint, mtCode);
+ FREE_C_HEAP_ARRAY(int, _value._fingerprint);
}
}
@@ -2491,7 +2491,7 @@
void AdapterHandlerEntry::deallocate() {
delete _fingerprint;
#ifdef ASSERT
- if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode);
+ if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code);
#endif
}
@@ -2902,7 +2902,7 @@
JRT_END
JRT_LEAF(void, SharedRuntime::OSR_migration_end( intptr_t* buf) )
- FREE_C_HEAP_ARRAY(intptr_t, buf, mtCode);
+ FREE_C_HEAP_ARRAY(intptr_t, buf);
JRT_END
bool AdapterHandlerLibrary::contains(CodeBlob* b) {
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -142,9 +142,6 @@
long NMethodSweeper::_time_counter = 0; // Virtual time used to periodically invoke sweeper
long NMethodSweeper::_last_sweep = 0; // Value of _time_counter when the last sweep happened
int NMethodSweeper::_seen = 0; // Nof. nmethod we have currently processed in current pass of CodeCache
-int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep
-int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep
-int NMethodSweeper::_marked_for_reclamation_count = 0; // Nof. nmethods marked for reclaim in current sweep
volatile bool NMethodSweeper::_should_sweep = true; // Indicates if we should invoke the sweeper
volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from:
@@ -161,6 +158,7 @@
Tickspan NMethodSweeper::_peak_sweep_time; // Peak time for a full sweep
Tickspan NMethodSweeper::_peak_sweep_fraction_time; // Peak time sweeping one fraction
+Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true);
class MarkActivationClosure: public CodeBlobClosure {
public:
@@ -370,9 +368,10 @@
ResourceMark rm;
Ticks sweep_start_counter = Ticks::now();
- _flushed_count = 0;
- _zombified_count = 0;
- _marked_for_reclamation_count = 0;
+ int flushed_count = 0;
+ int zombified_count = 0;
+ int marked_for_reclamation_count = 0;
+ int flushed_c2_count = 0;
if (PrintMethodFlushing && Verbose) {
tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
@@ -386,10 +385,8 @@
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- // The last invocation iterates until there are no more nmethods
while (!_current.end()) {
swept_count++;
- handle_safepoint_request();
// Since we will give up the CodeCache_lock, always skip ahead
// to the next nmethod. Other blobs can be deleted by other
// threads but nmethods are only reclaimed by the sweeper.
@@ -399,9 +396,32 @@
// Now ready to process nmethod and give up CodeCache_lock
{
MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- freed_memory += process_nmethod(nm);
+ int size = nm->total_size();
+ bool is_c2_method = nm->is_compiled_by_c2();
+
+ MethodStateChange type = process_nmethod(nm);
+ switch (type) {
+ case Flushed:
+ freed_memory += size;
+ ++flushed_count;
+ if (is_c2_method) {
+ ++flushed_c2_count;
+ }
+ break;
+ case MarkedForReclamation:
+ ++marked_for_reclamation_count;
+ break;
+ case MadeZombie:
+ ++zombified_count;
+ break;
+ case None:
+ break;
+ default:
+ ShouldNotReachHere();
+ }
}
_seen++;
+ handle_safepoint_request();
}
}
@@ -409,21 +429,25 @@
const Ticks sweep_end_counter = Ticks::now();
const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
- _total_time_sweeping += sweep_time;
- _total_time_this_sweep += sweep_time;
- _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
- _total_flushed_size += freed_memory;
- _total_nof_methods_reclaimed += _flushed_count;
-
+ {
+ MutexLockerEx mu(_stat_lock, Mutex::_no_safepoint_check_flag);
+ _total_time_sweeping += sweep_time;
+ _total_time_this_sweep += sweep_time;
+ _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
+ _total_flushed_size += freed_memory;
+ _total_nof_methods_reclaimed += flushed_count;
+ _total_nof_c2_methods_reclaimed += flushed_c2_count;
+ _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
+ }
EventSweepCodeCache event(UNTIMED);
if (event.should_commit()) {
event.set_starttime(sweep_start_counter);
event.set_endtime(sweep_end_counter);
event.set_sweepIndex(_traversals);
event.set_sweptCount(swept_count);
- event.set_flushedCount(_flushed_count);
- event.set_markedCount(_marked_for_reclamation_count);
- event.set_zombifiedCount(_zombified_count);
+ event.set_flushedCount(flushed_count);
+ event.set_markedCount(marked_for_reclamation_count);
+ event.set_zombifiedCount(zombified_count);
event.commit();
}
@@ -433,7 +457,6 @@
}
#endif
- _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
log_sweep("finished");
// Sweeper is the only case where memory is released, check here if it
@@ -511,10 +534,11 @@
nm->flush();
}
-int NMethodSweeper::process_nmethod(nmethod* nm) {
+NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) {
+ assert(nm != NULL, "sanity");
assert(!CodeCache_lock->owned_by_self(), "just checking");
- int freed_memory = 0;
+ MethodStateChange result = None;
// Make sure this nmethod doesn't get unloaded during the scan,
// since safepoints may happen during acquired below locks.
NMethodMarker nmm(nm);
@@ -529,7 +553,7 @@
nm->cleanup_inline_caches();
SWEEP(nm);
}
- return freed_memory;
+ return result;
}
if (nm->is_zombie()) {
@@ -541,12 +565,9 @@
if (PrintMethodFlushing && Verbose) {
tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
}
- freed_memory = nm->total_size();
- if (nm->is_compiled_by_c2()) {
- _total_nof_c2_methods_reclaimed++;
- }
release_nmethod(nm);
- _flushed_count++;
+ assert(result == None, "sanity");
+ result = Flushed;
} else {
if (PrintMethodFlushing && Verbose) {
tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
@@ -554,8 +575,9 @@
nm->mark_for_reclamation();
// Keep track of code cache state change
_bytes_changed += nm->total_size();
- _marked_for_reclamation_count++;
SWEEP(nm);
+ assert(result == None, "sanity");
+ result = MarkedForReclamation;
}
} else if (nm->is_not_entrant()) {
// If there are no current activations of this method on the
@@ -576,8 +598,9 @@
}
// Code cache state change is tracked in make_zombie()
nm->make_zombie();
- _zombified_count++;
SWEEP(nm);
+ assert(result == None, "sanity");
+ result = MadeZombie;
}
assert(nm->is_zombie(), "nmethod must be zombie");
} else {
@@ -594,17 +617,15 @@
if (nm->is_osr_method()) {
SWEEP(nm);
// No inline caches will ever point to osr methods, so we can just remove it
- freed_memory = nm->total_size();
- if (nm->is_compiled_by_c2()) {
- _total_nof_c2_methods_reclaimed++;
- }
release_nmethod(nm);
- _flushed_count++;
+ assert(result == None, "sanity");
+ result = Flushed;
} else {
// Code cache state change is tracked in make_zombie()
nm->make_zombie();
- _zombified_count++;
SWEEP(nm);
+ assert(result == None, "sanity");
+ result = MadeZombie;
}
} else {
possibly_flush(nm);
@@ -613,7 +634,7 @@
nm->cleanup_inline_caches();
SWEEP(nm);
}
- return freed_memory;
+ return result;
}
--- a/hotspot/src/share/vm/runtime/sweeper.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -56,15 +56,18 @@
class NMethodSweeper : public AllStatic {
friend class WhiteBox;
private:
+ enum MethodStateChange {
+ None,
+ MadeZombie,
+ MarkedForReclamation,
+ Flushed
+ };
static long _traversals; // Stack scan count, also sweep ID.
static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache
static long _time_counter; // Virtual time used to periodically invoke sweeper
static long _last_sweep; // Value of _time_counter when the last sweep happened
static NMethodIterator _current; // Current nmethod
static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache
- static int _flushed_count; // Nof. nmethods flushed in current sweep
- static int _zombified_count; // Nof. nmethods made zombie in current sweep
- static int _marked_for_reclamation_count; // Nof. nmethods marked for reclaim in current sweep
static volatile int _sweep_started; // Flag to control conc sweeper
static volatile bool _should_sweep; // Indicates if we should invoke the sweeper
@@ -83,8 +86,10 @@
static Tickspan _peak_sweep_time; // Peak time for a full sweep
static Tickspan _peak_sweep_fraction_time; // Peak time sweeping one fraction
- static int process_nmethod(nmethod *nm);
- static void release_nmethod(nmethod* nm);
+ static Monitor* _stat_lock;
+
+ static MethodStateChange process_nmethod(nmethod *nm);
+ static void release_nmethod(nmethod* nm);
static void init_sweeper_log() NOT_DEBUG_RETURN;
static bool wait_for_stack_scanning();
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -171,9 +171,9 @@
void Thread::operator delete(void* p) {
if (UseBiasedLocking) {
void* real_malloc_addr = ((Thread*) p)->_real_malloc_address;
- FreeHeap(real_malloc_addr, mtThread);
+ FreeHeap(real_malloc_addr);
} else {
- FreeHeap(p, mtThread);
+ FreeHeap(p);
}
}
@@ -1076,7 +1076,7 @@
}
-void JavaThread::allocate_threadObj(Handle thread_group, char* thread_name,
+void JavaThread::allocate_threadObj(Handle thread_group, const char* thread_name,
bool daemon, TRAPS) {
assert(thread_group.not_null(), "thread group should be specified");
assert(threadObj() == NULL, "should only create Java thread object once");
@@ -1123,8 +1123,8 @@
return;
}
- KlassHandle group(this, SystemDictionary::ThreadGroup_klass());
- Handle threadObj(this, this->threadObj());
+ KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass());
+ Handle threadObj(THREAD, this->threadObj());
JavaCalls::call_special(&result,
thread_group,
@@ -1133,8 +1133,6 @@
vmSymbols::thread_void_signature(),
threadObj, // Arg 1
THREAD);
-
-
}
// NamedThread -- non-JavaThread subclasses with multiple
@@ -1146,7 +1144,7 @@
NamedThread::~NamedThread() {
if (_name != NULL) {
- FREE_C_HEAP_ARRAY(char, _name, mtThread);
+ FREE_C_HEAP_ARRAY(char, _name);
_name = NULL;
}
}
@@ -2998,7 +2996,7 @@
void JavaThread::popframe_free_preserved_args() {
assert(_popframe_preserved_args != NULL, "should not free PopFrame preserved arguments twice");
- FREE_C_HEAP_ARRAY(char, (char*) _popframe_preserved_args, mtThread);
+ FREE_C_HEAP_ARRAY(char, (char*) _popframe_preserved_args);
_popframe_preserved_args = NULL;
_popframe_preserved_args_size = 0;
}
@@ -3608,7 +3606,7 @@
jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
// If we can't find the agent, exit.
vm_exit_during_initialization(buf, NULL);
- FREE_C_HEAP_ARRAY(char, buf, mtThread);
+ FREE_C_HEAP_ARRAY(char, buf);
}
} else {
// Try to load the agent from the standard dll directory
@@ -3628,7 +3626,7 @@
jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
// If we can't find the agent, exit.
vm_exit_during_initialization(buf, NULL);
- FREE_C_HEAP_ARRAY(char, buf, mtThread);
+ FREE_C_HEAP_ARRAY(char, buf);
}
}
}
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -749,6 +749,7 @@
class JavaThread: public Thread {
friend class VMStructs;
+ friend class WhiteBox;
private:
JavaThread* _next; // The next thread in the Threads list
oop _threadObj; // The Java level thread object
@@ -1000,7 +1001,7 @@
ThreadFunction entry_point() const { return _entry_point; }
// Allocates a new Java level thread object for this thread. thread_name may be NULL.
- void allocate_threadObj(Handle thread_group, char* thread_name, bool daemon, TRAPS);
+ void allocate_threadObj(Handle thread_group, const char* thread_name, bool daemon, TRAPS);
// Last frame anchor routines
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -554,9 +554,9 @@
\
nonstatic_field(OffsetTableContigSpace, _offsets, BlockOffsetArray) \
\
- nonstatic_field(OneContigSpaceCardGeneration, _min_heap_delta_bytes, size_t) \
- nonstatic_field(OneContigSpaceCardGeneration, _the_space, ContiguousSpace*) \
- nonstatic_field(OneContigSpaceCardGeneration, _last_gc, WaterMark) \
+ nonstatic_field(TenuredGeneration, _min_heap_delta_bytes, size_t) \
+ nonstatic_field(TenuredGeneration, _the_space, ContiguousSpace*) \
+ nonstatic_field(TenuredGeneration, _last_gc, WaterMark) \
\
\
\
@@ -1481,8 +1481,7 @@
declare_toplevel_type(Generation) \
declare_type(DefNewGeneration, Generation) \
declare_type(CardGeneration, Generation) \
- declare_type(OneContigSpaceCardGeneration, CardGeneration) \
- declare_type(TenuredGeneration, OneContigSpaceCardGeneration) \
+ declare_type(TenuredGeneration, CardGeneration) \
declare_toplevel_type(Space) \
declare_toplevel_type(BitMap) \
declare_type(CompactibleSpace, Space) \
@@ -1534,8 +1533,8 @@
declare_toplevel_type(HeapWord*) \
declare_toplevel_type(MemRegion*) \
declare_toplevel_type(OffsetTableContigSpace*) \
- declare_toplevel_type(OneContigSpaceCardGeneration*) \
declare_toplevel_type(Space*) \
+ declare_toplevel_type(TenuredGeneration*) \
declare_toplevel_type(ThreadLocalAllocBuffer*) \
\
/************************/ \
@@ -3268,10 +3267,10 @@
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
- FREE_C_HEAP_ARRAY(char, s, mtInternal);
+ FREE_C_HEAP_ARRAY(char, s);
return 1;
}
- FREE_C_HEAP_ARRAY(char, s, mtInternal);
+ FREE_C_HEAP_ARRAY(char, s);
}
const char* start = NULL;
if (strstr(typeName, "GrowableArray<") == typeName) {
@@ -3287,10 +3286,10 @@
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
- FREE_C_HEAP_ARRAY(char, s, mtInternal);
+ FREE_C_HEAP_ARRAY(char, s);
return 1;
}
- FREE_C_HEAP_ARRAY(char, s, mtInternal);
+ FREE_C_HEAP_ARRAY(char, s);
}
if (strstr(typeName, "const ") == typeName) {
const char * s = typeName + strlen("const ");
--- a/hotspot/src/share/vm/services/attachListener.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/attachListener.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -348,7 +348,7 @@
}
bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
if (res) {
- FREE_C_HEAP_ARRAY(char, value, mtInternal);
+ FREE_C_HEAP_ARRAY(char, value);
} else {
out->print_cr("setting flag %s failed", name);
}
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -174,7 +174,7 @@
template <> void DCmdArgument<char*>::destroy_value() {
if (_value != NULL) {
- FREE_C_HEAP_ARRAY(char, _value, mtInternal);
+ FREE_C_HEAP_ARRAY(char, _value);
set_value(NULL);
}
}
--- a/hotspot/src/share/vm/services/diagnosticArgument.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/diagnosticArgument.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 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
@@ -53,7 +53,7 @@
~StringArrayArgument() {
for (int i=0; i<_array->length(); i++) {
if(_array->at(i) != NULL) { // Safety check
- FREE_C_HEAP_ARRAY(char, _array->at(i), mtInternal);
+ FREE_C_HEAP_ARRAY(char, _array->at(i));
}
}
delete _array;
--- a/hotspot/src/share/vm/services/diagnosticFramework.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -60,16 +60,15 @@
bool DCmdArgIter::next(TRAPS) {
if (_len == 0) return false;
- // skipping spaces
+ // skipping delimiters
while (_cursor < _len - 1 && _buffer[_cursor] == _delim) {
_cursor++;
}
// handling end of command line
- if (_cursor >= _len - 1) {
- _cursor = _len - 1;
- _key_addr = &_buffer[_len - 1];
+ if (_cursor == _len - 1 && _buffer[_cursor] == _delim) {
+ _key_addr = &_buffer[_cursor];
_key_len = 0;
- _value_addr = &_buffer[_len - 1];
+ _value_addr = &_buffer[_cursor];
_value_len = 0;
return false;
}
--- a/hotspot/src/share/vm/services/heapDumper.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/heapDumper.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1404,7 +1404,7 @@
for (int i=0; i < _num_threads; i++) {
delete _stack_traces[i];
}
- FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);
+ FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces);
}
delete _klass_map;
}
--- a/hotspot/src/share/vm/services/management.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/management.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1744,7 +1744,7 @@
ccstr svalue = java_lang_String::as_utf8_string(str);
succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT);
if (succeed) {
- FREE_C_HEAP_ARRAY(char, svalue, mtInternal);
+ FREE_C_HEAP_ARRAY(char, svalue);
}
}
assert(succeed, "Setting flag should succeed");
@@ -1819,7 +1819,7 @@
for (int i = 0; i < _count; i++) {
os::free(_names_chars[i]);
}
- FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal);
+ FREE_C_HEAP_ARRAY(char *, _names_chars);
}
// Fills names with VM internal thread names and times with the corresponding
--- a/hotspot/src/share/vm/services/memoryManager.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/services/memoryManager.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -171,8 +171,8 @@
}
GCStatInfo::~GCStatInfo() {
- FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array, mtInternal);
- FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array, mtInternal);
+ FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array);
+ FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array);
}
void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) {
--- a/hotspot/src/share/vm/utilities/array.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/array.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -66,7 +66,7 @@
// allocate and initialize new data section
void* data = NEW_C_HEAP_ARRAY(char*, esize * size, F);
memcpy(data, _data, esize * length());
- FREE_C_HEAP_ARRAY(char*, _data, F);
+ FREE_C_HEAP_ARRAY(char*, _data);
_data = data;
}
--- a/hotspot/src/share/vm/utilities/bitMap.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/bitMap.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -468,7 +468,7 @@
(intptr_t) NULL_WORD);
if (res != NULL_WORD) {
guarantee( _pop_count_table == (void*) res, "invariant" );
- FREE_C_HEAP_ARRAY(idx_t, table, mtInternal);
+ FREE_C_HEAP_ARRAY(idx_t, table);
}
}
}
--- a/hotspot/src/share/vm/utilities/hashtable.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -149,7 +149,7 @@
// allocated by os::malloc
if (!UseSharedSpaces ||
!FileMapInfo::current_info()->is_in_shared_space(_buckets)) {
- FREE_C_HEAP_ARRAY(HashtableBucket, _buckets, F);
+ FREE_C_HEAP_ARRAY(HashtableBucket, _buckets);
}
_buckets = NULL;
}
--- a/hotspot/src/share/vm/utilities/numberSeq.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/numberSeq.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -139,7 +139,7 @@
}
TruncatedSeq::~TruncatedSeq() {
- FREE_C_HEAP_ARRAY(double, _sequence, mtGC);
+ FREE_C_HEAP_ARRAY(double, _sequence);
}
void TruncatedSeq::add(double val) {
--- a/hotspot/src/share/vm/utilities/ostream.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -498,37 +498,37 @@
jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms);
o_result = make_log_name_internal("test.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
- FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+ FREE_C_HEAP_ARRAY(char, o_result);
// test-%t-%p.log
jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid);
o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
- FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+ FREE_C_HEAP_ARRAY(char, o_result);
// test-%t%p.log
jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid);
o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
- FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+ FREE_C_HEAP_ARRAY(char, o_result);
// %p%t.log
jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms);
o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
- FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+ FREE_C_HEAP_ARRAY(char, o_result);
// %p-test.log
jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid);
o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
- FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+ FREE_C_HEAP_ARRAY(char, o_result);
// %t.log
jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms);
o_result = make_log_name_internal("%t.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
- FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+ FREE_C_HEAP_ARRAY(char, o_result);
}
#endif // PRODUCT
@@ -627,7 +627,7 @@
_file = NULL;
}
if (_file_name != NULL) {
- FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, _file_name);
_file_name = NULL;
}
}
@@ -829,7 +829,7 @@
"Warning: Cannot open log file: %s\n", try_name);
// Note: This feature is for maintainer use only. No need for L10N.
jio_print(warnbuf);
- FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, try_name);
try_name = make_log_name(log_name, os::get_temp_directory());
jio_snprintf(warnbuf, sizeof(warnbuf),
"Warning: Forcing option -XX:LogFile=%s\n", try_name);
@@ -837,7 +837,7 @@
delete file;
file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
}
- FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, try_name);
if (file->is_open()) {
_log_file = file;
@@ -1121,7 +1121,7 @@
const char* list_name = make_log_name(DumpLoadedClassList, NULL);
classlist_file = new(ResourceObj::C_HEAP, mtInternal)
fileStream(list_name);
- FREE_C_HEAP_ARRAY(char, list_name, mtInternal);
+ FREE_C_HEAP_ARRAY(char, list_name);
}
#endif
@@ -1274,7 +1274,7 @@
bufferedStream::~bufferedStream() {
if (!buffer_fixed) {
- FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
+ FREE_C_HEAP_ARRAY(char, buffer);
}
}
--- a/hotspot/src/share/vm/utilities/quickSort.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/quickSort.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -214,8 +214,8 @@
sort(test_array, length, test_even_odd_comparator, true);
assert(compare_arrays(test_array, expected_array, length), "Sorting already sorted array changed order of elements - not idempotent");
- FREE_C_HEAP_ARRAY(int, test_array, mtInternal);
- FREE_C_HEAP_ARRAY(int, expected_array, mtInternal);
+ FREE_C_HEAP_ARRAY(int, test_array);
+ FREE_C_HEAP_ARRAY(int, expected_array);
}
}
--- a/hotspot/src/share/vm/utilities/stack.inline.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/stack.inline.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -145,7 +145,7 @@
template <class E, MEMFLAGS F>
void Stack<E, F>::free(E* addr, size_t bytes)
{
- FREE_C_HEAP_ARRAY(char, (char*) addr, F);
+ FREE_C_HEAP_ARRAY(char, (char*) addr);
}
template <class E, MEMFLAGS F>
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -427,7 +427,7 @@
template<class E, MEMFLAGS F, unsigned int N>
GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
- FREE_C_HEAP_ARRAY(E, _elems, F);
+ FREE_C_HEAP_ARRAY(E, _elems);
}
// OverflowTaskQueue is a TaskQueue that also includes an overflow stack for
--- a/hotspot/src/share/vm/utilities/workgroup.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -489,7 +489,7 @@
SubTasksDone::~SubTasksDone() {
- if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks, mtInternal);
+ if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks);
}
// *** SequentialSubTasksDone
@@ -560,7 +560,7 @@
FreeIdSet::~FreeIdSet() {
_sets[_index] = NULL;
- FREE_C_HEAP_ARRAY(int, _ids, mtInternal);
+ FREE_C_HEAP_ARRAY(int, _ids);
}
void FreeIdSet::set_safepoint(bool b) {
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Dec 11 12:28:03 2014 -0800
@@ -58,7 +58,7 @@
#ifdef ASSERT
xmlStream::~xmlStream() {
- FREE_C_HEAP_ARRAY(char, _element_close_stack_low, mtInternal);
+ FREE_C_HEAP_ARRAY(char, _element_close_stack_low);
}
#endif
@@ -162,7 +162,7 @@
_element_close_stack_high = new_high;
_element_close_stack_low = new_low;
_element_close_stack_ptr = new_ptr;
- FREE_C_HEAP_ARRAY(char, old_low, mtInternal);
+ FREE_C_HEAP_ARRAY(char, old_low);
push_ptr = new_ptr - (tag_len+1);
}
assert(push_ptr >= _element_close_stack_low, "in range");
--- a/hotspot/test/TEST.groups Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/TEST.groups Thu Dec 11 12:28:03 2014 -0800
@@ -139,6 +139,7 @@
gc/g1/TestShrinkAuxiliaryData20.java \
gc/g1/TestShrinkAuxiliaryData25.java \
gc/g1/TestShrinkAuxiliaryData30.java \
+ gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
serviceability/threads/TestFalseDeadLock.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestArrayCopyNoInit.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,244 @@
+/*
+ * 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 8064703
+ * @summary Deoptimization between array allocation and arraycopy may result in non initialized array
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=020 TestArrayCopyNoInit
+ *
+ */
+
+import java.lang.invoke.*;
+
+public class TestArrayCopyNoInit {
+
+ static int[] m1(int[] src) {
+ int[] dest = new int[10];
+ try {
+ System.arraycopy(src, 0, dest, 0, 10);
+ } catch (NullPointerException npe) {
+ }
+ return dest;
+ }
+
+ static int[] m2(Object src, boolean flag) {
+ Class tmp = src.getClass();
+ if (flag) {
+ return null;
+ }
+ int[] dest = new int[10];
+ try {
+ System.arraycopy(src, 0, dest, 0, 10);
+ } catch (ArrayStoreException npe) {
+ }
+ return dest;
+ }
+
+ static int[] m3(int[] src, int src_offset) {
+ int tmp = src[0];
+ int[] dest = new int[10];
+ try {
+ System.arraycopy(src, src_offset, dest, 0, 10);
+ } catch (IndexOutOfBoundsException npe) {
+ }
+ return dest;
+ }
+
+ static int[] m4(int[] src, int length) {
+ int tmp = src[0];
+ int[] dest = new int[10];
+ try {
+ System.arraycopy(src, 0, dest, 0, length);
+ } catch (IndexOutOfBoundsException npe) {
+ }
+ return dest;
+ }
+
+ static TestArrayCopyNoInit[] m5(Object[] src) {
+ Object tmp = src[0];
+ TestArrayCopyNoInit[] dest = new TestArrayCopyNoInit[10];
+ System.arraycopy(src, 0, dest, 0, 0);
+ return dest;
+ }
+
+ static class A {
+ }
+
+ static class B extends A {
+ }
+
+ static class C extends B {
+ }
+
+ static class D extends C {
+ }
+
+ static class E extends D {
+ }
+
+ static class F extends E {
+ }
+
+ static class G extends F {
+ }
+
+ static class H extends G {
+ }
+
+ static class I extends H {
+ }
+
+ static H[] m6(Object[] src) {
+ Object tmp = src[0];
+ H[] dest = new H[10];
+ System.arraycopy(src, 0, dest, 0, 0);
+ return dest;
+ }
+
+ static Object m7_src(Object src) {
+ return src;
+ }
+
+ static int[] m7(Object src, boolean flag) {
+ Class tmp = src.getClass();
+ if (flag) {
+ return null;
+ }
+ src = m7_src(src);
+ int[] dest = new int[10];
+ try {
+ System.arraycopy(src, 0, dest, 0, 10);
+ } catch (ArrayStoreException npe) {
+ }
+ return dest;
+ }
+
+ static public void main(String[] args) throws Throwable {
+ boolean success = true;
+ int[] src = new int[10];
+ TestArrayCopyNoInit[] src2 = new TestArrayCopyNoInit[10];
+ int[] res = null;
+ TestArrayCopyNoInit[] res2 = null;
+ Object src_obj = new Object();
+
+ for (int i = 0; i < 20000; i++) {
+ m1(src);
+ }
+
+ res = m1(null);
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] != 0) {
+ success = false;
+ System.out.println("Uninitialized array following NPE");
+ break;
+ }
+ }
+
+ for (int i = 0; i < 20000; i++) {
+ if ((i%2) == 0) {
+ m2(src, false);
+ } else {
+ m2(src_obj, true);
+ }
+ }
+ res = m2(src_obj, false);
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] != 0) {
+ success = false;
+ System.out.println("Uninitialized array following failed array check");
+ break;
+ }
+ }
+
+ for (int i = 0; i < 20000; i++) {
+ m3(src, 0);
+ }
+ res = m3(src, -1);
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] != 0) {
+ success = false;
+ System.out.println("Uninitialized array following failed src offset check");
+ break;
+ }
+ }
+
+ for (int i = 0; i < 20000; i++) {
+ m4(src, 0);
+ }
+ res = m4(src, -1);
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] != 0) {
+ success = false;
+ System.out.println("Uninitialized array following failed length check");
+ break;
+ }
+ }
+
+ for (int i = 0; i < 20000; i++) {
+ m5(src2);
+ }
+ res2 = m5(new Object[10]);
+ for (int i = 0; i < res2.length; i++) {
+ if (res2[i] != null) {
+ success = false;
+ System.out.println("Uninitialized array following failed type check");
+ break;
+ }
+ }
+
+ H[] src3 = new H[10];
+ I b = new I();
+ for (int i = 0; i < 20000; i++) {
+ m6(src3);
+ }
+ H[] res3 = m6(new Object[10]);
+ for (int i = 0; i < res3.length; i++) {
+ if (res3[i] != null) {
+ success = false;
+ System.out.println("Uninitialized array following failed full type check");
+ break;
+ }
+ }
+
+ for (int i = 0; i < 20000; i++) {
+ if ((i%2) == 0) {
+ m7(src, false);
+ } else {
+ m7(src_obj, true);
+ }
+ }
+ res = m7(src_obj, false);
+ for (int i = 0; i < res.length; i++) {
+ if (res[i] != 0) {
+ success = false;
+ System.out.println("Uninitialized array following failed type check with return value profiling");
+ break;
+ }
+ }
+
+ if (!success) {
+ throw new RuntimeException("Some tests failed");
+ }
+ }
+}
--- a/hotspot/test/compiler/runtime/8010927/Test8010927.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/compiler/runtime/8010927/Test8010927.java Thu Dec 11 12:28:03 2014 -0800
@@ -29,7 +29,7 @@
* @build Test8010927
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xmx64m -XX:NewSize=20971520 -XX:MaxNewSize=32m -XX:-UseTLAB -XX:-UseParNewGC -XX:-UseAdaptiveSizePolicy Test8010927
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xmx64m -XX:NewSize=20971520 -XX:MaxNewSize=32m -XX:-UseTLAB -XX:-UseAdaptiveSizePolicy Test8010927
*/
import sun.hotspot.WhiteBox;
--- a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java Thu Dec 11 12:28:03 2014 -0800
@@ -24,22 +24,29 @@
/*
* @test
* @bug 8023014
- * @summary Test ensures that there is no crash if there is not enough ReservedCodeacacheSize
+ * @summary Test ensures that there is no crash if there is not enough ReservedCodeCacheSize
* to initialize all compiler threads. The option -Xcomp gives the VM more time to
- * to trigger the old bug.
+ * trigger the old bug.
* @library /testlibrary
*/
import com.oracle.java.testlibrary.*;
+import static com.oracle.java.testlibrary.Asserts.assertTrue;
public class SmallCodeCacheStartup {
- public static void main(String[] args) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=3m",
- "-XX:CICompilerCount=64",
- "-Xcomp",
- "-version");
- OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
- analyzer.shouldHaveExitValue(0);
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=3m",
+ "-XX:CICompilerCount=64",
+ "-Xcomp",
+ "-version");
+ OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
+ try {
+ analyzer.shouldHaveExitValue(0);
+ } catch (RuntimeException e) {
+ // Error occurred during initialization, did we run out of adapter space?
+ assertTrue(analyzer.getOutput().contains("VirtualMachineError: Out of space in CodeCache"),
+ "Expected VirtualMachineError");
+ }
- System.out.println("TEST PASSED");
+ System.out.println("TEST PASSED");
}
}
--- a/hotspot/test/compiler/types/correctness/CorrectnessTest.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java Thu Dec 11 12:28:03 2014 -0800
@@ -25,6 +25,7 @@
* @test CorrectnessTest
* @bug 8038418
* @library /testlibrary /testlibrary/whitebox
+ * @ignore 8066173
* @compile execution/TypeConflict.java execution/TypeProfile.java
* execution/MethodHandleDelegate.java
* @build CorrectnessTest
--- a/hotspot/test/compiler/types/correctness/OffTest.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/compiler/types/correctness/OffTest.java Thu Dec 11 12:28:03 2014 -0800
@@ -25,6 +25,7 @@
* @test CorrectnessTest
* @bug 8038418
* @library /testlibrary /testlibrary/whitebox
+ * @ignore 8066173
* @compile execution/TypeConflict.java execution/TypeProfile.java
* execution/MethodHandleDelegate.java
* @build CorrectnessTest
--- a/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java Thu Dec 11 12:28:03 2014 -0800
@@ -29,10 +29,11 @@
import sun.hotspot.WhiteBox;
import sun.hotspot.code.BlobType;
import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.InfiniteLoop;
/*
* @test AllocationCodeBlobTest
- * @bug 8059624
+ * @bug 8059624 8064669
* @library /testlibrary /testlibrary/whitebox
* @build AllocationCodeBlobTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
@@ -53,11 +54,32 @@
public static void main(String[] args) {
// check that Sweeper handels dummy blobs correctly
- new ForcedSweeper(500).start();
+ Thread t = new Thread(
+ new InfiniteLoop(WHITE_BOX::forceNMethodSweep, 1L),
+ "ForcedSweeper");
+ t.setDaemon(true);
+ System.out.println("Starting " + t.getName());
+ t.start();
+
EnumSet<BlobType> blobTypes = BlobType.getAvailable();
for (BlobType type : blobTypes) {
new AllocationCodeBlobTest(type).test();
}
+
+ // check that deoptimization works well w/ dummy blobs
+ t = new Thread(
+ new InfiniteLoop(WHITE_BOX::deoptimizeAll, 1L),
+ "Deoptimize Thread");
+ t.setDaemon(true);
+ System.out.println("Starting " + t.getName());
+ t.start();
+
+ for (int i = 0; i < 10_000; ++i) {
+ for (BlobType type : blobTypes) {
+ long addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
+ }
+ }
+
}
private final BlobType type;
@@ -105,24 +127,4 @@
private long getUsage() {
return bean.getUsage().getUsed();
}
-
- private static class ForcedSweeper extends Thread {
- private final int millis;
- public ForcedSweeper(int millis) {
- super("ForcedSweeper");
- setDaemon(true);
- this.millis = millis;
- }
- public void run() {
- try {
- while (true) {
- WHITE_BOX.forceNMethodSweep();
- Thread.sleep(millis);
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new Error(e);
- }
- }
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ *
+ */
+
+import java.lang.reflect.Method;
+import java.util.EnumSet;
+
+import sun.hotspot.WhiteBox;
+import sun.hotspot.code.BlobType;
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.InfiniteLoop;
+
+/*
+ * @test
+ * @bug 8059624 8064669
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ForceNMethodSweepTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:-TieredCompilation -XX:+WhiteBoxAPI
+ * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::*
+ * ForceNMethodSweepTest
+ * @summary testing of WB::forceNMethodSweep
+ */
+public class ForceNMethodSweepTest extends CompilerWhiteBoxTest {
+ public static void main(String[] args) throws Exception {
+ CompilerWhiteBoxTest.main(ForceNMethodSweepTest::new, args);
+ }
+ private final EnumSet<BlobType> blobTypes;
+ private ForceNMethodSweepTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
+ blobTypes = BlobType.getAvailable();
+ }
+
+ @Override
+ protected void test() throws Exception {
+ checkNotCompiled();
+ guaranteedSweep();
+ int usage = getTotalUsage();
+
+ compile();
+ checkCompiled();
+ int afterCompilation = getTotalUsage();
+ Asserts.assertGT(afterCompilation, usage,
+ "compilation should increase usage");
+
+ guaranteedSweep();
+ int afterSweep = getTotalUsage();
+ Asserts.assertLTE(afterSweep, afterCompilation,
+ "sweep shouldn't increase usage");
+
+ deoptimize();
+ guaranteedSweep();
+ int afterDeoptAndSweep = getTotalUsage();
+ Asserts.assertLT(afterDeoptAndSweep, afterSweep,
+ "sweep after deoptimization should decrease usage");
+ }
+
+ private int getTotalUsage() {
+ int usage = 0;
+ for (BlobType type : blobTypes) {
+ usage += type.getMemoryPool().getUsage().getUsed();
+ }
+ return usage;
+ }
+ private void guaranteedSweep() {
+ // not entrant -> ++stack_traversal_mark -> zombie -> reclamation -> flushed
+ for (int i = 0; i < 5; ++i) {
+ WHITE_BOX.fullGC();
+ WHITE_BOX.forceNMethodSweep();
+ }
+ }
+}
--- a/hotspot/test/compiler/whitebox/GetNMethodTest.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/compiler/whitebox/GetNMethodTest.java Thu Dec 11 12:28:03 2014 -0800
@@ -75,7 +75,7 @@
break;
case 2:
case 3:
- checkBlockType(nmethod, BlobType.MethodNonProfiled);
+ checkBlockType(nmethod, BlobType.MethodProfiled);
break;
default:
throw new Error("unexpected comp level " + nmethod);
--- a/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java Thu Dec 11 12:28:03 2014 -0800
@@ -26,7 +26,7 @@
* @key gc
* @summary Tests that all SoftReferences has been cleared at time of OOM.
* @library /testlibrary
- * @build TestSoftReference
+ * @build TestSoftReferencesBehaviorOnOOME
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 128k 256k
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 2k 32k 10
--- a/hotspot/test/gc/TestSystemGC.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/gc/TestSystemGC.java Thu Dec 11 12:28:03 2014 -0800
@@ -28,12 +28,10 @@
* @summary Runs System.gc() with different flags.
* @run main/othervm TestSystemGC
* @run main/othervm -XX:+UseSerialGC TestSystemGC
- * @run main/othervm -XX:+UseParNewGC TestSystemGC
* @run main/othervm -XX:+UseParallelGC TestSystemGC
* @run main/othervm -XX:+UseParallelGC -XX:-UseParallelOldGC TestSystemGC
* @run main/othervm -XX:+UseConcMarkSweepGC TestSystemGC
* @run main/othervm -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent TestSystemGC
- * @run main/othervm -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:-UseParNewGC TestSystemGC
* @run main/othervm -XX:+UseG1GC TestSystemGC
* @run main/othervm -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent TestSystemGC
* @run main/othervm -XX:+UseLargePages TestSystemGC
--- a/hotspot/test/gc/arguments/TestG1HeapRegionSize.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2013, 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
@@ -25,12 +25,11 @@
* @test TestG1HeapRegionSize
* @key gc
* @bug 8021879
- * @requires vm.gc=="G1" | vm.gc=="null"
* @summary Verify that the flag G1HeapRegionSize is updated properly
* @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
- * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m -XX:+UseG1GC TestG1HeapRegionSize 2097152
- * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m -XX:+UseG1GC TestG1HeapRegionSize 2097152
- * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m -XX:+UseG1GC TestG1HeapRegionSize 33554432
+ * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
*/
import sun.management.ManagementFactoryHelper;
@@ -43,7 +42,13 @@
HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
String expectedValue = getExpectedValue(args);
- VMOption option = diagnostic.getVMOption("G1HeapRegionSize");
+ VMOption option = diagnostic.getVMOption("UseG1GC");
+ if (option.getValue().equals("false")) {
+ System.out.println("Skipping this test. It is only a G1 test.");
+ return;
+ }
+
+ option = diagnostic.getVMOption("G1HeapRegionSize");
if (!expectedValue.equals(option.getValue())) {
throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.Utils;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @test
+ * @bug 8031323
+ * @summary Verify SurvivorAlignmentInBytes option processing.
+ * @library /testlibrary
+ * @run main TestSurvivorAlignmentInBytesOption
+ */
+public class TestSurvivorAlignmentInBytesOption {
+ private static final String[] FILTERED_VM_OPTIONS
+ = Utils.getFilteredTestJavaOpts(
+ "UnlockExperimentalVMOptions",
+ "SurvivorAlignmentInBytes",
+ "ObjectAlignmentInBytes");
+
+ public static void main(String args[]) throws Throwable {
+ String optionName = "SurvivorAlignmentInBytes";
+ String optionIsExperimental
+ = CommandLineOptionTest.getExperimentalOptionErrorMessage(
+ optionName);
+ String valueIsTooSmall= ".*SurvivorAlignmentInBytes=.*must be greater"
+ + " than ObjectAlignmentInBytes.*";
+ String mustBePowerOf2 = ".*SurvivorAlignmentInBytes=.*must be "
+ + "power of 2.*";
+
+ // Verify that without -XX:+UnlockExperimentalVMOptions usage of
+ // SurvivorAlignmentInBytes option will cause JVM startup failure
+ // with the warning message saying that that option is experimental.
+ CommandLineOptionTest.verifyJVMStartup(
+ new String[]{optionIsExperimental}, null, ExitCode.FAIL, false,
+ TestSurvivorAlignmentInBytesOption.prepareOptions(
+ "-XX:-UnlockExperimentalVMOptions",
+ CommandLineOptionTest.prepareNumericFlag(
+ optionName, 64)));
+
+ // Verify that with -XX:+UnlockExperimentalVMOptions passed to JVM
+ // usage of SurvivorAlignmentInBytes option won't cause JVM startup
+ // failure.
+ CommandLineOptionTest.verifyJVMStartup(
+ null, new String[]{optionIsExperimental}, ExitCode.OK, false,
+ TestSurvivorAlignmentInBytesOption.prepareOptions(
+ CommandLineOptionTest.prepareNumericFlag(
+ optionName, 64)));
+
+ // Verify that if specified SurvivorAlignmentInBytes is lower then
+ // ObjectAlignmentInBytes, then the JVM startup will fail with
+ // appropriate error message.
+ CommandLineOptionTest.verifyJVMStartup(
+ new String[]{valueIsTooSmall}, null, ExitCode.FAIL, false,
+ TestSurvivorAlignmentInBytesOption.prepareOptions(
+ CommandLineOptionTest.prepareNumericFlag(
+ optionName, 2)));
+
+ // Verify that if specified SurvivorAlignmentInBytes value is not
+ // a power of 2 then the JVM startup will fail with appropriate error
+ // message.
+ CommandLineOptionTest.verifyJVMStartup(
+ new String[]{mustBePowerOf2}, null, ExitCode.FAIL, false,
+ TestSurvivorAlignmentInBytesOption.prepareOptions(
+ CommandLineOptionTest.prepareNumericFlag(
+ optionName, 127)));
+
+ // Verify that if SurvivorAlignmentInBytes has correct value, then
+ // the JVM will be started without errors.
+ CommandLineOptionTest.verifyJVMStartup(
+ null, new String[]{".*SurvivorAlignmentInBytes.*"},
+ ExitCode.OK, false,
+ TestSurvivorAlignmentInBytesOption.prepareOptions(
+ CommandLineOptionTest.prepareNumericFlag(
+ optionName, 128)));
+
+ // Verify that we can setup different SurvivorAlignmentInBytes values.
+ for (int alignment = 32; alignment <= 128; alignment *= 2) {
+ CommandLineOptionTest.verifyOptionValue(optionName,
+ Integer.toString(alignment), false,
+ TestSurvivorAlignmentInBytesOption.prepareOptions(
+ CommandLineOptionTest.prepareNumericFlag(
+ optionName, alignment)));
+ }
+ }
+
+ private static String[] prepareOptions(String... options) {
+ List<String> finalOptions = new LinkedList<>();
+ Collections.addAll(finalOptions,
+ TestSurvivorAlignmentInBytesOption.FILTERED_VM_OPTIONS);
+ finalOptions.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+ Collections.addAll(finalOptions, options);
+ return finalOptions.toArray(new String[finalOptions.size()]);
+ }
+}
--- a/hotspot/test/gc/startup_warnings/TestDefNewCMS.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/gc/startup_warnings/TestDefNewCMS.java Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2013, 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
@@ -24,8 +24,8 @@
/*
* @test TestDefNewCMS
* @key gc
-* @bug 8006398
-* @summary Test that the deprecated DefNew+CMS combination print a warning message
+* @bug 8065972
+* @summary Test that the unsupported DefNew+CMS combination does not start
* @library /testlibrary
*/
@@ -37,9 +37,9 @@
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:-UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
- output.shouldContain("warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release");
- output.shouldNotContain("error");
- output.shouldHaveExitValue(0);
+ output.shouldContain("It is not possible to combine the DefNew young collector with the CMS collector.");
+ output.shouldContain("Error");
+ output.shouldHaveExitValue(1);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestNoParNew.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,46 @@
+/*
+* 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 TestNoParNew
+* @key gc
+* @bug 8065972
+* @summary Test that specifying -XX:-UseParNewGC on the command line logs a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestNoParNew {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:-UseParNewGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: The UseParNewGC flag is deprecated and will likely be removed in a future release");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- a/hotspot/test/gc/startup_warnings/TestParNewCMS.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/gc/startup_warnings/TestParNewCMS.java Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2013, 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
@@ -24,8 +24,8 @@
/*
* @test TestParNewCMS
* @key gc
-* @bug 8006398
-* @summary Test that the combination ParNew+CMS does not print a warning message
+* @bug 8065972
+* @summary Test that specifying -XX:+UseParNewGC on the command line logs a warning message
* @library /testlibrary
*/
@@ -38,7 +38,7 @@
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
- output.shouldNotContain("deprecated");
+ output.shouldContain("warning: The UseParNewGC flag is deprecated and will likely be removed in a future release");
output.shouldNotContain("error");
output.shouldHaveExitValue(0);
}
--- a/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java Thu Dec 11 12:28:03 2014 -0800
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2013, 2024, 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
@@ -24,8 +24,8 @@
/*
* @test TestParNewSerialOld
* @key gc
-* @bug 8006398
-* @summary Test that the deprecated ParNew+SerialOld combination print a warning message
+* @bug 8065972
+* @summary Test that the unsupported ParNew+SerialOld combination does not start
* @library /testlibrary
*/
@@ -38,9 +38,9 @@
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
- output.shouldContain("warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release");
- output.shouldNotContain("error");
- output.shouldHaveExitValue(0);
+ output.shouldContain("It is not possible to combine the ParNew young collector with the Serial old collector.");
+ output.shouldContain("Error");
+ output.shouldHaveExitValue(1);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/AlignmentHelper.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+import java.lang.management.MemoryPoolMXBean;
+import java.util.Optional;
+
+import sun.hotspot.WhiteBox;
+
+/**
+ * Helper class aimed to provide information about alignment of objects in
+ * particular heap space, expected memory usage after objects' allocation so on.
+ */
+public class AlignmentHelper {
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+ private static final long OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM = 8L;
+
+ /**
+ * Max relative allowed actual memory usage deviation from expected memory
+ * usage.
+ */
+ private static final float MAX_RELATIVE_DEVIATION = 0.05f; // 5%
+
+ public static final long OBJECT_ALIGNMENT_IN_BYTES = Optional.ofNullable(
+ AlignmentHelper.WHITE_BOX.getIntxVMFlag("ObjectAlignmentInBytes"))
+ .orElse(AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM);
+
+ public static final long SURVIVOR_ALIGNMENT_IN_BYTES = Optional.ofNullable(
+ AlignmentHelper.WHITE_BOX.getIntxVMFlag("SurvivorAlignmentInBytes"))
+ .orElseThrow(() ->new AssertionError(
+ "Unable to get SurvivorAlignmentInBytes value"));
+ /**
+ * Min amount of memory that will be occupied by an object.
+ */
+ public static final long MIN_OBJECT_SIZE
+ = AlignmentHelper.WHITE_BOX.getObjectSize(new Object());
+ /**
+ * Min amount of memory that will be occupied by an empty byte array.
+ */
+ public static final long MIN_ARRAY_SIZE
+ = AlignmentHelper.WHITE_BOX.getObjectSize(new byte[0]);
+
+ /**
+ * Precision at which actual memory usage in a heap space represented by
+ * this sizing helper could be measured.
+ */
+ private final long memoryUsageMeasurementPrecision;
+ /**
+ * Min amount of memory that will be occupied by an object allocated in a
+ * heap space represented by this sizing helper.
+ */
+ private final long minObjectSizeInThisSpace;
+ /**
+ * Object's alignment in a heap space represented by this sizing helper.
+ */
+ private final long objectAlignmentInThisRegion;
+ /**
+ * MemoryPoolMXBean associated with a heap space represented by this sizing
+ * helper.
+ */
+ private final MemoryPoolMXBean poolMXBean;
+
+ private static long alignUp(long value, long alignment) {
+ return ((value - 1) / alignment + 1) * alignment;
+ }
+
+ protected AlignmentHelper(long memoryUsageMeasurementPrecision,
+ long objectAlignmentInThisRegion, long minObjectSizeInThisSpace,
+ MemoryPoolMXBean poolMXBean) {
+ this.memoryUsageMeasurementPrecision = memoryUsageMeasurementPrecision;
+ this.minObjectSizeInThisSpace = minObjectSizeInThisSpace;
+ this.objectAlignmentInThisRegion = objectAlignmentInThisRegion;
+ this.poolMXBean = poolMXBean;
+ }
+
+ /**
+ * Returns how many objects have to be allocated to fill
+ * {@code memoryToFill} bytes in this heap space using objects of size
+ * {@code objectSize}.
+ */
+ public int getObjectsCount(long memoryToFill, long objectSize) {
+ return (int) (memoryToFill / getObjectSizeInThisSpace(objectSize));
+ }
+
+ /**
+ * Returns amount of memory that {@code objectsCount} of objects with size
+ * {@code objectSize} will occupy this this space after allocation.
+ */
+ public long getExpectedMemoryUsage(long objectSize, int objectsCount) {
+ long correctedObjectSize = getObjectSizeInThisSpace(objectSize);
+ return AlignmentHelper.alignUp(correctedObjectSize * objectsCount,
+ memoryUsageMeasurementPrecision);
+ }
+
+ /**
+ * Returns current memory usage in this heap space.
+ */
+ public long getActualMemoryUsage() {
+ return poolMXBean.getUsage().getUsed();
+ }
+
+ /**
+ * Returns maximum memory usage deviation from {@code expectedMemoryUsage}
+ * given the max allowed relative deviation equal to
+ * {@code relativeDeviation}.
+ *
+ * Note that value returned by this method is aligned according to
+ * memory measurement precision for this heap space.
+ */
+ public long getAllowedMemoryUsageDeviation(long expectedMemoryUsage) {
+ long unalignedDeviation = (long) (expectedMemoryUsage *
+ AlignmentHelper.MAX_RELATIVE_DEVIATION);
+ return AlignmentHelper.alignUp(unalignedDeviation,
+ memoryUsageMeasurementPrecision);
+ }
+
+ /**
+ * Returns amount of memory that will be occupied by an object with size
+ * {@code objectSize} in this heap space.
+ */
+ public long getObjectSizeInThisSpace(long objectSize) {
+ objectSize = Math.max(objectSize, minObjectSizeInThisSpace);
+
+ long alignedObjectSize = AlignmentHelper.alignUp(objectSize,
+ objectAlignmentInThisRegion);
+ long sizeDiff = alignedObjectSize - objectSize;
+
+ // If there is not enough space to fit padding object, then object will
+ // be aligned to {@code 2 * objectAlignmentInThisRegion}.
+ if (sizeDiff >= AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES
+ && sizeDiff < AlignmentHelper.MIN_OBJECT_SIZE) {
+ alignedObjectSize += AlignmentHelper.MIN_OBJECT_SIZE;
+ alignedObjectSize = AlignmentHelper.alignUp(alignedObjectSize,
+ objectAlignmentInThisRegion);
+ }
+
+ return alignedObjectSize;
+ }
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(String.format("AlignmentHelper for memory pool '%s':%n",
+ poolMXBean.getName()));
+ builder.append(String.format("Memory usage measurement precision: %d%n",
+ memoryUsageMeasurementPrecision));
+ builder.append(String.format("Min object size in this space: %d%n",
+ minObjectSizeInThisSpace));
+ builder.append(String.format("Object alignment in this space: %d%n",
+ objectAlignmentInThisRegion));
+
+ return builder.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/SurvivorAlignmentTestMain.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,416 @@
+/*
+ * 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.
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.Asserts;
+import com.sun.management.ThreadMXBean;
+import sun.hotspot.WhiteBox;
+import sun.misc.Unsafe;
+
+/**
+ * Main class for tests on {@code SurvivorAlignmentInBytes} option.
+ *
+ * Typical usage is to obtain instance using fromArgs method, allocate objects
+ * and verify that actual memory usage in tested heap space is close to
+ * expected.
+ */
+public class SurvivorAlignmentTestMain {
+ enum HeapSpace {
+ EDEN,
+ SURVIVOR,
+ TENURED
+ }
+
+ public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+ public static final long MAX_TENURING_THRESHOLD = Optional.ofNullable(
+ SurvivorAlignmentTestMain.WHITE_BOX.getIntxVMFlag(
+ "MaxTenuringThreshold")).orElse(15L);
+
+ /**
+ * Regexp used to parse memory size params, like 2G, 34m or 15k.
+ */
+ private static final Pattern SIZE_REGEX
+ = Pattern.compile("(?<size>[0-9]+)(?<multiplier>[GMKgmk])?");
+
+ // Names of different heap spaces.
+ private static final String DEF_NEW_EDEN = "Eden Space";
+ private static final String DEF_NEW_SURVIVOR = "Survivor Space";
+ private static final String PAR_NEW_EDEN = "Par Eden Space";
+ private static final String PAR_NEW_SURVIVOR = "Par Survivor Space";
+ private static final String PS_EDEN = "PS Eden Space";
+ private static final String PS_SURVIVOR = "PS Survivor Space";
+ private static final String G1_EDEN = "G1 Eden Space";
+ private static final String G1_SURVIVOR = "G1 Survivor Space";
+ private static final String SERIAL_TENURED = "Tenured Gen";
+ private static final String CMS_TENURED = "CMS Old Gen";
+ private static final String PS_TENURED = "PS Old Gen";
+ private static final String G1_TENURED = "G1 Old Gen";
+
+ private static final long G1_HEAP_REGION_SIZE = Optional.ofNullable(
+ SurvivorAlignmentTestMain.WHITE_BOX.getUintxVMFlag(
+ "G1HeapRegionSize")).orElse(-1L);
+
+ /**
+ * Min size of free chunk in CMS generation.
+ * An object allocated in CMS generation will at least occupy this amount
+ * of bytes.
+ */
+ private static final long CMS_MIN_FREE_CHUNK_SIZE
+ = 3L * Unsafe.ADDRESS_SIZE;
+
+ private static final AlignmentHelper EDEN_SPACE_HELPER;
+ private static final AlignmentHelper SURVIVOR_SPACE_HELPER;
+ private static final AlignmentHelper TENURED_SPACE_HELPER;
+ /**
+ * Amount of memory that should be filled during a test run.
+ */
+ private final long memoryToFill;
+ /**
+ * The size of an objects that will be allocated during a test run.
+ */
+ private final long objectSize;
+ /**
+ * Amount of memory that will be actually occupied by an object in eden
+ * space.
+ */
+ private final long actualObjectSize;
+ /**
+ * Storage for allocated objects.
+ */
+ private final Object[] garbage;
+ /**
+ * Heap space whose memory usage is a subject of assertions during the test
+ * run.
+ */
+ private final HeapSpace testedSpace;
+
+ private long[] baselinedThreadMemoryUsage = null;
+ private long[] threadIds = null;
+
+ /**
+ * Initialize {@code EDEN_SPACE_HELPER}, {@code SURVIVOR_SPACE_HELPER} and
+ * {@code TENURED_SPACE_HELPER} to represent heap spaces in use.
+ *
+ * Note that regardless to GC object's alignment in survivor space is
+ * expected to be equal to {@code SurvivorAlignmentInBytes} value and
+ * alignment in other spaces is expected to be equal to
+ * {@code ObjectAlignmentInBytes} value.
+ *
+ * In CMS generation we can't allocate less then {@code MinFreeChunk} value,
+ * for other CGs we expect that object of size {@code MIN_OBJECT_SIZE}
+ * could be allocated as it is (of course, its size could be aligned
+ * according to alignment value used in a particular space).
+ *
+ * For G1 GC MXBeans could report memory usage only with region size
+ * precision (if an object allocated in some G1 heap region, then all region
+ * will claimed as used), so for G1's spaces precision is equal to
+ * {@code G1HeapRegionSize} value.
+ */
+ static {
+ AlignmentHelper edenHelper = null;
+ AlignmentHelper survivorHelper = null;
+ AlignmentHelper tenuredHelper = null;
+ for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
+ switch (pool.getName()) {
+ case SurvivorAlignmentTestMain.DEF_NEW_EDEN:
+ case SurvivorAlignmentTestMain.PAR_NEW_EDEN:
+ case SurvivorAlignmentTestMain.PS_EDEN:
+ Asserts.assertNull(edenHelper,
+ "Only one bean for eden space is expected.");
+ edenHelper = new AlignmentHelper(
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.MIN_OBJECT_SIZE, pool);
+ break;
+ case SurvivorAlignmentTestMain.G1_EDEN:
+ Asserts.assertNull(edenHelper,
+ "Only one bean for eden space is expected.");
+ edenHelper = new AlignmentHelper(
+ SurvivorAlignmentTestMain.G1_HEAP_REGION_SIZE,
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.MIN_OBJECT_SIZE, pool);
+ break;
+ case SurvivorAlignmentTestMain.DEF_NEW_SURVIVOR:
+ case SurvivorAlignmentTestMain.PAR_NEW_SURVIVOR:
+ case SurvivorAlignmentTestMain.PS_SURVIVOR:
+ Asserts.assertNull(survivorHelper,
+ "Only one bean for survivor space is expected.");
+ survivorHelper = new AlignmentHelper(
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.SURVIVOR_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.MIN_OBJECT_SIZE, pool);
+ break;
+ case SurvivorAlignmentTestMain.G1_SURVIVOR:
+ Asserts.assertNull(survivorHelper,
+ "Only one bean for survivor space is expected.");
+ survivorHelper = new AlignmentHelper(
+ SurvivorAlignmentTestMain.G1_HEAP_REGION_SIZE,
+ AlignmentHelper.SURVIVOR_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.MIN_OBJECT_SIZE, pool);
+ break;
+ case SurvivorAlignmentTestMain.SERIAL_TENURED:
+ case SurvivorAlignmentTestMain.PS_TENURED:
+ case SurvivorAlignmentTestMain.G1_TENURED:
+ Asserts.assertNull(tenuredHelper,
+ "Only one bean for tenured space is expected.");
+ tenuredHelper = new AlignmentHelper(
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.MIN_OBJECT_SIZE, pool);
+ break;
+ case SurvivorAlignmentTestMain.CMS_TENURED:
+ Asserts.assertNull(tenuredHelper,
+ "Only one bean for tenured space is expected.");
+ tenuredHelper = new AlignmentHelper(
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
+ SurvivorAlignmentTestMain.CMS_MIN_FREE_CHUNK_SIZE,
+ pool);
+ break;
+ }
+ }
+ EDEN_SPACE_HELPER = Objects.requireNonNull(edenHelper,
+ "AlignmentHelper for eden space should be initialized.");
+ SURVIVOR_SPACE_HELPER = Objects.requireNonNull(survivorHelper,
+ "AlignmentHelper for survivor space should be initialized.");
+ TENURED_SPACE_HELPER = Objects.requireNonNull(tenuredHelper,
+ "AlignmentHelper for tenured space should be initialized.");
+ }
+ /**
+ * Returns an SurvivorAlignmentTestMain instance constructed using CLI
+ * options.
+ *
+ * Following options are expected:
+ * <ul>
+ * <li>memoryToFill</li>
+ * <li>objectSize</li>
+ * </ul>
+ *
+ * Both argument may contain multiplier suffix k, m or g.
+ */
+ public static SurvivorAlignmentTestMain fromArgs(String[] args) {
+ Asserts.assertEQ(args.length, 3, "Expected three arguments: "
+ + "memory size, object size and tested heap space name.");
+
+ long memoryToFill = parseSize(args[0]);
+ long objectSize = Math.max(parseSize(args[1]),
+ AlignmentHelper.MIN_ARRAY_SIZE);
+ HeapSpace testedSpace = HeapSpace.valueOf(args[2]);
+
+ return new SurvivorAlignmentTestMain(memoryToFill, objectSize,
+ testedSpace);
+ }
+
+ /**
+ * Returns a value parsed from a string with format
+ * <integer><multiplier>.
+ */
+ private static long parseSize(String sizeString) {
+ Matcher matcher = SIZE_REGEX.matcher(sizeString);
+ Asserts.assertTrue(matcher.matches(),
+ "sizeString should have following format \"[0-9]+([MBK])?\"");
+ long size = Long.valueOf(matcher.group("size"));
+
+ if (matcher.group("multiplier") != null) {
+ long K = 1024L;
+ // fall through multipliers
+ switch (matcher.group("multiplier").toLowerCase()) {
+ case "g":
+ size *= K;
+ case "m":
+ size *= K;
+ case "k":
+ size *= K;
+ }
+ }
+ return size;
+ }
+
+ private SurvivorAlignmentTestMain(long memoryToFill, long objectSize,
+ HeapSpace testedSpace) {
+ this.objectSize = objectSize;
+ this.memoryToFill = memoryToFill;
+ this.testedSpace = testedSpace;
+
+ AlignmentHelper helper = SurvivorAlignmentTestMain.EDEN_SPACE_HELPER;
+
+ this.actualObjectSize = helper.getObjectSizeInThisSpace(
+ this.objectSize);
+ int arrayLength = helper.getObjectsCount(memoryToFill, this.objectSize);
+ garbage = new Object[arrayLength];
+ }
+
+ /**
+ * Allocate byte arrays to fill {@code memoryToFill} memory.
+ */
+ public void allocate() {
+ int byteArrayLength = Math.max((int) (objectSize
+ - Unsafe.ARRAY_BYTE_BASE_OFFSET), 0);
+
+ for (int i = 0; i < garbage.length; i++) {
+ garbage[i] = new byte[byteArrayLength];
+ }
+ }
+
+ /**
+ * Release memory occupied after {@code allocate} call.
+ */
+ public void release() {
+ for (int i = 0; i < garbage.length; i++) {
+ garbage[i] = null;
+ }
+ }
+
+ /**
+ * Returns expected amount of memory occupied in a {@code heapSpace} by
+ * objects referenced from {@code garbage} array.
+ */
+ public long getExpectedMemoryUsage() {
+ AlignmentHelper alignmentHelper = getAlignmentHelper(testedSpace);
+ return alignmentHelper.getExpectedMemoryUsage(objectSize,
+ garbage.length);
+ }
+
+ /**
+ * Verifies that memory usage in a {@code heapSpace} deviates from
+ * {@code expectedUsage} for no more than {@code MAX_RELATIVE_DEVIATION}.
+ */
+ public void verifyMemoryUsage(long expectedUsage) {
+ AlignmentHelper alignmentHelper = getAlignmentHelper(testedSpace);
+
+ long actualMemoryUsage = alignmentHelper.getActualMemoryUsage();
+ boolean otherThreadsAllocatedMemory = areOtherThreadsAllocatedMemory();
+
+ long memoryUsageDiff = Math.abs(actualMemoryUsage - expectedUsage);
+ long maxAllowedUsageDiff
+ = alignmentHelper.getAllowedMemoryUsageDeviation(expectedUsage);
+
+ System.out.println("Verifying memory usage in space: " + testedSpace);
+ System.out.println("Allocated objects count: " + garbage.length);
+ System.out.println("Desired object size: " + objectSize);
+ System.out.println("Actual object size: " + actualObjectSize);
+ System.out.println("Expected object size in space: "
+ + alignmentHelper.getObjectSizeInThisSpace(objectSize));
+ System.out.println("Expected memory usage: " + expectedUsage);
+ System.out.println("Actual memory usage: " + actualMemoryUsage);
+ System.out.println("Memory usage diff: " + memoryUsageDiff);
+ System.out.println("Max allowed usage diff: " + maxAllowedUsageDiff);
+
+ if (memoryUsageDiff > maxAllowedUsageDiff
+ && otherThreadsAllocatedMemory) {
+ System.out.println("Memory usage diff is incorrect, but it seems "
+ + "like someone else allocated objects");
+ return;
+ }
+
+ Asserts.assertLTE(memoryUsageDiff, maxAllowedUsageDiff,
+ "Actual memory usage should not deviate from expected for " +
+ "more then " + maxAllowedUsageDiff);
+ }
+
+ /**
+ * Baselines amount of memory allocated by each thread.
+ */
+ public void baselineMemoryAllocation() {
+ ThreadMXBean bean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
+ threadIds = bean.getAllThreadIds();
+ baselinedThreadMemoryUsage = bean.getThreadAllocatedBytes(threadIds);
+ }
+
+ /**
+ * Checks if threads other then the current thread were allocating objects
+ * after baselinedThreadMemoryUsage call.
+ *
+ * If baselinedThreadMemoryUsage was not called, then this method will return
+ * {@code false}.
+ */
+ public boolean areOtherThreadsAllocatedMemory() {
+ if (baselinedThreadMemoryUsage == null) {
+ return false;
+ }
+
+ ThreadMXBean bean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
+ long currentMemoryAllocation[]
+ = bean.getThreadAllocatedBytes(threadIds);
+ boolean otherThreadsAllocatedMemory = false;
+
+ System.out.println("Verifying amount of memory allocated by threads:");
+ for (int i = 0; i < threadIds.length; i++) {
+ System.out.format("Thread %d%nbaseline allocation: %d"
+ + "%ncurrent allocation:%d%n", threadIds[i],
+ baselinedThreadMemoryUsage[i], currentMemoryAllocation[i]);
+ System.out.println(bean.getThreadInfo(threadIds[i]));
+
+ long bytesAllocated = Math.abs(currentMemoryAllocation[i]
+ - baselinedThreadMemoryUsage[i]);
+ if (bytesAllocated > 0
+ && threadIds[i] != Thread.currentThread().getId()) {
+ otherThreadsAllocatedMemory = true;
+ }
+ }
+
+ return otherThreadsAllocatedMemory;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(String.format("SurvivorAlignmentTestMain info:%n"));
+ builder.append(String.format("Desired object size: %d%n", objectSize));
+ builder.append(String.format("Memory to fill: %d%n", memoryToFill));
+ builder.append(String.format("Objects to be allocated: %d%n",
+ garbage.length));
+
+ builder.append(String.format("Alignment helpers to be used: %n"));
+ for (HeapSpace heapSpace: HeapSpace.values()) {
+ builder.append(String.format("For space %s:%n%s%n", heapSpace,
+ getAlignmentHelper(heapSpace)));
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Returns {@code AlignmentHelper} for a space {@code heapSpace}.
+ */
+ public static AlignmentHelper getAlignmentHelper(HeapSpace heapSpace) {
+ switch (heapSpace) {
+ case EDEN:
+ return SurvivorAlignmentTestMain.EDEN_SPACE_HELPER;
+ case SURVIVOR:
+ return SurvivorAlignmentTestMain.SURVIVOR_SPACE_HELPER;
+ case TENURED:
+ return SurvivorAlignmentTestMain.TENURED_SPACE_HELPER;
+ default:
+ throw new Error("Unexpected heap space: " + heapSpace);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,84 @@
+/*
+ * 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 8031323
+ * @summary Verify that object's alignment in eden space is not affected by
+ * SurvivorAlignmentInBytes option.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestAllocationInEden SurvivorAlignmentTestMain AlignmentHelper
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB
+ * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent
+ * TestAllocationInEden 10m 9 EDEN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB
+ * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent
+ * TestAllocationInEden 10m 47 EDEN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB
+ * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent
+ * TestAllocationInEden 10m 9 EDEN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB
+ * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent
+ * TestAllocationInEden 10m 87 EDEN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB
+ * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent
+ * TestAllocationInEden 10m 9 EDEN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB
+ * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent
+ * TestAllocationInEden 10m 147 EDEN
+ */
+public class TestAllocationInEden {
+ public static void main(String args[]) {
+ SurvivorAlignmentTestMain test
+ = SurvivorAlignmentTestMain.fromArgs(args);
+ System.out.println(test);
+
+ long expectedMemoryUsage = test.getExpectedMemoryUsage();
+ test.baselineMemoryAllocation();
+ System.gc();
+
+ test.allocate();
+
+ test.verifyMemoryUsage(expectedMemoryUsage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,96 @@
+/*
+ * 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 8031323
+ * @summary Verify that objects promoted from eden space to tenured space during
+ * full GC are not aligned to SurvivorAlignmentInBytes value.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestPromotionFromEdenToTenured SurvivorAlignmentTestMain
+ * AlignmentHelper
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32
+ * TestPromotionFromEdenToTenured 10m 9 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32
+ * TestPromotionFromEdenToTenured 10m 47 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64
+ * TestPromotionFromEdenToTenured 10m 9 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64
+ * TestPromotionFromEdenToTenured 10m 87 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:OldSize=32M -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128
+ * TestPromotionFromEdenToTenured 10m 9 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128
+ * TestPromotionFromEdenToTenured 10m 147 TENURED
+ */
+public class TestPromotionFromEdenToTenured {
+ public static void main(String args[]) {
+ SurvivorAlignmentTestMain test
+ = SurvivorAlignmentTestMain.fromArgs(args);
+ System.out.println(test);
+
+ long expectedMemoryUsage = test.getExpectedMemoryUsage();
+ test.baselineMemoryAllocation();
+ System.gc();
+ // increase expected usage by current old gen usage
+ expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper(
+ SurvivorAlignmentTestMain.HeapSpace.TENURED)
+ .getActualMemoryUsage();
+
+ test.allocate();
+ System.gc();
+
+ test.verifyMemoryUsage(expectedMemoryUsage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,101 @@
+/*
+ * 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 8031323
+ * @summary Verify that objects promoted from survivor space to tenured space
+ * during full GC are not aligned to SurvivorAlignmentInBytes value.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestPromotionFromSurvivorToTenuredAfterFullGC
+ * SurvivorAlignmentTestMain AlignmentHelper
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32
+ * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32
+ * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 47
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m
+ * -XX:OldSize=32m -XX:InitialHeapSize=232m
+ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64
+ * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64
+ * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 87
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m
+ * -XX:OldSize=32M -XX:InitialHeapSize=288m
+ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128
+ * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32m -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128
+ * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 147
+ * TENURED
+ */
+public class TestPromotionFromSurvivorToTenuredAfterFullGC {
+ public static void main(String args[]) {
+ SurvivorAlignmentTestMain test
+ = SurvivorAlignmentTestMain.fromArgs(args);
+ System.out.println(test);
+
+ long expectedMemoryUsage = test.getExpectedMemoryUsage();
+ test.baselineMemoryAllocation();
+ System.gc();
+ // increase expected usage by current old gen usage
+ expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper(
+ SurvivorAlignmentTestMain.HeapSpace.TENURED)
+ .getActualMemoryUsage();
+
+ test.allocate();
+ SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
+ System.gc();
+
+ test.verifyMemoryUsage(expectedMemoryUsage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,106 @@
+/*
+ * 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 8031323
+ * @summary Verify that objects promoted from survivor space to tenured space
+ * when their age exceeded tenuring threshold are not aligned to
+ * SurvivorAlignmentInBytes value.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestPromotionFromSurvivorToTenuredAfterMinorGC
+ * SurvivorAlignmentTestMain AlignmentHelper
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32M -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32
+ * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32M -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32
+ * TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 47
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m
+ * -XX:OldSize=32M -XX:InitialHeapSize=232m
+ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64
+ * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32M -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64
+ * TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 87
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m
+ * -XX:OldSize=32M -XX:InitialHeapSize=288m
+ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128
+ * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9
+ * TENURED
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:OldSize=32M -XX:SurvivorRatio=1
+ * -XX:-ExplicitGCInvokesConcurrent
+ * -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128
+ * TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 147
+ * TENURED
+ */
+public class TestPromotionFromSurvivorToTenuredAfterMinorGC {
+ public static void main(String args[]) throws Exception {
+ SurvivorAlignmentTestMain test
+ = SurvivorAlignmentTestMain.fromArgs(args);
+ System.out.println(test);
+
+ long expectedMemoryUsage = test.getExpectedMemoryUsage();
+ test.baselineMemoryAllocation();
+ SurvivorAlignmentTestMain.WHITE_BOX.fullGC();
+ // increase expected usage by current old gen usage
+ expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper(
+ SurvivorAlignmentTestMain.HeapSpace.TENURED)
+ .getActualMemoryUsage();
+
+ test.allocate();
+ for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD;
+ i++) {
+ SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
+ }
+
+ test.verifyMemoryUsage(expectedMemoryUsage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,85 @@
+/*
+ * 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 8031323
+ * @summary Verify that objects promoted from eden space to survivor space after
+ * minor GC are aligned to SurvivorAlignmentInBytes.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestPromotionToSurvivor
+ * SurvivorAlignmentTestMain AlignmentHelper
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m
+ * -XX:-ExplicitGCInvokesConcurrent
+ * TestPromotionToSurvivor 10m 9 SURVIVOR
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m
+ * TestPromotionToSurvivor 20m 47 SURVIVOR
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m
+ * -XX:-ExplicitGCInvokesConcurrent
+ * TestPromotionToSurvivor 8m 9 SURVIVOR
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m
+ * -XX:-ExplicitGCInvokesConcurrent
+ * TestPromotionToSurvivor 20m 87 SURVIVOR
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=32m
+ * -XX:InitialHeapSize=288m -XX:-ExplicitGCInvokesConcurrent
+ * TestPromotionToSurvivor 10m 9 SURVIVOR
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
+ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
+ * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m
+ * -XX:-ExplicitGCInvokesConcurrent
+ * TestPromotionToSurvivor 20m 147 SURVIVOR
+ */
+public class TestPromotionToSurvivor {
+ public static void main(String args[]) {
+ SurvivorAlignmentTestMain test
+ = SurvivorAlignmentTestMain.fromArgs(args);
+ System.out.println(test);
+
+ long expectedUsage = test.getExpectedMemoryUsage();
+ test.baselineMemoryAllocation();
+ SurvivorAlignmentTestMain.WHITE_BOX.fullGC();
+
+ test.allocate();
+ SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
+
+ test.verifyMemoryUsage(expectedUsage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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 TestConMarkCycleWB
+ * @bug 8065579
+ * @requires vm.gc=="null" | vm.gc=="G1"
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.WhiteBox TestConcMarkCycleWB
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC TestConcMarkCycleWB
+ * @summary Verifies that ConcurrentMarking-related WB works properly
+ */
+import static com.oracle.java.testlibrary.Asserts.assertFalse;
+import static com.oracle.java.testlibrary.Asserts.assertTrue;
+import sun.hotspot.WhiteBox;
+
+public class TestConcMarkCycleWB {
+
+ public static void main(String[] args) throws Exception {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+
+ wb.youngGC();
+ assertTrue(wb.g1StartConcMarkCycle());
+ while (wb.g1InConcurrentMark()) {
+ Thread.sleep(5);
+ }
+
+ wb.fullGC();
+ assertTrue(wb.g1StartConcMarkCycle());
+ while (wb.g1InConcurrentMark()) {
+ Thread.sleep(5);
+ }
+ assertTrue(wb.g1StartConcMarkCycle());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/memory/ReadVMPageSize.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,46 @@
+/*
+ * 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
+ * @summary Using WhiteBox to get VM page size
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ReadVMPageSize
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ReadVMPageSize
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class ReadVMPageSize {
+ public static void main(String args[]) throws Exception {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+ int pageSize = wb.getVMPageSize();
+ if (pageSize < 0) {
+ throw new Exception("pageSize < 0");
+ } else {
+ System.out.println("Page size = " + pageSize);
+ }
+ }
+}
--- a/hotspot/test/serviceability/ParserTest.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/serviceability/ParserTest.java Thu Dec 11 12:28:03 2014 -0800
@@ -48,6 +48,7 @@
testBool();
testQuotes();
testMemorySize();
+ testSingleLetterArg();
}
public static void main(String... args) throws Exception {
@@ -99,7 +100,7 @@
false, "0");
DiagnosticCommand[] args = {arg};
- wb.parseCommandLine(name + "=10", args);
+ wb.parseCommandLine(name + "=10", ',', args);
parse(name, "10", name + "=10", args);
parse(name, "-5", name + "=-5", args);
@@ -149,6 +150,15 @@
parse(name, "Recording 1", "\"" + name + "\"" + "=\"Recording 1\",arg=value", args);
}
+ public void testSingleLetterArg() throws Exception {
+ DiagnosticCommand[] args = new DiagnosticCommand[]{
+ new DiagnosticCommand("flag", "desc", DiagnosticArgumentType.STRING, true, false, null),
+ new DiagnosticCommand("value", "desc", DiagnosticArgumentType.STRING, true, false, null)
+ };
+ parse("flag", "flag", "flag v", ' ', args);
+ parse("value", "v", "flag v", ' ', args);
+ }
+
public void testMemorySize() throws Exception {
String name = "name";
String defaultValue = "1024";
@@ -176,9 +186,13 @@
public void parse(String searchName, String expectedValue,
String cmdLine, DiagnosticCommand[] argumentTypes) throws Exception {
+ parse(searchName, expectedValue, cmdLine, ',', argumentTypes);
+ }
+ public void parse(String searchName, String expectedValue,
+ String cmdLine, char delim, DiagnosticCommand[] argumentTypes) throws Exception {
//parseCommandLine will return an object array that looks like
//{<name of parsed object>, <of parsed object> ... }
- Object[] res = wb.parseCommandLine(cmdLine, argumentTypes);
+ Object[] res = wb.parseCommandLine(cmdLine, delim, argumentTypes);
for (int i = 0; i < res.length-1; i+=2) {
String parsedName = (String) res[i];
if (searchName.equals(parsedName)) {
@@ -196,8 +210,11 @@
}
private void shouldFail(String argument, DiagnosticCommand[] argumentTypes) throws Exception {
+ shouldFail(argument, ',', argumentTypes);
+ }
+ private void shouldFail(String argument, char delim, DiagnosticCommand[] argumentTypes) throws Exception {
try {
- wb.parseCommandLine(argument, argumentTypes);
+ wb.parseCommandLine(argument, delim, argumentTypes);
throw new Exception("Parser accepted argument: " + argument);
} catch (IllegalArgumentException e) {
//expected
--- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Thu Dec 11 12:28:03 2014 -0800
@@ -34,6 +34,7 @@
import com.oracle.java.testlibrary.JDKToolLauncher;
import com.oracle.java.testlibrary.OutputBuffer;
+import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.ProcessTools;
import java.io.File;
@@ -48,6 +49,10 @@
System.out.println(Ã);
try {
+ if (!Platform.shouldSAAttach()) {
+ System.out.println("SA attach not expected to work - test skipped.");
+ return;
+ }
int pid = ProcessTools.getProcessId();
JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
.addToolArg("-F")
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Asserts.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Asserts.java Thu Dec 11 12:28:03 2014 -0800
@@ -68,8 +68,7 @@
* @see #assertLessThan(T, T, String)
*/
public static <T extends Comparable<T>> void assertLessThan(T lhs, T rhs) {
- String msg = "Expected that " + format(lhs) + " < " + format(rhs);
- assertLessThan(lhs, rhs, msg);
+ assertLessThan(lhs, rhs, null);
}
/**
@@ -81,7 +80,7 @@
* @throws RuntimeException if the assertion isn't valid.
*/
public static <T extends Comparable<T>>void assertLessThan(T lhs, T rhs, String msg) {
- assertTrue(compare(lhs, rhs, msg) < 0, msg);
+ assertTrue(compare(lhs, rhs, msg) < 0, getMessage(lhs, rhs, "<", msg));
}
/**
@@ -108,8 +107,7 @@
* @see #assertLessThanOrEqual(T, T, String)
*/
public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs) {
- String msg = "Expected that " + format(lhs) + " <= " + format(rhs);
- assertLessThanOrEqual(lhs, rhs, msg);
+ assertLessThanOrEqual(lhs, rhs, null);
}
/**
@@ -121,7 +119,7 @@
* @throws RuntimeException if the assertion isn't valid.
*/
public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs, String msg) {
- assertTrue(compare(lhs, rhs, msg) <= 0, msg);
+ assertTrue(compare(lhs, rhs, msg) <= 0, getMessage(lhs, rhs, "<=", msg));
}
/**
@@ -148,8 +146,7 @@
* @see #assertEquals(T, T, String)
*/
public static void assertEquals(Object lhs, Object rhs) {
- String msg = "Expected " + format(lhs) + " to equal " + format(rhs);
- assertEquals(lhs, rhs, msg);
+ assertEquals(lhs, rhs, null);
}
/**
@@ -166,7 +163,7 @@
error(msg);
}
} else {
- assertTrue(lhs.equals(rhs), msg);
+ assertTrue(lhs.equals(rhs), getMessage(lhs, rhs, "==", msg));
}
}
@@ -194,8 +191,7 @@
* @see #assertGreaterThanOrEqual(T, T, String)
*/
public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs) {
- String msg = "Expected that " + format(lhs) + " >= " + format(rhs);
- assertGreaterThanOrEqual(lhs, rhs, msg);
+ assertGreaterThanOrEqual(lhs, rhs, null);
}
/**
@@ -207,7 +203,7 @@
* @throws RuntimeException if the assertion isn't valid.
*/
public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs, String msg) {
- assertTrue(compare(lhs, rhs, msg) >= 0, msg);
+ assertTrue(compare(lhs, rhs, msg) >= 0, getMessage(lhs, rhs, ">=", msg));
}
/**
@@ -234,8 +230,7 @@
* @see #assertGreaterThan(T, T, String)
*/
public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs) {
- String msg = "Expected that " + format(lhs) + " > " + format(rhs);
- assertGreaterThan(lhs, rhs, msg);
+ assertGreaterThan(lhs, rhs, null);
}
/**
@@ -247,7 +242,7 @@
* @throws RuntimeException if the assertion isn't valid.
*/
public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs, String msg) {
- assertTrue(compare(lhs, rhs, msg) > 0, msg);
+ assertTrue(compare(lhs, rhs, msg) > 0, getMessage(lhs, rhs, ">", msg));
}
/**
@@ -274,8 +269,7 @@
* @see #assertNotEquals(T, T, String)
*/
public static void assertNotEquals(Object lhs, Object rhs) {
- String msg = "Expected " + format(lhs) + " to not equal " + format(rhs);
- assertNotEquals(lhs, rhs, msg);
+ assertNotEquals(lhs, rhs, null);
}
/**
@@ -292,7 +286,7 @@
error(msg);
}
} else {
- assertFalse(lhs.equals(rhs), msg);
+ assertFalse(lhs.equals(rhs), getMessage(lhs, rhs,"!=", msg));
}
}
@@ -450,4 +444,8 @@
throw new RuntimeException(msg);
}
+ private static String getMessage(Object lhs, Object rhs, String op, String msg) {
+ return (msg == null ? "" : msg + " ") + "(assert failed: " + format(lhs) + " " + op + " " + format(rhs) + ")";
+ }
}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.util.Objects;
+
+/**
+ * Class which runs another Runnable in infinite loop with certain pauses
+ * between cycles.
+ */
+public class InfiniteLoop implements Runnable {
+ private final Runnable target;
+ private final long mills;
+
+
+ /**
+ * @param target a target to run in a loop
+ * @param mills the length of pause time in milliseconds
+ * @throws NullPointerException if target is null
+ * @throws IllegalArgumentException if the value of millis is negative
+ */
+ public InfiniteLoop(Runnable target, long mills) {
+ Objects.requireNonNull(target);
+ if (mills < 0) {
+ throw new IllegalArgumentException("mills < 0");
+ }
+ this.target = target;
+ this.mills = mills;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (true) {
+ target.run();
+ Thread.sleep(mills);
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new Error(e);
+ }
+ }
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Thu Dec 11 12:28:03 2014 -0800
@@ -23,6 +23,9 @@
package com.oracle.java.testlibrary;
+import java.util.regex.Pattern;
+import com.oracle.java.testlibrary.Utils;
+
public class Platform {
private static final String osName = System.getProperty("os.name");
private static final String dataModel = System.getProperty("sun.arch.data.model");
@@ -30,6 +33,7 @@
private static final String javaVersion = System.getProperty("java.version");
private static final String osArch = System.getProperty("os.arch");
private static final String vmName = System.getProperty("java.vm.name");
+ private static final String userName = System.getProperty("user.name");
public static boolean isClient() {
return vmName.endsWith(" Client VM");
@@ -94,33 +98,87 @@
// Returns true for sparc and sparcv9.
public static boolean isSparc() {
- return isArch("sparc");
+ return isArch("sparc.*");
}
public static boolean isARM() {
- return isArch("arm");
+ return isArch("arm.*");
}
public static boolean isPPC() {
- return isArch("ppc");
+ return isArch("ppc.*");
}
public static boolean isX86() {
- // On Linux it's 'i386', Windows 'x86'
- return (isArch("i386") || isArch("x86"));
+ // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
+ return isArch("(i386)|(x86(?!_64))");
}
public static boolean isX64() {
// On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
- return (isArch("amd64") || isArch("x86_64"));
+ return isArch("(amd64)|(x86_64)");
}
- private static boolean isArch(String archname) {
- return osArch.toLowerCase().startsWith(archname.toLowerCase());
+ private static boolean isArch(String archnameRE) {
+ return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
+ .matcher(osArch)
+ .matches();
}
public static String getOsArch() {
return osArch;
}
+ /**
+ * Return a boolean for whether we expect to be able to attach
+ * the SA to our own processes on this system.
+ */
+ public static boolean shouldSAAttach() throws Exception {
+
+ if (isLinux()) {
+ return canPtraceAttachLinux();
+ } else if (isOSX()) {
+ return canAttachOSX();
+ } else {
+ // Other platforms expected to work:
+ return true;
+ }
+ }
+
+ /**
+ * On Linux, first check the SELinux boolean "deny_ptrace" and return false
+ * as we expect to be denied if that is "1". Then expect permission to attach
+ * if we are root, so return true. Then return false for an expected denial
+ * if "ptrace_scope" is 1, and true otherwise.
+ */
+ public static boolean canPtraceAttachLinux() throws Exception {
+
+ // SELinux deny_ptrace:
+ String deny_ptrace = Utils.fileAsString("/sys/fs/selinux/booleans/deny_ptrace");
+ if (deny_ptrace != null && deny_ptrace.contains("1")) {
+ // ptrace will be denied:
+ return false;
+ }
+
+ if (userName.equals("root")) {
+ return true;
+ }
+
+ // ptrace_scope:
+ String ptrace_scope = Utils.fileAsString("/proc/sys/kernel/yama/ptrace_scope");
+ if (ptrace_scope != null && ptrace_scope.contains("1")) {
+ // ptrace will be denied:
+ return false;
+ }
+
+ // Otherwise expect to be permitted:
+ return true;
+ }
+
+ /**
+ * On OSX, expect permission to attach only if we are root.
+ */
+ public static boolean canAttachOSX() throws Exception {
+ return userName.equals("root");
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/TimeLimitedRunner.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.util.Objects;
+import java.util.concurrent.Callable;
+
+/**
+ * Auxiliary class to run target w/ given timeout.
+ */
+public class TimeLimitedRunner implements Callable<Void> {
+ private final long stoptime;
+ private final long timeout;
+ private final double factor;
+ private final Callable<Boolean> target;
+
+ /**
+ * @param timeout a timeout. zero means no time limitation
+ * @param factor a multiplier used to estimate next iteration time
+ * @param target a target to run
+ * @throws NullPointerException if target is null
+ * @throws IllegalArgumentException if timeout is negative or
+ factor isn't positive
+ */
+ public TimeLimitedRunner(long timeout, double factor,
+ Callable<Boolean> target) {
+ Objects.requireNonNull(target, "target must not be null");
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout[" + timeout + "] < 0");
+ }
+ if (factor <= 0d) {
+ throw new IllegalArgumentException("factor[" + factor + "] <= 0");
+ }
+ this.stoptime = System.currentTimeMillis() + timeout;
+ this.timeout = timeout;
+ this.factor = factor;
+ this.target = target;
+ }
+
+ /**
+ * Runs @{linkplan target} while it returns true and timeout isn't exceeded
+ */
+ @Override
+ public Void call() throws Exception {
+ long maxDuration = 0L;
+ long iterStart = System.currentTimeMillis();
+ if (timeout != 0 && iterStart > stoptime) {
+ return null;
+ }
+ while (target.call()) {
+ if (timeout != 0) {
+ long iterDuration = System.currentTimeMillis() - iterStart;
+ maxDuration = Math.max(maxDuration, iterDuration);
+ iterStart = System.currentTimeMillis();
+ if (iterStart + (maxDuration * factor) > stoptime) {
+ System.out.println("Not enough time to continue execution. "
+ + "Interrupted.");
+ break;
+ }
+ }
+ }
+ return null;
+ }
+
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Thu Dec 11 12:28:03 2014 -0800
@@ -314,6 +314,35 @@
}
/**
+ * Return the contents of the named file as a single String,
+ * or null if not found.
+ * @param filename name of the file to read
+ * @return String contents of file, or null if file not found.
+ */
+ public static String fileAsString(String filename) {
+ StringBuilder result = new StringBuilder();
+ try {
+ File file = new File(filename);
+ if (file.exists()) {
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+ while (true) {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ result.append(line).append("\n");
+ }
+ } else {
+ // Does not exist:
+ return null;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result.toString();
+ }
+
+ /**
* @return Unsafe instance.
*/
public static synchronized Unsafe getUnsafe() {
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Thu Dec 11 12:28:03 2014 -0800
@@ -74,6 +74,7 @@
// Memory
public native long getObjectAddress(Object o);
public native int getHeapOopSize();
+ public native int getVMPageSize();
public native boolean isObjectInOldGen(Object o);
public native long getObjectSize(Object o);
@@ -93,7 +94,7 @@
public native boolean g1IsHumongous(Object o);
public native long g1NumFreeRegions();
public native int g1RegionSize();
- public native Object[] parseCommandLine(String commandline, DiagnosticCommand[] args);
+ public native Object[] parseCommandLine(String commandline, char delim, DiagnosticCommand[] args);
// NMT
public native long NMTMalloc(long size);
@@ -153,7 +154,14 @@
public native Object[] getNMethod(Executable method, boolean isOsr);
public native long allocateCodeBlob(int size, int type);
public native void freeCodeBlob(long addr);
- public native void forceNMethodSweep();
+ public void forceNMethodSweep() {
+ try {
+ forceNMethodSweep0().join();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ public native Thread forceNMethodSweep0();
public native Object[] getCodeHeapEntries(int type);
public native int getCompilationActivityMode();
public native Object[] getCodeBlob(long addr);
@@ -168,12 +176,16 @@
public native long incMetaspaceCapacityUntilGC(long increment);
public native long metaspaceCapacityUntilGC();
- // force Young GC
+ // Force Young GC
public native void youngGC();
- // force Full GC
+ // Force Full GC
public native void fullGC();
+ // Method tries to start concurrent mark cycle.
+ // It returns false if CM Thread is always in concurrent cycle.
+ public native boolean g1StartConcMarkCycle();
+
// Tests on ReservedSpace/VirtualSpace classes
public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations);
public native void runMemoryUnitTests();
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java Thu Dec 11 11:44:00 2014 -0800
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java Thu Dec 11 12:28:03 2014 -0800
@@ -34,14 +34,21 @@
private DiagnosticArgumentType type;
private boolean mandatory;
private String defaultValue;
+ private boolean argument;
public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
boolean mandatory, String defaultValue) {
+ this(name, desc, type, false, mandatory, defaultValue);
+ }
+
+ public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
+ boolean argument, boolean mandatory, String defaultValue) {
this.name = name;
this.desc = desc;
this.type = type;
this.mandatory = mandatory;
this.defaultValue = defaultValue;
+ this.argument = argument;
}
public String getName() {
@@ -60,6 +67,10 @@
return mandatory;
}
+ public boolean isArgument() {
+ return argument;
+ }
+
public String getDefaultValue() {
return defaultValue;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Dec 11 12:28:03 2014 -0800
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Platform;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @test
+ * @summary Verify that for each group of mutually exclusive predicates defined
+ * in com.oracle.java.testlibrary.Platform one and only one predicate
+ * evaluates to true.
+ * @library /testlibrary
+ * @run main TestMutuallyExclusivePlatformPredicates
+ */
+public class TestMutuallyExclusivePlatformPredicates {
+ private static enum MethodGroup {
+ ARCH("isARM", "isPPC", "isSparc", "isX86", "isX64"),
+ BITNESS("is32bit", "is64bit"),
+ OS("isLinux", "isSolaris", "isWindows", "isOSX"),
+ VM_TYPE("isClient", "isServer", "isGraal", "isMinimal"),
+ IGNORED("isEmbedded", "isDebugBuild");
+
+ public final List<String> methodNames;
+
+ private MethodGroup(String... methodNames) {
+ this.methodNames = Collections.unmodifiableList(
+ Arrays.asList(methodNames));
+ }
+ }
+
+ public static void main(String args[]) {
+ EnumSet<MethodGroup> notIgnoredMethodGroups
+ = EnumSet.complementOf(EnumSet.of(MethodGroup.IGNORED));
+
+ notIgnoredMethodGroups.forEach(
+ TestMutuallyExclusivePlatformPredicates::verifyPredicates);
+
+ TestMutuallyExclusivePlatformPredicates.verifyCoverage();
+ }
+
+ /**
+ * Verifies that one and only one predicate method defined in
+ * {@link com.oracle.java.testlibrary.Platform}, whose name included into
+ * methodGroup will return {@code true}.
+ * @param methodGroup The group of methods that should be tested.
+ */
+ private static void verifyPredicates(MethodGroup methodGroup) {
+ System.out.println("Verifying method group: " + methodGroup.name());
+ long truePredicatesCount = methodGroup.methodNames.stream()
+ .filter(TestMutuallyExclusivePlatformPredicates
+ ::evaluatePredicate)
+ .count();
+
+ Asserts.assertEQ(truePredicatesCount, 1L, String.format(
+ "Only one predicate from group %s should be evaluated to true "
+ + "(Actually %d predicates were evaluated to true).",
+ methodGroup.name(), truePredicatesCount));
+ }
+
+ /**
+ * Verifies that all predicates defined in
+ * {@link com.oracle.java.testlibrary.Platform} were either tested or
+ * explicitly ignored.
+ */
+ private static void verifyCoverage() {
+ Set<String> allMethods = new HashSet<>();
+ for (MethodGroup group : MethodGroup.values()) {
+ allMethods.addAll(group.methodNames);
+ }
+
+ for (Method m : Platform.class.getMethods()) {
+ if (m.getParameterCount() == 0
+ && m.getReturnType() == boolean.class) {
+ Asserts.assertTrue(allMethods.contains(m.getName()),
+ "All Platform's methods with signature '():Z' should "
+ + "be tested ");
+ }
+ }
+ }
+
+ /**
+ * Evaluates predicate method with name {@code name} defined in
+ * {@link com.oracle.java.testlibrary.Platform}.
+ *
+ * @param name The name of a predicate to be evaluated.
+ * @return evaluated predicate's value.
+ * @throws java.lang.Error if predicate is not defined or could not be
+ * evaluated.
+ */
+ private static boolean evaluatePredicate(String name) {
+ try {
+ System.out.printf("Trying to evaluate predicate with name %s%n",
+ name);
+ boolean value
+ = (Boolean) Platform.class.getMethod(name).invoke(null);
+ System.out.printf("Predicate evaluated to: %s%n", value);
+ return value;
+ } catch (NoSuchMethodException e) {
+ throw new Error("Predicate with name " + name
+ + " is not defined in " + Platform.class.getName(), e);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new Error("Unable to evaluate predicate " + name, e);
+ }
+ }
+}