--- a/.hgtags-top-repo Thu Feb 16 13:01:32 2012 -0800
+++ b/.hgtags-top-repo Wed Jul 05 18:03:08 2017 +0200
@@ -147,3 +147,4 @@
60d6f64a86b1e511169d264727f6d51415978df0 jdk8-b23
1a5f1d6b98d6827cdb529a4abe6e52a886d944f4 jdk8-b24
221a378e06a326f45e5d89e2123cd6323e0181d1 jdk8-b25
+2accafff224ae39caf5f532c305251ba624bf2c0 jdk8-b26
--- a/corba/.hgtags Thu Feb 16 13:01:32 2012 -0800
+++ b/corba/.hgtags Wed Jul 05 18:03:08 2017 +0200
@@ -147,3 +147,4 @@
5218eb256658442b62b05295aafa5b5f35252972 jdk8-b23
b98f0e6dddf987df565029a1f58417fc1844c3f3 jdk8-b24
e45d6b406d5f91ff5256a5c82456ab1e7eb8becd jdk8-b25
+79f709a099f40c08f76567fa6d813f9009a69826 jdk8-b26
--- a/hotspot/.hgtags Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/.hgtags Wed Jul 05 18:03:08 2017 +0200
@@ -220,3 +220,7 @@
64b46f975ab82948c1e021e17775ff4fab8bc40e hs23-b14
9ad8feb5afbddec46d3cfe29fb5f73c2e99d5a43 jdk8-b25
d71e662fe03741b6de498ca2077220148405a978 hs23-b15
+fd3060701216a11c0df6dcd053c6fd7c2b17a42c jdk8-b26
+f92a171cf0071ca6c3fa8231d7d570377f8b2f4d hs23-b16
+f92a171cf0071ca6c3fa8231d7d570377f8b2f4d hs23-b16
+931e5f39e365a0d550d79148ff87a7f9e864d2e1 hs23-b16
--- a/hotspot/agent/src/os/linux/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/agent/src/os/linux/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2012, 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
@@ -40,7 +40,7 @@
LIBS = -lthread_db
-CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
+CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) -D_FILE_OFFSET_BITS=64
LIBSA = $(ARCH)/libsaproc.so
--- a/hotspot/agent/src/os/linux/libproc_impl.c Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/agent/src/os/linux/libproc_impl.c Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,10 +50,6 @@
char alt_path[PATH_MAX + 1];
init_alt_root();
- fd = open(name, O_RDONLY);
- if (fd >= 0) {
- return fd;
- }
if (alt_root_len > 0) {
strcpy(alt_path, alt_root);
@@ -73,6 +69,11 @@
return fd;
}
}
+ } else {
+ fd = open(name, O_RDONLY);
+ if (fd >= 0) {
+ return fd;
+ }
}
return -1;
--- a/hotspot/make/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -402,7 +402,6 @@
$(install-file)
else
$(EXPORT_INCLUDE_DIR)/jfr.h:
-
endif
# Doc files (jvmti.html)
@@ -448,12 +447,18 @@
($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
test_jdk:
- ifneq ($(ZERO_BUILD), true)
ifeq ($(ARCH_DATA_MODEL), 32)
- $(JDK_IMAGE_DIR)/bin/java -client -version
+ ifneq ($(ZERO_BUILD), true)
+ $(JDK_IMAGE_DIR)/bin/java -d32 -client -Xinternalversion
+ $(JDK_IMAGE_DIR)/bin/java -d32 -client -version
+ endif
+ $(JDK_IMAGE_DIR)/bin/java -d32 -server -Xinternalversion
+ $(JDK_IMAGE_DIR)/bin/java -d32 -server -version
endif
- endif
- $(JDK_IMAGE_DIR)/bin/java -server -version
+ ifeq ($(ARCH_DATA_MODEL), 64)
+ $(JDK_IMAGE_DIR)/bin/java -d64 -server -Xinternalversion
+ $(JDK_IMAGE_DIR)/bin/java -d64 -server -version
+ endif
copy_product_jdk::
$(RM) -r $(JDK_IMAGE_DIR)
@@ -545,6 +550,7 @@
OUTPUTDIR.desc = Output directory, default is build/<osname>
BOOTDIR.desc = JDK used to compile agent java source and test with
JDK_IMPORT_PATH.desc = Promoted JDK to copy for 'create_jdk'
+JDK_IMAGE_DIR.desc = Directory to place JDK to copy
EXPORT_PATH.desc = Directory to place files to export for JDK build
# Make variables to print out (description and value)
@@ -553,6 +559,7 @@
OUTPUTDIR \
BOOTDIR \
JDK_IMPORT_PATH \
+ JDK_IMAGE_DIR \
EXPORT_PATH
# Make variables that should refer to directories that exist
--- a/hotspot/make/bsd/makefiles/defs.make Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/bsd/makefiles/defs.make Wed Jul 05 18:03:08 2017 +0200
@@ -191,6 +191,9 @@
# Set universal image dir
JDK_IMAGE_DIR=$(OUTPUTDIR)/jdk-universal$(EXPORT_SUBDIR)
+ ifneq ($(ALT_JDK_IMAGE_DIR),)
+ JDK_IMAGE_DIR=$(ALT_JDK_IMAGE_DIR)
+ endif
# Binaries to 'universalize' if built
UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX)
--- a/hotspot/make/bsd/makefiles/top.make Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/bsd/makefiles/top.make Wed Jul 05 18:03:08 2017 +0200
@@ -124,8 +124,8 @@
@$(UpdatePCH)
@$(MAKE) -f vm.make $(MFLAGS-adjusted)
-install: the_vm
- @$(MAKE) -f vm.make install
+install gamma: the_vm
+ @$(MAKE) -f vm.make $@
# next rules support "make foo.[ois]"
--- a/hotspot/make/defs.make Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/defs.make Wed Jul 05 18:03:08 2017 +0200
@@ -193,6 +193,9 @@
# Default jdk image if one is created for you with create_jdk
JDK_IMAGE_DIR=$(OUTPUTDIR)/jdk-$(PLATFORM)
+ifneq ($(ALT_JDK_IMAGE_DIR),)
+ JDK_IMAGE_DIR=$(ALT_JDK_IMAGE_DIR)
+endif
# The platform dependent defs.make defines platform specific variable such
# as ARCH, EXPORT_LIST etc. We must place the include here after BOOTDIR is defined.
--- a/hotspot/make/hotspot_version Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/hotspot_version Wed Jul 05 18:03:08 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=23
HS_MINOR_VER=0
-HS_BUILD_NUMBER=15
+HS_BUILD_NUMBER=16
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/jprt.properties Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/jprt.properties Wed Jul 05 18:03:08 2017 +0200
@@ -38,7 +38,9 @@
# This tells jprt what default release we want to build
-jprt.tools.default.release=${jprt.submit.release}
+jprt.hotspot.default.release=jdk7
+
+jprt.tools.default.release=${jprt.submit.option.release?${jprt.submit.option.release}:${jprt.hotspot.default.release}}
# Disable syncing the source after builds and tests are done.
@@ -52,126 +54,46 @@
# Define the Solaris platforms we want for the various releases
jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk7b107=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk7temp=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk6=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6perf=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u10=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u14=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u18=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u20=solaris_sparc_5.8
-jprt.my.solaris.sparc.ejdk7=${jprt.my.solaris.sparc.jdk7}
-jprt.my.solaris.sparc.ejdk6=${jprt.my.solaris.sparc.jdk6}
jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk7b107=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk7temp=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk6=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6perf=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u10=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u14=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u18=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u20=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.ejdk7=${jprt.my.solaris.sparcv9.jdk7}
-jprt.my.solaris.sparcv9.ejdk6=${jprt.my.solaris.sparcv9.jdk6}
jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
jprt.my.solaris.i586.jdk8=solaris_i586_5.10
jprt.my.solaris.i586.jdk7=solaris_i586_5.10
-jprt.my.solaris.i586.jdk7b107=solaris_i586_5.10
-jprt.my.solaris.i586.jdk7temp=solaris_i586_5.10
-jprt.my.solaris.i586.jdk6=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6perf=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u10=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u14=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u18=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u20=solaris_i586_5.8
-jprt.my.solaris.i586.ejdk7=${jprt.my.solaris.i586.jdk7}
-jprt.my.solaris.i586.ejdk6=${jprt.my.solaris.i586.jdk6}
jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
jprt.my.solaris.x64.jdk8=solaris_x64_5.10
jprt.my.solaris.x64.jdk7=solaris_x64_5.10
-jprt.my.solaris.x64.jdk7b107=solaris_x64_5.10
-jprt.my.solaris.x64.jdk7temp=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6perf=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u10=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u14=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u18=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u20=solaris_x64_5.10
-jprt.my.solaris.x64.ejdk7=${jprt.my.solaris.x64.jdk7}
-jprt.my.solaris.x64.ejdk6=${jprt.my.solaris.x64.jdk6}
jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
jprt.my.linux.i586.jdk8=linux_i586_2.6
jprt.my.linux.i586.jdk7=linux_i586_2.6
-jprt.my.linux.i586.jdk7b107=linux_i586_2.6
-jprt.my.linux.i586.jdk7temp=linux_i586_2.6
-jprt.my.linux.i586.jdk6=linux_i586_2.4
-jprt.my.linux.i586.jdk6perf=linux_i586_2.4
-jprt.my.linux.i586.jdk6u10=linux_i586_2.4
-jprt.my.linux.i586.jdk6u14=linux_i586_2.4
-jprt.my.linux.i586.jdk6u18=linux_i586_2.4
-jprt.my.linux.i586.jdk6u20=linux_i586_2.4
-jprt.my.linux.i586.ejdk7=linux_i586_2.6
-jprt.my.linux.i586.ejdk6=linux_i586_2.6
jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
jprt.my.linux.x64.jdk8=linux_x64_2.6
jprt.my.linux.x64.jdk7=linux_x64_2.6
-jprt.my.linux.x64.jdk7b107=linux_x64_2.6
-jprt.my.linux.x64.jdk7temp=linux_x64_2.6
-jprt.my.linux.x64.jdk6=linux_x64_2.4
-jprt.my.linux.x64.jdk6perf=linux_x64_2.4
-jprt.my.linux.x64.jdk6u10=linux_x64_2.4
-jprt.my.linux.x64.jdk6u14=linux_x64_2.4
-jprt.my.linux.x64.jdk6u18=linux_x64_2.4
-jprt.my.linux.x64.jdk6u20=linux_x64_2.4
-jprt.my.linux.x64.ejdk7=${jprt.my.linux.x64.jdk7}
-jprt.my.linux.x64.ejdk6=${jprt.my.linux.x64.jdk6}
jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
jprt.my.linux.ppc.jdk8=linux_ppc_2.6
jprt.my.linux.ppc.jdk7=linux_ppc_2.6
-jprt.my.linux.ppc.jdk7b107=linux_ppc_2.6
-jprt.my.linux.ppc.jdk7temp=linux_ppc_2.6
-jprt.my.linux.ppc.ejdk6=linux_ppc_2.6
-jprt.my.linux.ppc.ejdk7=linux_ppc_2.6
jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
jprt.my.linux.ppcv2.jdk8=linux_ppcv2_2.6
jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.jdk7b107=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.jdk7temp=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.ejdk6=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.ejdk7=linux_ppcv2_2.6
jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
jprt.my.linux.ppcsflt.jdk8=linux_ppcsflt_2.6
jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7b107=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7temp=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.ejdk6=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.ejdk7=linux_ppcsflt_2.6
jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7b107=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7temp=linux_armvfp_2.6
-jprt.my.linux.armvfp.ejdk6=linux_armvfp_2.6
-jprt.my.linux.armvfp.ejdk7=linux_armvfp_2.6
jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
-jprt.my.linux.armsflt.jdk7b107=linux_armsflt_2.6
-jprt.my.linux.armsflt.jdk7temp=linux_armsflt_2.6
-jprt.my.linux.armsflt.ejdk6=linux_armsflt_2.6
-jprt.my.linux.armsflt.ejdk7=linux_armsflt_2.6
jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
jprt.my.macosx.x64.jdk8=macosx_x64_10.7
@@ -180,30 +102,10 @@
jprt.my.windows.i586.jdk8=windows_i586_5.1
jprt.my.windows.i586.jdk7=windows_i586_5.1
-jprt.my.windows.i586.jdk7b107=windows_i586_5.0
-jprt.my.windows.i586.jdk7temp=windows_i586_5.0
-jprt.my.windows.i586.jdk6=windows_i586_5.0
-jprt.my.windows.i586.jdk6perf=windows_i586_5.0
-jprt.my.windows.i586.jdk6u10=windows_i586_5.0
-jprt.my.windows.i586.jdk6u14=windows_i586_5.0
-jprt.my.windows.i586.jdk6u18=windows_i586_5.0
-jprt.my.windows.i586.jdk6u20=windows_i586_5.0
-jprt.my.windows.i586.ejdk7=${jprt.my.windows.i586.jdk7}
-jprt.my.windows.i586.ejdk6=${jprt.my.windows.i586.jdk6}
jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
jprt.my.windows.x64.jdk8=windows_x64_5.2
jprt.my.windows.x64.jdk7=windows_x64_5.2
-jprt.my.windows.x64.jdk7b107=windows_x64_5.2
-jprt.my.windows.x64.jdk7temp=windows_x64_5.2
-jprt.my.windows.x64.jdk6=windows_x64_5.2
-jprt.my.windows.x64.jdk6perf=windows_x64_5.2
-jprt.my.windows.x64.jdk6u10=windows_x64_5.2
-jprt.my.windows.x64.jdk6u14=windows_x64_5.2
-jprt.my.windows.x64.jdk6u18=windows_x64_5.2
-jprt.my.windows.x64.jdk6u20=windows_x64_5.2
-jprt.my.windows.x64.ejdk7=${jprt.my.windows.x64.jdk7}
-jprt.my.windows.x64.ejdk6=${jprt.my.windows.x64.jdk6}
jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
# Standard list of jprt build targets for this source tree
@@ -539,16 +441,6 @@
jprt.test.targets.jdk8=${jprt.test.targets.standard}
jprt.test.targets.jdk7=${jprt.test.targets.standard}
-jprt.test.targets.jdk7temp=${jprt.test.targets.standard}
-jprt.test.targets.jdk7b105=${jprt.test.targets.standard}
-jprt.test.targets.jdk6=${jprt.test.targets.standard}
-jprt.test.targets.jdk6perf=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u10=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u14=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u18=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u20=${jprt.test.targets.standard}
-jprt.test.targets.ejdk6=${jprt.test.targets.embedded}
-jprt.test.targets.ejdk7=${jprt.test.targets.embedded}
jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
# The default test/Makefile targets that should be run
@@ -593,15 +485,5 @@
jprt.make.rule.test.targets.jdk8=${jprt.make.rule.test.targets.standard}
jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk7temp=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk7b107=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6perf=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u10=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u14=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u18=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u20=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.ejdk6=${jprt.make.rule.test.targets.embedded}
-jprt.make.rule.test.targets.ejdk7=${jprt.make.rule.test.targets.embedded}
jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
--- a/hotspot/make/linux/makefiles/saproc.make Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/linux/makefiles/saproc.make Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,7 @@
fi
@echo Making SA debugger back-end...
$(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \
+ -D_FILE_OFFSET_BITS=64 \
$(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
-I$(SASRCDIR) \
-I$(GENERATED) \
--- a/hotspot/make/linux/makefiles/top.make Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/linux/makefiles/top.make Wed Jul 05 18:03:08 2017 +0200
@@ -115,8 +115,8 @@
@$(UpdatePCH)
@$(MAKE) -f vm.make $(MFLAGS-adjusted)
-install: the_vm
- @$(MAKE) -f vm.make install
+install gamma: the_vm
+ @$(MAKE) -f vm.make $@
# next rules support "make foo.[ois]"
--- a/hotspot/make/solaris/makefiles/top.make Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/make/solaris/makefiles/top.make Wed Jul 05 18:03:08 2017 +0200
@@ -107,8 +107,8 @@
the_vm: vm_build_preliminaries $(adjust-mflags)
@$(MAKE) -f vm.make $(MFLAGS-adjusted)
-install: the_vm
- @$(MAKE) -f vm.make install
+install gamma: the_vm
+ @$(MAKE) -f vm.make $@
# next rules support "make foo.[oi]"
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -56,14 +56,15 @@
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
define_pd_global(intx, ThreadStackSize, 1024);
define_pd_global(intx, VMThreadStackSize, 1024);
+define_pd_global(intx, StackShadowPages, 10 DEBUG_ONLY(+1));
#else
define_pd_global(intx, ThreadStackSize, 512);
define_pd_global(intx, VMThreadStackSize, 512);
+define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
#endif
define_pd_global(intx, StackYellowPages, 2);
define_pd_global(intx, StackRedPages, 1);
-define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -3431,6 +3431,9 @@
ResourceMark rm;
// setup code generation tools
int pad = VerifyThread ? 512 : 0;// Extra slop space for more verify code
+ if (UseStackBanging) {
+ pad += StackShadowPages*16 + 32;
+ }
#ifdef _LP64
CodeBuffer buffer("deopt_blob", 2100+pad, 512);
#else
@@ -3650,6 +3653,9 @@
ResourceMark rm;
// setup code generation tools
int pad = VerifyThread ? 512 : 0;
+ if (UseStackBanging) {
+ pad += StackShadowPages*16 + 32;
+ }
#ifdef _LP64
CodeBuffer buffer("uncommon_trap_blob", 2700+pad, 512);
#else
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -236,6 +236,16 @@
}
}
+// Force generation of a 4 byte immediate value even if it fits into 8bit
+void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) {
+ assert(isByte(op1) && isByte(op2), "wrong opcode");
+ assert((op1 & 0x01) == 1, "should be 32bit operation");
+ assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
+ emit_byte(op1);
+ emit_byte(op2 | encode(dst));
+ emit_long(imm32);
+}
+
// immediate-to-memory forms
void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) {
assert((op1 & 0x01) == 1, "should be 32bit operation");
@@ -939,6 +949,7 @@
}
void Assembler::addr_nop_4() {
+ assert(UseAddressNop, "no CPU support");
// 4 bytes: NOP DWORD PTR [EAX+0]
emit_byte(0x0F);
emit_byte(0x1F);
@@ -947,6 +958,7 @@
}
void Assembler::addr_nop_5() {
+ assert(UseAddressNop, "no CPU support");
// 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset
emit_byte(0x0F);
emit_byte(0x1F);
@@ -956,6 +968,7 @@
}
void Assembler::addr_nop_7() {
+ assert(UseAddressNop, "no CPU support");
// 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset
emit_byte(0x0F);
emit_byte(0x1F);
@@ -964,6 +977,7 @@
}
void Assembler::addr_nop_8() {
+ assert(UseAddressNop, "no CPU support");
// 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset
emit_byte(0x0F);
emit_byte(0x1F);
@@ -2769,6 +2783,12 @@
emit_arith(0x81, 0xE8, dst, imm32);
}
+// Force generation of a 4 byte immediate value even if it fits into 8bit
+void Assembler::subl_imm32(Register dst, int32_t imm32) {
+ prefix(dst);
+ emit_arith_imm32(0x81, 0xE8, dst, imm32);
+}
+
void Assembler::subl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
@@ -4760,6 +4780,12 @@
emit_arith(0x81, 0xE8, dst, imm32);
}
+// Force generation of a 4 byte immediate value even if it fits into 8bit
+void Assembler::subq_imm32(Register dst, int32_t imm32) {
+ (void) prefixq_and_encode(dst->encoding());
+ emit_arith_imm32(0x81, 0xE8, dst, imm32);
+}
+
void Assembler::subq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
@@ -5101,15 +5127,6 @@
}
}
-void MacroAssembler::fat_nop() {
- // A 5 byte nop that is safe for patching (see patch_verified_entry)
- emit_byte(0x26); // es:
- emit_byte(0x2e); // cs:
- emit_byte(0x64); // fs:
- emit_byte(0x65); // gs:
- emit_byte(0x90);
-}
-
void MacroAssembler::jC2(Register tmp, Label& L) {
// set parity bit if FPU flag C2 is set (via rax)
save_rax(tmp);
@@ -5704,17 +5721,6 @@
/* else */ { subq(dst, value) ; return; }
}
-void MacroAssembler::fat_nop() {
- // A 5 byte nop that is safe for patching (see patch_verified_entry)
- // Recommened sequence from 'Software Optimization Guide for the AMD
- // Hammer Processor'
- emit_byte(0x66);
- emit_byte(0x66);
- emit_byte(0x90);
- emit_byte(0x66);
- emit_byte(0x90);
-}
-
void MacroAssembler::incrementq(Register reg, int value) {
if (value == min_jint) { addq(reg, value); return; }
if (value < 0) { decrementq(reg, -value); return; }
@@ -6766,6 +6772,19 @@
mov(rbp, rsp);
}
+// A 5 byte nop that is safe for patching (see patch_verified_entry)
+void MacroAssembler::fat_nop() {
+ if (UseAddressNop) {
+ addr_nop_5();
+ } else {
+ emit_byte(0x26); // es:
+ emit_byte(0x2e); // cs:
+ emit_byte(0x64); // fs:
+ emit_byte(0x65); // gs:
+ emit_byte(0x90);
+ }
+}
+
void MacroAssembler::fcmp(Register tmp) {
fcmp(tmp, 1, true, true);
}
@@ -7825,6 +7844,11 @@
LP64_ONLY(subq(dst, imm32)) NOT_LP64(subl(dst, imm32));
}
+// Force generation of a 4 byte immediate value even if it fits into 8bit
+void MacroAssembler::subptr_imm32(Register dst, int32_t imm32) {
+ LP64_ONLY(subq_imm32(dst, imm32)) NOT_LP64(subl_imm32(dst, imm32));
+}
+
void MacroAssembler::subptr(Register dst, Register src) {
LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src));
}
@@ -9292,6 +9316,80 @@
}
#endif // _LP64
+
+// C2 compiled method's prolog code.
+void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) {
+
+ // WARNING: Initial instruction MUST be 5 bytes or longer so that
+ // NativeJump::patch_verified_entry will be able to patch out the entry
+ // code safely. The push to verify stack depth is ok at 5 bytes,
+ // the frame allocation can be either 3 or 6 bytes. So if we don't do
+ // stack bang then we must use the 6 byte frame allocation even if
+ // we have no frame. :-(
+
+ assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
+ // Remove word for return addr
+ framesize -= wordSize;
+
+ // Calls to C2R adapters often do not accept exceptional returns.
+ // We require that their callers must bang for them. But be careful, because
+ // some VM calls (such as call site linkage) can use several kilobytes of
+ // stack. But the stack safety zone should account for that.
+ // See bugs 4446381, 4468289, 4497237.
+ if (stack_bang) {
+ generate_stack_overflow_check(framesize);
+
+ // We always push rbp, so that on return to interpreter rbp, will be
+ // restored correctly and we can correct the stack.
+ push(rbp);
+ // Remove word for ebp
+ framesize -= wordSize;
+
+ // Create frame
+ if (framesize) {
+ subptr(rsp, framesize);
+ }
+ } else {
+ // Create frame (force generation of a 4 byte immediate value)
+ subptr_imm32(rsp, framesize);
+
+ // Save RBP register now.
+ framesize -= wordSize;
+ movptr(Address(rsp, framesize), rbp);
+ }
+
+ if (VerifyStackAtCalls) { // Majik cookie to verify stack depth
+ framesize -= wordSize;
+ movptr(Address(rsp, framesize), (int32_t)0xbadb100d);
+ }
+
+#ifndef _LP64
+ // If method sets FPU control word do it now
+ if (fp_mode_24b) {
+ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
+ }
+ if (UseSSE >= 2 && VerifyFPU) {
+ verify_FPU(0, "FPU stack must be clean on entry");
+ }
+#endif
+
+#ifdef ASSERT
+ if (VerifyStackAtCalls) {
+ Label L;
+ push(rax);
+ mov(rax, rsp);
+ andptr(rax, StackAlignmentInBytes-1);
+ cmpptr(rax, StackAlignmentInBytes-wordSize);
+ pop(rax);
+ jcc(Assembler::equal, L);
+ stop("Stack is not properly aligned!");
+ bind(L);
+ }
+#endif
+
+}
+
+
// IndexOf for constant substrings with size >= 8 chars
// which don't need to be loaded through stack.
void MacroAssembler::string_indexofC8(Register str1, Register str2,
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -667,6 +667,8 @@
void emit_arith_b(int op1, int op2, Register dst, int imm8);
void emit_arith(int op1, int op2, Register dst, int32_t imm32);
+ // Force generation of a 4 byte immediate value even if it fits into 8bit
+ void emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32);
// only 32bit??
void emit_arith(int op1, int op2, Register dst, jobject obj);
void emit_arith(int op1, int op2, Register dst, Register src);
@@ -1526,6 +1528,9 @@
void subq(Register dst, Address src);
void subq(Register dst, Register src);
+ // Force generation of a 4 byte immediate value even if it fits into 8bit
+ void subl_imm32(Register dst, int32_t imm32);
+ void subq_imm32(Register dst, int32_t imm32);
// Subtract Scalar Double-Precision Floating-Point Values
void subsd(XMMRegister dst, Address src);
@@ -1763,8 +1768,8 @@
// Alignment
void align(int modulus);
- // Misc
- void fat_nop(); // 5 byte nop
+ // A 5 byte nop that is safe for patching (see patch_verified_entry)
+ void fat_nop();
// Stack frame creation/removal
void enter();
@@ -2275,6 +2280,8 @@
void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); }
void subptr(Register dst, int32_t src);
+ // Force generation of a 4 byte immediate value even if it fits into 8bit
+ void subptr_imm32(Register dst, int32_t src);
void subptr(Register dst, Register src);
void subptr(Register dst, RegisterOrConstant src) {
if (src.is_constant()) subptr(dst, (int) src.as_constant());
@@ -2566,6 +2573,9 @@
void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
+ // C2 compiled method's prolog code.
+ void verified_entry(int framesize, bool stack_bang, bool fp_mode_24b);
+
// IndexOf strings.
// Small strings are loaded through stack if they cross page boundary.
void string_indexof(Register str1, Register str2,
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -381,6 +381,16 @@
void C1_MacroAssembler::verified_entry() {
+ if (C1Breakpoint || VerifyFPU || !UseStackBanging) {
+ // Verified Entry first instruction should be 5 bytes long for correct
+ // patching by patch_verified_entry().
+ //
+ // C1Breakpoint and VerifyFPU have one byte first instruction.
+ // Also first instruction will be one byte "push(rbp)" if stack banging
+ // code is not generated (see build_frame() above).
+ // For all these cases generate long instruction first.
+ fat_nop();
+ }
if (C1Breakpoint)int3();
// build frame
verify_FPU(0, "method_entry");
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -60,9 +60,9 @@
#ifdef AMD64
// Very large C++ stack frames using solaris-amd64 optimized builds
// due to lack of optimization caused by C++ compiler bugs
-define_pd_global(intx, StackShadowPages, SOLARIS_ONLY(20) NOT_SOLARIS(6) DEBUG_ONLY(+2));
+define_pd_global(intx, StackShadowPages, NOT_WIN64(20) WIN64_ONLY(6) DEBUG_ONLY(+2));
#else
-define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+5));
+define_pd_global(intx, StackShadowPages, 4 DEBUG_ONLY(+5));
#endif // AMD64
define_pd_global(intx, PreInflateSpin, 10);
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1018,41 +1018,26 @@
void trace_method_handle_stub(const char* adaptername,
oop mh,
intptr_t* saved_regs,
- intptr_t* entry_sp,
- intptr_t* saved_sp,
- intptr_t* saved_bp) {
+ intptr_t* entry_sp) {
// called as a leaf from native code: do not block the JVM!
bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have rcx_mh
+ const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
+ tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT, adaptername, mh_reg_name, mh, entry_sp);
- intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
- intptr_t* base_sp = last_sp;
- typedef MethodHandles::RicochetFrame RicochetFrame;
- RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes());
- if (Universe::heap()->is_in((address) rfp->saved_args_base())) {
- // Probably an interpreter frame.
- base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
- }
- intptr_t mh_reg = (intptr_t)mh;
- const char* mh_reg_name = "rcx_mh";
- if (!has_mh) mh_reg_name = "rcx";
- tty->print_cr("MH %s %s="PTR_FORMAT" sp=("PTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="PTR_FORMAT,
- adaptername, mh_reg_name, mh_reg,
- (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
if (Verbose) {
- tty->print(" reg dump: ");
- int saved_regs_count = (entry_sp-1) - saved_regs;
- // 32 bit: rdi rsi rbp rsp; rbx rdx rcx (*) rax
- int i;
- for (i = 0; i <= saved_regs_count; i++) {
- if (i > 0 && i % 4 == 0 && i != saved_regs_count) {
+ tty->print_cr("Registers:");
+ const int saved_regs_count = RegisterImpl::number_of_registers;
+ for (int i = 0; i < saved_regs_count; i++) {
+ Register r = as_Register(i);
+ // The registers are stored in reverse order on the stack (by pusha).
+ tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[((saved_regs_count - 1) - i)]);
+ if ((i + 1) % 4 == 0) {
tty->cr();
- tty->print(" + dump: ");
+ } else {
+ tty->print(", ");
}
- tty->print(" %d: "PTR_FORMAT, i, saved_regs[i]);
}
tty->cr();
- if (last_sp != saved_sp && last_sp != NULL)
- tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp);
{
// dumping last frame with frame::describe
@@ -1102,14 +1087,7 @@
values.describe(-1, dump_sp, "sp for #1");
}
- // mark saved_sp if seems valid
- if (has_mh) {
- if ((saved_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) {
- values.describe(-1, saved_sp, "*saved_sp");
- }
- }
-
- tty->print_cr(" stack layout:");
+ tty->print_cr("Stack layout:");
values.print(p);
}
if (has_mh)
@@ -1125,16 +1103,12 @@
oopDesc* mh;
intptr_t* saved_regs;
intptr_t* entry_sp;
- intptr_t* saved_sp;
- intptr_t* saved_bp;
};
void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) {
trace_method_handle_stub(args->adaptername,
args->mh,
args->saved_regs,
- args->entry_sp,
- args->saved_sp,
- args->saved_bp);
+ args->entry_sp);
}
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
@@ -1157,20 +1131,18 @@
__ fst_d(Address(rsp, 0));
}
- // incoming state:
+ // Incoming state:
// rcx: method handle
- // r13 or rsi: saved sp
- // To avoid calling convention issues, build a record on the stack and pass the pointer to that instead.
- // Note: fix the increment below if pushing more arguments
- __ push(rbp); // saved_bp
- __ push(saved_last_sp_register()); // saved_sp
+ //
+ // To avoid calling convention issues, build a record on the stack
+ // and pass the pointer to that instead.
__ push(rbp); // entry_sp (with extra align space)
__ push(rbx); // pusha saved_regs
__ push(rcx); // mh
__ push(rcx); // slot for adaptername
__ movptr(Address(rsp, 0), (intptr_t) adaptername);
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp);
- __ increment(rsp, 6 * wordSize); // MethodHandleStubArguments
+ __ increment(rsp, sizeof(MethodHandleStubArguments));
if (UseSSE >= 2) {
__ movdbl(xmm0, Address(rsp, 0));
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -2997,7 +2997,7 @@
// Generate oop map
OopMap* map = new OopMap(framesize, 0);
- oop_maps->add_gc_map(__ pc() - start, map);
+ oop_maps->add_gc_map(the_pc - start, map);
__ reset_last_Java_frame(true, true);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -249,13 +249,18 @@
enum {
// AMD
- CPU_FAMILY_AMD_11H = 17,
+ CPU_FAMILY_AMD_11H = 0x11,
// Intel
CPU_FAMILY_INTEL_CORE = 6,
- CPU_MODEL_NEHALEM_EP = 26,
- CPU_MODEL_WESTMERE_EP = 44,
-// CPU_MODEL_IVYBRIDGE_EP = ??, TODO - get real value
- CPU_MODEL_SANDYBRIDGE_EP = 45
+ CPU_MODEL_NEHALEM = 0x1e,
+ CPU_MODEL_NEHALEM_EP = 0x1a,
+ CPU_MODEL_NEHALEM_EX = 0x2e,
+ CPU_MODEL_WESTMERE = 0x25,
+ CPU_MODEL_WESTMERE_EP = 0x2c,
+ CPU_MODEL_WESTMERE_EX = 0x2f,
+ CPU_MODEL_SANDYBRIDGE = 0x2a,
+ CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
+ CPU_MODEL_IVYBRIDGE_EP = 0x3a
} cpuExtendedFamily;
// cpuid information block. All info derived from executing cpuid with
@@ -325,7 +330,7 @@
uint32_t proc_name_4, proc_name_5, proc_name_6, proc_name_7;
uint32_t proc_name_8, proc_name_9, proc_name_10,proc_name_11;
- // cpuid function 0x80000005 //AMD L1, Intel reserved
+ // cpuid function 0x80000005 // AMD L1, Intel reserved
uint32_t ext_cpuid5_eax; // unused currently
uint32_t ext_cpuid5_ebx; // reserved
ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD)
@@ -547,15 +552,15 @@
static bool is_intel_tsc_synched_at_init() {
if (is_intel_family_core()) {
uint32_t ext_model = extended_cpu_model();
- if (ext_model == CPU_MODEL_NEHALEM_EP ||
- ext_model == CPU_MODEL_WESTMERE_EP ||
-// TODO ext_model == CPU_MODEL_IVYBRIDGE_EP ||
- ext_model == CPU_MODEL_SANDYBRIDGE_EP) {
- // 2-socket invtsc support. EX versions with 4 sockets are not
- // guaranteed to synchronize tscs at initialization via a double
- // handshake. The tscs can be explicitly set in software. Code
- // that uses tsc values must be prepared for them to arbitrarily
- // jump backward or forward.
+ if (ext_model == CPU_MODEL_NEHALEM_EP ||
+ ext_model == CPU_MODEL_WESTMERE_EP ||
+ ext_model == CPU_MODEL_SANDYBRIDGE_EP ||
+ ext_model == CPU_MODEL_IVYBRIDGE_EP) {
+ // <= 2-socket invariant tsc support. EX versions are usually used
+ // in > 2-socket systems and likely don't synchronize tscs at
+ // initialization.
+ // Code that uses tsc values must be prepared for them to arbitrarily
+ // jump forward or backward.
return true;
}
}
--- a/hotspot/src/cpu/x86/vm/x86.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/x86.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2011, 2012, 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
@@ -37,10 +37,87 @@
static address double_signmask() { return (address)double_signmask_pool; }
static address double_signflip() { return (address)double_signflip_pool; }
#endif
+
+#ifndef PRODUCT
+ void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
+ st->print("nop \t# %d bytes pad for loops and calls", _count);
+ }
+#endif
+
+ void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const {
+ MacroAssembler _masm(&cbuf);
+ __ nop(_count);
+ }
+
+ uint MachNopNode::size(PhaseRegAlloc*) const {
+ return _count;
+ }
+
+#ifndef PRODUCT
+ void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const {
+ st->print("# breakpoint");
+ }
+#endif
+
+ void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
+ MacroAssembler _masm(&cbuf);
+ __ int3();
+ }
+
+ uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
+ return MachNode::size(ra_);
+ }
+
+%}
+
+encode %{
+
+ enc_class preserve_SP %{
+ debug_only(int off0 = cbuf.insts_size());
+ MacroAssembler _masm(&cbuf);
+ // RBP is preserved across all calls, even compiled calls.
+ // Use it to preserve RSP in places where the callee might change the SP.
+ __ movptr(rbp_mh_SP_save, rsp);
+ debug_only(int off1 = cbuf.insts_size());
+ assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
+ %}
+
+ enc_class restore_SP %{
+ MacroAssembler _masm(&cbuf);
+ __ movptr(rsp, rbp_mh_SP_save);
+ %}
+
+ enc_class call_epilog %{
+ if (VerifyStackAtCalls) {
+ // Check that stack depth is unchanged: find majik cookie on stack
+ int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
+ MacroAssembler _masm(&cbuf);
+ Label L;
+ __ cmpptr(Address(rsp, framesize), (int32_t)0xbadb100d);
+ __ jccb(Assembler::equal, L);
+ // Die if stack mismatch
+ __ int3();
+ __ bind(L);
+ }
+ %}
+
%}
// INSTRUCTIONS -- Platform independent definitions (same for 32- and 64-bit)
+// ============================================================================
+
+instruct ShouldNotReachHere() %{
+ match(Halt);
+ format %{ "int3\t# ShouldNotReachHere" %}
+ ins_encode %{
+ __ int3();
+ %}
+ ins_pipe(pipe_slow);
+%}
+
+// ============================================================================
+
instruct addF_reg(regF dst, regF src) %{
predicate((UseSSE>=1) && (UseAVX == 0));
match(Set dst (AddF dst src));
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1997, 2012, 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
@@ -341,12 +341,6 @@
return round_to(current_offset, alignment_required()) - current_offset;
}
-#ifndef PRODUCT
-void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
- st->print("INT3");
-}
-#endif
-
// EMIT_RM()
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3);
@@ -550,118 +544,66 @@
//=============================================================================
#ifndef PRODUCT
-void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
+void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
Compile* C = ra_->C;
- if( C->in_24_bit_fp_mode() ) {
- st->print("FLDCW 24 bit fpu control word");
- st->print_cr(""); st->print("\t");
- }
int framesize = C->frame_slots() << LogBytesPerInt;
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
- // Remove two words for return addr and rbp,
- framesize -= 2*wordSize;
-
- // Calls to C2R adapters often do not accept exceptional returns.
- // We require that their callers must bang for them. But be careful, because
- // some VM calls (such as call site linkage) can use several kilobytes of
- // stack. But the stack safety zone should account for that.
- // See bugs 4446381, 4468289, 4497237.
+ // Remove wordSize for return addr which is already pushed.
+ framesize -= wordSize;
+
if (C->need_stack_bang(framesize)) {
- st->print_cr("# stack bang"); st->print("\t");
- }
- st->print_cr("PUSHL EBP"); st->print("\t");
-
- if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
- st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
- st->print_cr(""); st->print("\t");
framesize -= wordSize;
- }
-
- if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
+ st->print("# stack bang");
+ st->print("\n\t");
+ st->print("PUSH EBP\t# Save EBP");
if (framesize) {
- st->print("SUB ESP,%d\t# Create frame",framesize);
+ st->print("\n\t");
+ st->print("SUB ESP, #%d\t# Create frame",framesize);
}
} else {
- st->print("SUB ESP,%d\t# Create frame",framesize);
+ st->print("SUB ESP, #%d\t# Create frame",framesize);
+ st->print("\n\t");
+ framesize -= wordSize;
+ st->print("MOV [ESP + #%d], EBP\t# Save EBP",framesize);
+ }
+
+ if (VerifyStackAtCalls) {
+ st->print("\n\t");
+ framesize -= wordSize;
+ st->print("MOV [ESP + #%d], 0xBADB100D\t# Majik cookie for stack depth check",framesize);
}
+
+ if( C->in_24_bit_fp_mode() ) {
+ st->print("\n\t");
+ st->print("FLDCW \t# load 24 bit fpu control word");
+ }
+ if (UseSSE >= 2 && VerifyFPU) {
+ st->print("\n\t");
+ st->print("# verify FPU stack (must be clean on entry)");
+ }
+
+#ifdef ASSERT
+ if (VerifyStackAtCalls) {
+ st->print("\n\t");
+ st->print("# stack alignment check");
+ }
+#endif
+ st->cr();
}
#endif
void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
Compile* C = ra_->C;
-
- if (UseSSE >= 2 && VerifyFPU) {
- MacroAssembler masm(&cbuf);
- masm.verify_FPU(0, "FPU stack must be clean on entry");
- }
-
- // WARNING: Initial instruction MUST be 5 bytes or longer so that
- // NativeJump::patch_verified_entry will be able to patch out the entry
- // code safely. The fldcw is ok at 6 bytes, the push to verify stack
- // depth is ok at 5 bytes, the frame allocation can be either 3 or
- // 6 bytes. So if we don't do the fldcw or the push then we must
- // use the 6 byte frame allocation even if we have no frame. :-(
- // If method sets FPU control word do it now
- if( C->in_24_bit_fp_mode() ) {
- MacroAssembler masm(&cbuf);
- masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
- }
+ MacroAssembler _masm(&cbuf);
int framesize = C->frame_slots() << LogBytesPerInt;
- assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
- // Remove two words for return addr and rbp,
- framesize -= 2*wordSize;
-
- // Calls to C2R adapters often do not accept exceptional returns.
- // We require that their callers must bang for them. But be careful, because
- // some VM calls (such as call site linkage) can use several kilobytes of
- // stack. But the stack safety zone should account for that.
- // See bugs 4446381, 4468289, 4497237.
- if (C->need_stack_bang(framesize)) {
- MacroAssembler masm(&cbuf);
- masm.generate_stack_overflow_check(framesize);
- }
-
- // We always push rbp, so that on return to interpreter rbp, will be
- // restored correctly and we can correct the stack.
- emit_opcode(cbuf, 0x50 | EBP_enc);
-
- if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
- emit_opcode(cbuf, 0x68); // push 0xbadb100d
- emit_d32(cbuf, 0xbadb100d);
- framesize -= wordSize;
- }
-
- if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
- if (framesize) {
- emit_opcode(cbuf, 0x83); // sub SP,#framesize
- emit_rm(cbuf, 0x3, 0x05, ESP_enc);
- emit_d8(cbuf, framesize);
- }
- } else {
- emit_opcode(cbuf, 0x81); // sub SP,#framesize
- emit_rm(cbuf, 0x3, 0x05, ESP_enc);
- emit_d32(cbuf, framesize);
- }
+
+ __ verified_entry(framesize, C->need_stack_bang(framesize), C->in_24_bit_fp_mode());
+
C->set_frame_complete(cbuf.insts_size());
-#ifdef ASSERT
- if (VerifyStackAtCalls) {
- Label L;
- MacroAssembler masm(&cbuf);
- masm.push(rax);
- masm.mov(rax, rsp);
- masm.andptr(rax, StackAlignmentInBytes-1);
- masm.cmpptr(rax, StackAlignmentInBytes-wordSize);
- masm.pop(rax);
- masm.jcc(Assembler::equal, L);
- masm.stop("Stack is not properly aligned!");
- masm.bind(L);
- }
-#endif
-
if (C->has_mach_constant_base_node()) {
// NOTE: We set the table base offset here because users might be
// emitted before MachConstantBaseNode.
@@ -1169,7 +1111,7 @@
}
#ifndef PRODUCT
-void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
+void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
implementation( NULL, ra_, false, st );
}
#endif
@@ -1182,22 +1124,6 @@
return implementation( NULL, ra_, true, NULL );
}
-//=============================================================================
-#ifndef PRODUCT
-void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
- st->print("NOP \t# %d bytes pad for loops and calls", _count);
-}
-#endif
-
-void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
- MacroAssembler _masm(&cbuf);
- __ nop(_count);
-}
-
-uint MachNopNode::size(PhaseRegAlloc *) const {
- return _count;
-}
-
//=============================================================================
#ifndef PRODUCT
@@ -1883,21 +1809,6 @@
}
%}
- enc_class preserve_SP %{
- debug_only(int off0 = cbuf.insts_size());
- MacroAssembler _masm(&cbuf);
- // RBP is preserved across all calls, even compiled calls.
- // Use it to preserve RSP in places where the callee might change the SP.
- __ movptr(rbp_mh_SP_save, rsp);
- debug_only(int off1 = cbuf.insts_size());
- assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
- %}
-
- enc_class restore_SP %{
- MacroAssembler _masm(&cbuf);
- __ movptr(rsp, rbp_mh_SP_save);
- %}
-
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
// who we intended to call.
@@ -3846,9 +3757,9 @@
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
// Otherwise, it is above the locks and verification slot and alignment word
return_addr(STACK - 1 +
- round_to(1+VerifyStackAtCalls+
- Compile::current()->fixed_slots(),
- (StackAlignmentInBytes/wordSize)));
+ round_to((Compile::current()->in_preserve_stack_slots() +
+ Compile::current()->fixed_slots()),
+ stack_alignment_in_slots()));
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
@@ -13476,6 +13387,25 @@
ins_pipe( ialu_reg_mem );
%}
+
+// ============================================================================
+// This name is KNOWN by the ADLC and cannot be changed.
+// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
+// for this guy.
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
+ match(Set dst (ThreadLocal));
+ effect(DEF dst, KILL cr);
+
+ format %{ "MOV $dst, Thread::current()" %}
+ ins_encode %{
+ Register dstReg = as_Register($dst$$reg);
+ __ get_thread(dstReg);
+ %}
+ ins_pipe( ialu_reg_fat );
+%}
+
+
+
//----------PEEPHOLE RULES-----------------------------------------------------
// These must follow all instruction definitions as they use the names
// defined in the instructions definitions.
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2012, 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
@@ -610,13 +610,6 @@
return round_to(current_offset, alignment_required()) - current_offset;
}
-#ifndef PRODUCT
-void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const
-{
- st->print("INT3");
-}
-#endif
-
// EMIT_RM()
void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
@@ -853,121 +846,53 @@
//=============================================================================
#ifndef PRODUCT
-void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const
-{
+void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
Compile* C = ra_->C;
int framesize = C->frame_slots() << LogBytesPerInt;
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
- // Remove wordSize for return adr already pushed
- // and another for the RBP we are going to save
- framesize -= 2*wordSize;
- bool need_nop = true;
-
- // Calls to C2R adapters often do not accept exceptional returns.
- // We require that their callers must bang for them. But be
- // careful, because some VM calls (such as call site linkage) can
- // use several kilobytes of stack. But the stack safety zone should
- // account for that. See bugs 4446381, 4468289, 4497237.
+ // Remove wordSize for return addr which is already pushed.
+ framesize -= wordSize;
+
if (C->need_stack_bang(framesize)) {
- st->print_cr("# stack bang"); st->print("\t");
- need_nop = false;
+ framesize -= wordSize;
+ st->print("# stack bang");
+ st->print("\n\t");
+ st->print("pushq rbp\t# Save rbp");
+ if (framesize) {
+ st->print("\n\t");
+ st->print("subq rsp, #%d\t# Create frame",framesize);
+ }
+ } else {
+ st->print("subq rsp, #%d\t# Create frame",framesize);
+ st->print("\n\t");
+ framesize -= wordSize;
+ st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
}
- st->print_cr("pushq rbp"); st->print("\t");
if (VerifyStackAtCalls) {
- // Majik cookie to verify stack depth
- st->print_cr("pushq 0xffffffffbadb100d"
- "\t# Majik cookie for stack depth check");
- st->print("\t");
- framesize -= wordSize; // Remove 2 for cookie
- need_nop = false;
+ st->print("\n\t");
+ framesize -= wordSize;
+ st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
+#ifdef ASSERT
+ st->print("\n\t");
+ st->print("# stack alignment check");
+#endif
}
-
- if (framesize) {
- st->print("subq rsp, #%d\t# Create frame", framesize);
- if (framesize < 0x80 && need_nop) {
- st->print("\n\tnop\t# nop for patch_verified_entry");
- }
- }
+ st->cr();
}
#endif
-void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
-{
+void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
Compile* C = ra_->C;
-
- // WARNING: Initial instruction MUST be 5 bytes or longer so that
- // NativeJump::patch_verified_entry will be able to patch out the entry
- // code safely. The fldcw is ok at 6 bytes, the push to verify stack
- // depth is ok at 5 bytes, the frame allocation can be either 3 or
- // 6 bytes. So if we don't do the fldcw or the push then we must
- // use the 6 byte frame allocation even if we have no frame. :-(
- // If method sets FPU control word do it now
+ MacroAssembler _masm(&cbuf);
int framesize = C->frame_slots() << LogBytesPerInt;
- assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
- // Remove wordSize for return adr already pushed
- // and another for the RBP we are going to save
- framesize -= 2*wordSize;
- bool need_nop = true;
-
- // Calls to C2R adapters often do not accept exceptional returns.
- // We require that their callers must bang for them. But be
- // careful, because some VM calls (such as call site linkage) can
- // use several kilobytes of stack. But the stack safety zone should
- // account for that. See bugs 4446381, 4468289, 4497237.
- if (C->need_stack_bang(framesize)) {
- MacroAssembler masm(&cbuf);
- masm.generate_stack_overflow_check(framesize);
- need_nop = false;
- }
-
- // We always push rbp so that on return to interpreter rbp will be
- // restored correctly and we can correct the stack.
- emit_opcode(cbuf, 0x50 | RBP_enc);
-
- if (VerifyStackAtCalls) {
- // Majik cookie to verify stack depth
- emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d
- emit_d32(cbuf, 0xbadb100d);
- framesize -= wordSize; // Remove 2 for cookie
- need_nop = false;
- }
-
- if (framesize) {
- emit_opcode(cbuf, Assembler::REX_W);
- if (framesize < 0x80) {
- emit_opcode(cbuf, 0x83); // sub SP,#framesize
- emit_rm(cbuf, 0x3, 0x05, RSP_enc);
- emit_d8(cbuf, framesize);
- if (need_nop) {
- emit_opcode(cbuf, 0x90); // nop
- }
- } else {
- emit_opcode(cbuf, 0x81); // sub SP,#framesize
- emit_rm(cbuf, 0x3, 0x05, RSP_enc);
- emit_d32(cbuf, framesize);
- }
- }
+
+ __ verified_entry(framesize, C->need_stack_bang(framesize), false);
C->set_frame_complete(cbuf.insts_size());
-#ifdef ASSERT
- if (VerifyStackAtCalls) {
- Label L;
- MacroAssembler masm(&cbuf);
- masm.push(rax);
- masm.mov(rax, rsp);
- masm.andptr(rax, StackAlignmentInBytes-1);
- masm.cmpptr(rax, StackAlignmentInBytes-wordSize);
- masm.pop(rax);
- masm.jcc(Assembler::equal, L);
- masm.stop("Stack is not properly aligned!");
- masm.bind(L);
- }
-#endif
-
if (C->has_mach_constant_base_node()) {
// NOTE: We set the table base offset here because users might be
// emitted before MachConstantBaseNode.
@@ -1598,26 +1523,6 @@
//=============================================================================
#ifndef PRODUCT
-void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const
-{
- st->print("nop \t# %d bytes pad for loops and calls", _count);
-}
-#endif
-
-void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const
-{
- MacroAssembler _masm(&cbuf);
- __ nop(_count);
-}
-
-uint MachNopNode::size(PhaseRegAlloc*) const
-{
- return _count;
-}
-
-
-//=============================================================================
-#ifndef PRODUCT
void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
{
int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
@@ -2323,21 +2228,6 @@
RELOC_DISP32);
%}
- enc_class preserve_SP %{
- debug_only(int off0 = cbuf.insts_size());
- MacroAssembler _masm(&cbuf);
- // RBP is preserved across all calls, even compiled calls.
- // Use it to preserve RSP in places where the callee might change the SP.
- __ movptr(rbp_mh_SP_save, rsp);
- debug_only(int off1 = cbuf.insts_size());
- assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
- %}
-
- enc_class restore_SP %{
- MacroAssembler _masm(&cbuf);
- __ movptr(rsp, rbp_mh_SP_save);
- %}
-
enc_class Java_Static_Call(method meth)
%{
// JAVA STATIC CALL
@@ -3276,9 +3166,9 @@
// Ret Addr is on stack in slot 0 if no locks or verification or alignment.
// Otherwise, it is above the locks and verification slot and alignment word
return_addr(STACK - 2 +
- round_to(2 + 2 * VerifyStackAtCalls +
- Compile::current()->fixed_slots(),
- WordsPerLong * 2));
+ round_to((Compile::current()->in_preserve_stack_slots() +
+ Compile::current()->fixed_slots()),
+ stack_alignment_in_slots()));
// Body of function which returns an integer array locating
// arguments either in registers or in stack slots. Passed an array
@@ -11736,6 +11626,21 @@
%}
+// ============================================================================
+// This name is KNOWN by the ADLC and cannot be changed.
+// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
+// for this guy.
+instruct tlsLoadP(r15_RegP dst) %{
+ match(Set dst (ThreadLocal));
+ effect(DEF dst);
+
+ size(0);
+ format %{ "# TLS is in R15" %}
+ ins_encode( /*empty encoding*/ );
+ ins_pipe(ialu_reg_reg);
+%}
+
+
//----------PEEPHOLE RULES-----------------------------------------------------
// These must follow all instruction definitions as they use the names
// defined in the instructions definitions.
--- a/hotspot/src/os/bsd/vm/decoder_machO.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os/bsd/vm/decoder_machO.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,9 @@
#include "utilities/decoder.hpp"
-// Just a placehold for now
-class MachODecoder: public NullDecoder {
+// Just a placehold for now, a real implementation should derive
+// from AbstractDecoder
+class MachODecoder : public NullDecoder {
public:
MachODecoder() { }
~MachODecoder() { }
--- a/hotspot/src/os/windows/vm/decoder_windows.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -36,7 +36,7 @@
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
-class WindowsDecoder: public NullDecoder {
+class WindowsDecoder : public AbstractDecoder {
public:
WindowsDecoder();
--- a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1999, 2012, 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,137 +24,3 @@
// X86 Bsd Architecture Description File
-//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
-// This block specifies the encoding classes used by the compiler to output
-// byte streams. Encoding classes generate functions which are called by
-// Machine Instruction Nodes in order to generate the bit encoding of the
-// instruction. Operands specify their base encoding interface with the
-// interface keyword. There are currently supported four interfaces,
-// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
-// operand to generate a function which returns its register number when
-// queried. CONST_INTER causes an operand to generate a function which
-// returns the value of the constant when queried. MEMORY_INTER causes an
-// operand to generate four functions which return the Base Register, the
-// Index Register, the Scale Value, and the Offset Value of the operand when
-// queried. COND_INTER causes an operand to generate six functions which
-// return the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional instruction.
-// Instructions specify two basic values for encoding. They use the
-// ins_encode keyword to specify their encoding class (which must be one of
-// the class names specified in the encoding block), and they use the
-// opcode keyword to specify, in order, their primary, secondary, and
-// tertiary opcode. Only the opcode sections which a particular instruction
-// needs for encoding need to be specified.
-encode %{
- // Build emit functions for each basic byte or larger field in the intel
- // encoding scheme (opcode, rm, sib, immediate), and call them from C++
- // code in the enc_class source block. Emit functions will live in the
- // main source block for now. In future, we can generalize this by
- // adding a syntax that specifies the sizes of fields in an order,
- // so that the adlc can build the emit functions automagically
-
- enc_class bsd_tlsencode (eRegP dst) %{
- Register dstReg = as_Register($dst$$reg);
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->get_thread(dstReg);
- %}
-
- enc_class bsd_breakpoint %{
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
- %}
-
- enc_class call_epilog %{
- if( VerifyStackAtCalls ) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
- if(framesize >= 128) {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0xBC);
- emit_d8(cbuf,0x24);
- emit_d32(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- else {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0x7C);
- emit_d8(cbuf,0x24);
- emit_d8(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 5; // size of call to breakpoint, 1 for CC
- emit_opcode(cbuf,0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
- }
- %}
-
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
- match(Set dst (ThreadLocal));
- effect(DEF dst, KILL cr);
-
- format %{ "MOV $dst, Thread::current()" %}
- ins_encode( bsd_tlsencode(dst) );
- ins_pipe( ialu_reg_fat );
-%}
-
-instruct TLS(eRegP dst) %{
- match(Set dst (ThreadLocal));
-
- expand %{
- tlsLoadP(dst);
- %}
-%}
-
-// Die now
-instruct ShouldNotReachHere( )
-%{
- match(Halt);
-
- // Use the following format syntax
- format %{ "INT3 ; ShouldNotReachHere" %}
- // QQQ TODO for now call breakpoint
- // opcode(0xCC);
- // ins_encode(Opc);
- ins_encode(bsd_breakpoint);
- ins_pipe( pipe_slow );
-%}
-
-
-
-// Platform dependent source
-
-source %{
-
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer &cbuf) {
-
- // Debugger doesn't really catch this but best we can do so far QQQ
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
- emit_break(cbuf);
-}
-
-
-uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
- return 5;
-}
-
-%}
--- a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2012, 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,8 +55,7 @@
// adding a syntax that specifies the sizes of fields in an order,
// so that the adlc can build the emit functions automagically
- enc_class Java_To_Runtime(method meth)
- %{
+ enc_class Java_To_Runtime(method meth) %{
// No relocation needed
// movq r10, <meth>
@@ -70,104 +69,15 @@
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
%}
- enc_class bsd_breakpoint
- %{
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
- %}
-
- enc_class call_epilog
- %{
- if (VerifyStackAtCalls) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize =
- ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
- if (framesize) {
- if (framesize < 0x80) {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0x7C);
- emit_d8(cbuf, 0x24);
- emit_d8(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- } else {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0xBC);
- emit_d8(cbuf, 0x24);
- emit_d32(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 5; // size of call to breakpoint, 1 for CC
- emit_opcode(cbuf, 0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
- }
- %}
-
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(r15_RegP dst)
-%{
- match(Set dst (ThreadLocal));
- effect(DEF dst);
-
- size(0);
- format %{ "# TLS is in R15" %}
- ins_encode( /*empty encoding*/ );
- ins_pipe(ialu_reg_reg);
-%}
-
-// Die now
-instruct ShouldNotReachHere()
-%{
- match(Halt);
-
- // Use the following format syntax
- format %{ "int3\t# ShouldNotReachHere" %}
- // QQQ TODO for now call breakpoint
- // opcode(0xCC);
- // ins_encode(Opc);
- ins_encode(bsd_breakpoint);
- ins_pipe(pipe_slow);
%}
// Platform dependent source
-source
-%{
+source %{
int MachCallRuntimeNode::ret_addr_offset() {
return 13; // movq r10,#addr; callq (r10)
}
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer& cbuf) {
- // Debugger doesn't really catch this but best we can do so far QQQ
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
- emit_break(cbuf);
-}
-
-uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
- return 5;
-}
-
%}
--- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1999, 2012, 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,137 +24,3 @@
// X86 Linux Architecture Description File
-//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
-// This block specifies the encoding classes used by the compiler to output
-// byte streams. Encoding classes generate functions which are called by
-// Machine Instruction Nodes in order to generate the bit encoding of the
-// instruction. Operands specify their base encoding interface with the
-// interface keyword. There are currently supported four interfaces,
-// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
-// operand to generate a function which returns its register number when
-// queried. CONST_INTER causes an operand to generate a function which
-// returns the value of the constant when queried. MEMORY_INTER causes an
-// operand to generate four functions which return the Base Register, the
-// Index Register, the Scale Value, and the Offset Value of the operand when
-// queried. COND_INTER causes an operand to generate six functions which
-// return the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional instruction.
-// Instructions specify two basic values for encoding. They use the
-// ins_encode keyword to specify their encoding class (which must be one of
-// the class names specified in the encoding block), and they use the
-// opcode keyword to specify, in order, their primary, secondary, and
-// tertiary opcode. Only the opcode sections which a particular instruction
-// needs for encoding need to be specified.
-encode %{
- // Build emit functions for each basic byte or larger field in the intel
- // encoding scheme (opcode, rm, sib, immediate), and call them from C++
- // code in the enc_class source block. Emit functions will live in the
- // main source block for now. In future, we can generalize this by
- // adding a syntax that specifies the sizes of fields in an order,
- // so that the adlc can build the emit functions automagically
-
- enc_class linux_tlsencode (eRegP dst) %{
- Register dstReg = as_Register($dst$$reg);
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->get_thread(dstReg);
- %}
-
- enc_class linux_breakpoint %{
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
- %}
-
- enc_class call_epilog %{
- if( VerifyStackAtCalls ) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
- if(framesize >= 128) {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0xBC);
- emit_d8(cbuf,0x24);
- emit_d32(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- else {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0x7C);
- emit_d8(cbuf,0x24);
- emit_d8(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 5; // size of call to breakpoint, 1 for CC
- emit_opcode(cbuf,0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
- }
- %}
-
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
- match(Set dst (ThreadLocal));
- effect(DEF dst, KILL cr);
-
- format %{ "MOV $dst, Thread::current()" %}
- ins_encode( linux_tlsencode(dst) );
- ins_pipe( ialu_reg_fat );
-%}
-
-instruct TLS(eRegP dst) %{
- match(Set dst (ThreadLocal));
-
- expand %{
- tlsLoadP(dst);
- %}
-%}
-
-// Die now
-instruct ShouldNotReachHere( )
-%{
- match(Halt);
-
- // Use the following format syntax
- format %{ "INT3 ; ShouldNotReachHere" %}
- // QQQ TODO for now call breakpoint
- // opcode(0xCC);
- // ins_encode(Opc);
- ins_encode(linux_breakpoint);
- ins_pipe( pipe_slow );
-%}
-
-
-
-// Platform dependent source
-
-source %{
-
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer &cbuf) {
-
- // Debugger doesn't really catch this but best we can do so far QQQ
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
- emit_break(cbuf);
-}
-
-
-uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
- return MachNode::size(ra_);
-}
-
-%}
--- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2012, 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,8 +55,7 @@
// adding a syntax that specifies the sizes of fields in an order,
// so that the adlc can build the emit functions automagically
- enc_class Java_To_Runtime(method meth)
- %{
+ enc_class Java_To_Runtime(method meth) %{
// No relocation needed
// movq r10, <meth>
@@ -70,105 +69,15 @@
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
%}
- enc_class linux_breakpoint
- %{
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
- %}
-
- enc_class call_epilog
- %{
- if (VerifyStackAtCalls) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize =
- ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
- if (framesize) {
- if (framesize < 0x80) {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0x7C);
- emit_d8(cbuf, 0x24);
- emit_d8(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- } else {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0xBC);
- emit_d8(cbuf, 0x24);
- emit_d32(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 5; // size of call to breakpoint, 1 for CC
- emit_opcode(cbuf, 0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
- }
- %}
-
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(r15_RegP dst)
-%{
- match(Set dst (ThreadLocal));
- effect(DEF dst);
-
- size(0);
- format %{ "# TLS is in R15" %}
- ins_encode( /*empty encoding*/ );
- ins_pipe(ialu_reg_reg);
-%}
-
-// Die now
-instruct ShouldNotReachHere()
-%{
- match(Halt);
-
- // Use the following format syntax
- format %{ "int3\t# ShouldNotReachHere" %}
- // QQQ TODO for now call breakpoint
- // opcode(0xCC);
- // ins_encode(Opc);
- ins_encode(linux_breakpoint);
- ins_pipe(pipe_slow);
%}
// Platform dependent source
-source
-%{
+source %{
int MachCallRuntimeNode::ret_addr_offset() {
return 13; // movq r10,#addr; callq (r10)
}
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer& cbuf) {
- // Debugger doesn't really catch this but best we can do so far QQQ
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
- emit_break(cbuf);
-}
-
-uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
- // distance could be far and requires load and call through register
- return MachNode::size(ra_);
-}
-
%}
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1999, 2012, 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,144 +24,3 @@
// X86 Solaris Architecture Description File
-//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
-// This block specifies the encoding classes used by the compiler to output
-// byte streams. Encoding classes generate functions which are called by
-// Machine Instruction Nodes in order to generate the bit encoding of the
-// instruction. Operands specify their base encoding interface with the
-// interface keyword. There are currently supported four interfaces,
-// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
-// operand to generate a function which returns its register number when
-// queried. CONST_INTER causes an operand to generate a function which
-// returns the value of the constant when queried. MEMORY_INTER causes an
-// operand to generate four functions which return the Base Register, the
-// Index Register, the Scale Value, and the Offset Value of the operand when
-// queried. COND_INTER causes an operand to generate six functions which
-// return the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional instruction.
-// Instructions specify two basic values for encoding. They use the
-// ins_encode keyword to specify their encoding class (which must be one of
-// the class names specified in the encoding block), and they use the
-// opcode keyword to specify, in order, their primary, secondary, and
-// tertiary opcode. Only the opcode sections which a particular instruction
-// needs for encoding need to be specified.
-encode %{
- // Build emit functions for each basic byte or larger field in the intel
- // encoding scheme (opcode, rm, sib, immediate), and call them from C++
- // code in the enc_class source block. Emit functions will live in the
- // main source block for now. In future, we can generalize this by
- // adding a syntax that specifies the sizes of fields in an order,
- // so that the adlc can build the emit functions automagically
-
- enc_class solaris_tlsencode (eRegP dst) %{
- Register dstReg = as_Register($dst$$reg);
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->get_thread(dstReg);
- %}
-
- enc_class solaris_breakpoint %{
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- // Really need to fix this
- masm->push(rax);
- masm->push(rcx);
- masm->push(rdx);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
- masm->pop(rdx);
- masm->pop(rcx);
- masm->pop(rax);
- %}
-
- enc_class call_epilog %{
- if( VerifyStackAtCalls ) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
- if(framesize >= 128) {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0xBC);
- emit_d8(cbuf,0x24);
- emit_d32(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- else {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0x7C);
- emit_d8(cbuf,0x24);
- emit_d8(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 11; // size of call to breakpoint (and register preserve), 1 for CC
- emit_opcode(cbuf,0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
- }
- %}
-
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
- match(Set dst (ThreadLocal));
- effect(DEF dst, KILL cr);
-
- format %{ "MOV $dst, Thread::current()" %}
- ins_encode( solaris_tlsencode(dst) );
- ins_pipe( ialu_reg_fat );
-%}
-
-instruct TLS(eRegP dst) %{
- match(Set dst (ThreadLocal));
-
- expand %{
- tlsLoadP(dst);
- %}
-%}
-
-// Die now
-instruct ShouldNotReachHere( )
-%{
- match(Halt);
-
- // Use the following format syntax
- format %{ "INT3 ; ShouldNotReachHere" %}
- // QQQ TODO for now call breakpoint
- // opcode(0xCC);
- // ins_encode(Opc);
- ins_encode(solaris_breakpoint);
- ins_pipe( pipe_slow );
-%}
-
-
-
-// Platform dependent source
-
-source %{
-
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer &cbuf) {
-
- // Debugger doesn't really catch this but best we can do so far QQQ
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
- emit_break(cbuf);
-}
-
-
-uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
- return MachNode::size(ra_);
-}
-
-%}
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2004, 2012, 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,8 +55,7 @@
// adding a syntax that specifies the sizes of fields in an order,
// so that the adlc can build the emit functions automagically
- enc_class Java_To_Runtime(method meth)
- %{
+ enc_class Java_To_Runtime(method meth) %{
// No relocation needed
// movq r10, <meth>
@@ -70,118 +69,24 @@
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
%}
- enc_class solaris_breakpoint
- %{
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
- %}
-
- enc_class call_epilog
- %{
- if (VerifyStackAtCalls) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize =
- ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
- if (framesize) {
- if (framesize < 0x80) {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0x7C);
- emit_d8(cbuf, 0x24);
- emit_d8(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- } else {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0xBC);
- emit_d8(cbuf, 0x24);
- emit_d32(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 5; // size of call to breakpoint, 1 for CC
- emit_opcode(cbuf, 0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
+ enc_class post_call_verify_mxcsr %{
+ MacroAssembler _masm(&cbuf);
+ if (RestoreMXCSROnJNICalls) {
+ __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std()));
+ }
+ else if (CheckJNICalls) {
+ __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry())));
}
%}
-
- enc_class post_call_verify_mxcsr %{
- MacroAssembler masm(&cbuf);
- if (RestoreMXCSROnJNICalls) {
- masm.ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std()));
- }
- else if (CheckJNICalls) {
- masm.call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry())));
- }
- %}
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(r15_RegP dst)
-%{
- match(Set dst (ThreadLocal));
- effect(DEF dst);
-
- size(0);
- format %{ "# TLS is in R15" %}
- ins_encode( /*empty encoding*/ );
- ins_pipe(ialu_reg_reg);
-%}
-
-// Die now
-instruct ShouldNotReachHere()
-%{
- match(Halt);
-
- // Use the following format syntax
- format %{ "int3\t# ShouldNotReachHere" %}
- // QQQ TODO for now call breakpoint
- // opcode(0xCC);
- // ins_encode(Opc);
- ins_encode(solaris_breakpoint);
- ins_pipe(pipe_slow);
%}
// Platform dependent source
-source
-%{
+source %{
-int MachCallRuntimeNode::ret_addr_offset()
-{
+int MachCallRuntimeNode::ret_addr_offset() {
return 13; // movq r10,#addr; callq (r10)
}
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer& cbuf)
-{
- // Debugger doesn't really catch this but best we can do so far QQQ
- MacroAssembler* masm = new MacroAssembler(&cbuf);
- masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
-{
- emit_break(cbuf);
-}
-
-uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const
-{
- // distance could be far and requires load and call through register
- return MachNode::size(ra_);
-}
-
%}
--- a/hotspot/src/os_cpu/windows_x86/vm/windows_x86_32.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/windows_x86/vm/windows_x86_32.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1999, 2012, 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,134 +24,3 @@
// X86 Win32 Architecture Description File
-//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
-// This block specifies the encoding classes used by the compiler to output
-// byte streams. Encoding classes generate functions which are called by
-// Machine Instruction Nodes in order to generate the bit encoding of the
-// instruction. Operands specify their base encoding interface with the
-// interface keyword. There are currently supported four interfaces,
-// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
-// operand to generate a function which returns its register number when
-// queried. CONST_INTER causes an operand to generate a function which
-// returns the value of the constant when queried. MEMORY_INTER causes an
-// operand to generate four functions which return the Base Register, the
-// Index Register, the Scale Value, and the Offset Value of the operand when
-// queried. COND_INTER causes an operand to generate six functions which
-// return the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional instruction.
-// Instructions specify two basic values for encoding. They use the
-// ins_encode keyword to specify their encoding class (which must be one of
-// the class names specified in the encoding block), and they use the
-// opcode keyword to specify, in order, their primary, secondary, and
-// tertiary opcode. Only the opcode sections which a particular instruction
-// needs for encoding need to be specified.
-encode %{
- // Build emit functions for each basic byte or larger field in the intel
- // encoding scheme (opcode, rm, sib, immediate), and call them from C++
- // code in the enc_class source block. Emit functions will live in the
- // main source block for now. In future, we can generalize this by
- // adding a syntax that specifies the sizes of fields in an order,
- // so that the adlc can build the emit functions automagically
-
- enc_class tlsencode (eRegP dst, eRegP src) %{
- emit_rm(cbuf, 0x2, $dst$$reg, $src$$reg);
- emit_d32(cbuf, ThreadLocalStorage::get_thread_ptr_offset() );
- %}
-
- enc_class call_epilog %{
- if( VerifyStackAtCalls ) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
- if(framesize >= 128) {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0xBC);
- emit_d8(cbuf,0x24);
- emit_d32(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- else {
- emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
- emit_d8(cbuf,0x7C);
- emit_d8(cbuf,0x24);
- emit_d8(cbuf,framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- // jmp EQ around INT3
- emit_opcode(cbuf,0x74);
- emit_d8(cbuf,1);
- // Die if stack mismatch
- emit_opcode(cbuf,0xCC);
- }
- %}
-
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-
-//----------OS and Locking Instructions----------------------------------------
-
-// The prefix of this name is KNOWN by the ADLC and cannot be changed.
-instruct tlsLoadP_prefixLoadP(eRegP t1) %{
- effect(DEF t1);
-
- format %{ "MOV $t1,FS:[0x00] "%}
- opcode(0x8B, 0x64);
- ins_encode(OpcS, OpcP, conmemref(t1));
- ins_pipe( ialu_reg_fat );
-%}
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-// %%% Should do this with a clause like: bottom_type(TypeRawPtr::BOTTOM);
-instruct tlsLoadP(eRegP dst, eRegP t1) %{
- effect(DEF dst, USE t1);
-
- format %{ "MOV $dst,[$t1 + TLS::thread_ptr_offset()]" %}
- opcode(0x8B);
- ins_encode(OpcP, tlsencode(dst, t1));
- ins_pipe( ialu_reg_reg_fat );
-%}
-
-instruct TLS(eRegP dst) %{
- match(Set dst (ThreadLocal));
- expand %{
- eRegP t1;
- tlsLoadP_prefixLoadP(t1);
- tlsLoadP(dst, t1);
- %}
-%}
-
-// Die now
-instruct ShouldNotReachHere( )
-%{
- match(Halt);
- // Use the following format syntax
- format %{ "INT3 ; ShouldNotReachHere" %}
- opcode(0xCC);
- ins_encode(OpcP);
- ins_pipe( pipe_slow );
-%}
-
-//
-// Platform dependent source
-//
-source %{
-
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer &cbuf) {
- cbuf.insts()->emit_int8((unsigned char) 0xcc);
-}
-
-void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
- emit_break(cbuf);
-}
-
-
-uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
- return 1;
-}
-
-
-%}
--- a/hotspot/src/os_cpu/windows_x86/vm/windows_x86_64.ad Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/os_cpu/windows_x86/vm/windows_x86_64.ad Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2012, 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
@@ -67,69 +67,6 @@
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
%}
- enc_class call_epilog %{
- if (VerifyStackAtCalls) {
- // Check that stack depth is unchanged: find majik cookie on stack
- int framesize =
- ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
- if (framesize) {
- if (framesize < 0x80) {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0x7C);
- emit_d8(cbuf, 0x24);
- emit_d8(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- } else {
- emit_opcode(cbuf, Assembler::REX_W);
- emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
- emit_d8(cbuf, 0xBC);
- emit_d8(cbuf, 0x24);
- emit_d32(cbuf, framesize); // Find majik cookie from ESP
- emit_d32(cbuf, 0xbadb100d);
- }
- }
- // jmp EQ around INT3
- // QQQ TODO
- const int jump_around = 5; // size of call to breakpoint, 1 for CC
- emit_opcode(cbuf, 0x74);
- emit_d8(cbuf, jump_around);
- // QQQ temporary
- emit_break(cbuf);
- // Die if stack mismatch
- // emit_opcode(cbuf,0xCC);
- }
- %}
-%}
-
-// INSTRUCTIONS -- Platform dependent
-
-
-//----------OS and Locking Instructions----------------------------------------
-
-// This name is KNOWN by the ADLC and cannot be changed.
-// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
-// for this guy.
-instruct tlsLoadP(r15_RegP dst)
-%{
- match(Set dst (ThreadLocal));
- effect(DEF dst);
-
- size(0);
- format %{ "# TLS is in R15" %}
- ins_encode( /*empty encoding*/ );
- ins_pipe(ialu_reg_reg);
-%}
-
-// Die now
-instruct ShouldNotReachHere( )
-%{
- match(Halt);
- // Use the following format syntax
- format %{ "INT3 ; ShouldNotReachHere" %}
- opcode(0xCC);
- ins_encode(OpcP);
- ins_pipe( pipe_slow );
%}
//
@@ -142,17 +79,4 @@
return 13; // movq r10,#addr; callq (r10)
}
-// emit an interrupt that is caught by the debugger
-void emit_break(CodeBuffer &cbuf) {
- cbuf.insts()->emit_int8((unsigned char) 0xcc);
-}
-
-void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
- emit_break(cbuf);
-}
-
-uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
- return 1;
-}
-
%}
--- a/hotspot/src/share/tools/hsdis/hsdis.c Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/tools/hsdis/hsdis.c Wed Jul 05 18:03:08 2017 +0200
@@ -356,7 +356,7 @@
if (plen > mach_size) plen = mach_size;
strncpy(mach_option, p, plen);
mach_option[plen] = '\0';
- } else if (plen > 6 && strncmp(p, "hsdis-", 6)) {
+ } else if (plen > 6 && strncmp(p, "hsdis-", 6) == 0) {
// do not pass these to the next level
} else {
/* just copy it; {i386,sparc}-dis.c might like to see it */
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -594,6 +594,13 @@
return false;
}
+static bool is_safepoint(BlockEnd* x, BlockBegin* sux) {
+ // An Instruction with multiple successors, x, is replaced by a Goto
+ // to a single successor, sux. Is a safepoint check needed = was the
+ // instruction being replaced a safepoint and the single remaining
+ // successor a back branch?
+ return x->is_safepoint() && (sux->bci() < x->state_before()->bci());
+}
void Canonicalizer::do_If(If* x) {
// move const to right
@@ -614,7 +621,7 @@
case If::geq: sux = x->sux_for(true); break;
}
// If is a safepoint then the debug information should come from the state_before of the If.
- set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
+ set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
return;
}
@@ -626,7 +633,7 @@
x->sux_for(false));
if (sux != NULL) {
// If is a safepoint then the debug information should come from the state_before of the If.
- set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
+ set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
}
}
} else if (rt->as_IntConstant() != NULL) {
@@ -694,10 +701,12 @@
}
} else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) {
if (x->cond() == Instruction::eql) {
- set_canonical(new Goto(x->fsux(), x->state_before(), x->is_safepoint()));
+ BlockBegin* sux = x->fsux();
+ set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
} else {
assert(x->cond() == Instruction::neq, "only other valid case");
- set_canonical(new Goto(x->tsux(), x->state_before(), x->is_safepoint()));
+ BlockBegin* sux = x->tsux();
+ set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
}
}
}
@@ -710,7 +719,7 @@
if (v >= x->lo_key() && v <= x->hi_key()) {
sux = x->sux_at(v - x->lo_key());
}
- set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
+ set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
} else if (x->number_of_sux() == 1) {
// NOTE: Code permanently disabled for now since the switch statement's
// tag expression may produce side-effects in which case it must
@@ -741,7 +750,7 @@
sux = x->sux_at(i);
}
}
- set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
+ set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
} else if (x->number_of_sux() == 1) {
// NOTE: Code permanently disabled for now since the switch statement's
// tag expression may produce side-effects in which case it must
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1181,6 +1181,11 @@
bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
+ assert(i->as_Goto() == NULL ||
+ (i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
+ (i->as_Goto()->sux_at(0) == fsux && i->as_Goto()->is_safepoint() == fsux->bci() < stream()->cur_bci()),
+ "safepoint state of Goto returned by canonicalizer incorrect");
+
if (is_profiling()) {
If* if_node = i->as_If();
if (if_node != NULL) {
@@ -1303,7 +1308,16 @@
// add default successor
sux->at_put(i, block_at(bci() + sw.default_offset()));
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
- append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
+ Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
+#ifdef ASSERT
+ if (res->as_Goto()) {
+ for (i = 0; i < l; i++) {
+ if (sux->at(i) == res->as_Goto()->sux_at(0)) {
+ assert(res->as_Goto()->is_safepoint() == sw.dest_offset_at(i) < 0, "safepoint state of Goto returned by canonicalizer incorrect");
+ }
+ }
+ }
+#endif
}
}
@@ -1338,7 +1352,16 @@
// add default successor
sux->at_put(i, block_at(bci() + sw.default_offset()));
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
- append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
+ Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
+#ifdef ASSERT
+ if (res->as_Goto()) {
+ for (i = 0; i < l; i++) {
+ if (sux->at(i) == res->as_Goto()->sux_at(0)) {
+ assert(res->as_Goto()->is_safepoint() == sw.pair_at(i).offset() < 0, "safepoint state of Goto returned by canonicalizer incorrect");
+ }
+ }
+ }
+#endif
}
}
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -2464,12 +2464,15 @@
// frequently used constants
-ConstantOopWriteValue LinearScan::_oop_null_scope_value = ConstantOopWriteValue(NULL);
-ConstantIntValue LinearScan::_int_m1_scope_value = ConstantIntValue(-1);
-ConstantIntValue LinearScan::_int_0_scope_value = ConstantIntValue(0);
-ConstantIntValue LinearScan::_int_1_scope_value = ConstantIntValue(1);
-ConstantIntValue LinearScan::_int_2_scope_value = ConstantIntValue(2);
-LocationValue _illegal_value = LocationValue(Location());
+// Allocate them with new so they are never destroyed (otherwise, a
+// forced exit could destroy these objects while they are still in
+// use).
+ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (ResourceObj::C_HEAP) ConstantOopWriteValue(NULL);
+ConstantIntValue* LinearScan::_int_m1_scope_value = new (ResourceObj::C_HEAP) ConstantIntValue(-1);
+ConstantIntValue* LinearScan::_int_0_scope_value = new (ResourceObj::C_HEAP) ConstantIntValue(0);
+ConstantIntValue* LinearScan::_int_1_scope_value = new (ResourceObj::C_HEAP) ConstantIntValue(1);
+ConstantIntValue* LinearScan::_int_2_scope_value = new (ResourceObj::C_HEAP) ConstantIntValue(2);
+LocationValue* _illegal_value = new (ResourceObj::C_HEAP) LocationValue(Location());
void LinearScan::init_compute_debug_info() {
// cache for frequently used scope values
@@ -2508,7 +2511,7 @@
case T_OBJECT: {
jobject value = c->as_jobject();
if (value == NULL) {
- scope_values->append(&_oop_null_scope_value);
+ scope_values->append(_oop_null_scope_value);
} else {
scope_values->append(new ConstantOopWriteValue(c->as_jobject()));
}
@@ -2519,10 +2522,10 @@
case T_FLOAT: {
int value = c->as_jint_bits();
switch (value) {
- case -1: scope_values->append(&_int_m1_scope_value); break;
- case 0: scope_values->append(&_int_0_scope_value); break;
- case 1: scope_values->append(&_int_1_scope_value); break;
- case 2: scope_values->append(&_int_2_scope_value); break;
+ case -1: scope_values->append(_int_m1_scope_value); break;
+ case 0: scope_values->append(_int_0_scope_value); break;
+ case 1: scope_values->append(_int_1_scope_value); break;
+ case 2: scope_values->append(_int_2_scope_value); break;
default: scope_values->append(new ConstantIntValue(c->as_jint_bits())); break;
}
return 1;
@@ -2531,7 +2534,7 @@
case T_LONG: // fall through
case T_DOUBLE: {
#ifdef _LP64
- scope_values->append(&_int_0_scope_value);
+ scope_values->append(_int_0_scope_value);
scope_values->append(new ConstantLongValue(c->as_jlong_bits()));
#else
if (hi_word_offset_in_bytes > lo_word_offset_in_bytes) {
@@ -2657,7 +2660,7 @@
}
// Does this reverse on x86 vs. sparc?
first = new LocationValue(loc1);
- second = &_int_0_scope_value;
+ second = _int_0_scope_value;
#else
Location loc1, loc2;
if (!frame_map()->locations_for_slot(opr->double_stack_ix(), Location::normal, &loc1, &loc2)) {
@@ -2671,7 +2674,7 @@
#ifdef _LP64
VMReg rname_first = opr->as_register_lo()->as_VMReg();
first = new LocationValue(Location::new_reg_loc(Location::lng, rname_first));
- second = &_int_0_scope_value;
+ second = _int_0_scope_value;
#else
VMReg rname_first = opr->as_register_lo()->as_VMReg();
VMReg rname_second = opr->as_register_hi()->as_VMReg();
@@ -2694,7 +2697,7 @@
VMReg rname_first = opr->as_xmm_double_reg()->as_VMReg();
# ifdef _LP64
first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
- second = &_int_0_scope_value;
+ second = _int_0_scope_value;
# else
first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
// %%% This is probably a waste but we'll keep things as they were for now
@@ -2741,7 +2744,7 @@
#ifdef _LP64
first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
- second = &_int_0_scope_value;
+ second = _int_0_scope_value;
#else
first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
// %%% This is probably a waste but we'll keep things as they were for now
@@ -2822,7 +2825,7 @@
}
} else {
// append a dummy value because real value not needed
- scope_values->append(&_illegal_value);
+ scope_values->append(_illegal_value);
return 1;
}
}
@@ -2865,7 +2868,7 @@
nof_locals = cur_scope->method()->max_locals();
locals = new GrowableArray<ScopeValue*>(nof_locals);
for(int i = 0; i < nof_locals; i++) {
- locals->append(&_illegal_value);
+ locals->append(_illegal_value);
}
}
--- a/hotspot/src/share/vm/c1/c1_LinearScan.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -160,11 +160,11 @@
// TODO: cached scope values for registers could be static
ScopeValueArray _scope_value_cache;
- static ConstantOopWriteValue _oop_null_scope_value;
- static ConstantIntValue _int_m1_scope_value;
- static ConstantIntValue _int_0_scope_value;
- static ConstantIntValue _int_1_scope_value;
- static ConstantIntValue _int_2_scope_value;
+ static ConstantOopWriteValue* _oop_null_scope_value;
+ static ConstantIntValue* _int_m1_scope_value;
+ static ConstantIntValue* _int_0_scope_value;
+ static ConstantIntValue* _int_1_scope_value;
+ static ConstantIntValue* _int_2_scope_value;
// accessors
IR* ir() const { return _ir; }
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -284,6 +284,7 @@
template(run_method_name, "run") \
template(exit_method_name, "exit") \
template(add_method_name, "add") \
+ template(remove_method_name, "remove") \
template(parent_name, "parent") \
template(threads_name, "threads") \
template(groups_name, "groups") \
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -204,7 +204,8 @@
}
void log_nmethod(JavaThread* thread, nmethod* nm) {
- log(thread, "nmethod " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]",
+ log(thread, "nmethod %d%s " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]",
+ nm->compile_id(), nm->is_osr_method() ? "%" : "",
nm, nm->code_begin(), nm->code_end());
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -6092,7 +6092,11 @@
_inter_sweep_timer.reset();
_inter_sweep_timer.start();
- update_time_of_last_gc(os::javaTimeMillis());
+ // We need to use a monotonically non-deccreasing time in ms
+ // or we will see time-warp warnings and os::javaTimeMillis()
+ // does not guarantee monotonicity.
+ jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ update_time_of_last_gc(now);
// NOTE on abstract state transitions:
// Mutators allocate-live and/or mark the mod-union table dirty
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -48,6 +48,8 @@
#ifndef PRODUCT
bool CSetChooserCache::verify() {
+ guarantee(false, "CSetChooserCache::verify(): don't call this any more");
+
int index = _first;
HeapRegion *prev = NULL;
for (int i = 0; i < _occupancy; ++i) {
@@ -75,6 +77,8 @@
#endif // PRODUCT
void CSetChooserCache::insert(HeapRegion *hr) {
+ guarantee(false, "CSetChooserCache::insert(): don't call this any more");
+
assert(!is_full(), "cache should not be empty");
hr->calc_gc_efficiency();
@@ -104,6 +108,9 @@
}
HeapRegion *CSetChooserCache::remove_first() {
+ guarantee(false, "CSetChooserCache::remove_first(): "
+ "don't call this any more");
+
if (_occupancy > 0) {
assert(_cache[_first] != NULL, "cache should have at least one region");
HeapRegion *ret = _cache[_first];
@@ -118,16 +125,35 @@
}
}
-static inline int orderRegions(HeapRegion* hr1, HeapRegion* hr2) {
+// Even though we don't use the GC efficiency in our heuristics as
+// much as we used to, we still order according to GC efficiency. This
+// will cause regions with a lot of live objects and large RSets to
+// end up at the end of the array. Given that we might skip collecting
+// the last few old regions, if after a few mixed GCs the remaining
+// have reclaimable bytes under a certain threshold, the hope is that
+// the ones we'll skip are ones with both large RSets and a lot of
+// live objects, not the ones with just a lot of live objects if we
+// ordered according to the amount of reclaimable bytes per region.
+static int orderRegions(HeapRegion* hr1, HeapRegion* hr2) {
if (hr1 == NULL) {
- if (hr2 == NULL) return 0;
- else return 1;
+ if (hr2 == NULL) {
+ return 0;
+ } else {
+ return 1;
+ }
} else if (hr2 == NULL) {
return -1;
}
- if (hr2->gc_efficiency() < hr1->gc_efficiency()) return -1;
- else if (hr1->gc_efficiency() < hr2->gc_efficiency()) return 1;
- else return 0;
+
+ double gc_eff1 = hr1->gc_efficiency();
+ double gc_eff2 = hr2->gc_efficiency();
+ if (gc_eff1 > gc_eff2) {
+ return -1;
+ } if (gc_eff1 < gc_eff2) {
+ return 1;
+ } else {
+ return 0;
+ }
}
static int orderRegions(HeapRegion** hr1p, HeapRegion** hr2p) {
@@ -151,51 +177,61 @@
//
_markedRegions((ResourceObj::set_allocation_type((address)&_markedRegions,
ResourceObj::C_HEAP),
- 100),
- true),
- _curMarkedIndex(0),
- _numMarkedRegions(0),
- _unmarked_age_1_returned_as_new(false),
- _first_par_unreserved_idx(0)
-{}
-
-
+ 100), true /* C_Heap */),
+ _curr_index(0), _length(0),
+ _regionLiveThresholdBytes(0), _remainingReclaimableBytes(0),
+ _first_par_unreserved_idx(0) {
+ _regionLiveThresholdBytes =
+ HeapRegion::GrainBytes * (size_t) G1OldCSetRegionLiveThresholdPercent / 100;
+}
#ifndef PRODUCT
bool CollectionSetChooser::verify() {
+ guarantee(_length >= 0, err_msg("_length: %d", _length));
+ guarantee(0 <= _curr_index && _curr_index <= _length,
+ err_msg("_curr_index: %d _length: %d", _curr_index, _length));
int index = 0;
- guarantee(_curMarkedIndex <= _numMarkedRegions,
- "_curMarkedIndex should be within bounds");
- while (index < _curMarkedIndex) {
- guarantee(_markedRegions.at(index++) == NULL,
- "all entries before _curMarkedIndex should be NULL");
+ size_t sum_of_reclaimable_bytes = 0;
+ while (index < _curr_index) {
+ guarantee(_markedRegions.at(index) == NULL,
+ "all entries before _curr_index should be NULL");
+ index += 1;
}
HeapRegion *prev = NULL;
- while (index < _numMarkedRegions) {
+ while (index < _length) {
HeapRegion *curr = _markedRegions.at(index++);
guarantee(curr != NULL, "Regions in _markedRegions array cannot be NULL");
int si = curr->sort_index();
guarantee(!curr->is_young(), "should not be young!");
+ guarantee(!curr->isHumongous(), "should not be humongous!");
guarantee(si > -1 && si == (index-1), "sort index invariant");
if (prev != NULL) {
- guarantee(orderRegions(prev, curr) != 1, "regions should be sorted");
+ guarantee(orderRegions(prev, curr) != 1,
+ err_msg("GC eff prev: %1.4f GC eff curr: %1.4f",
+ prev->gc_efficiency(), curr->gc_efficiency()));
}
+ sum_of_reclaimable_bytes += curr->reclaimable_bytes();
prev = curr;
}
- return _cache.verify();
+ guarantee(sum_of_reclaimable_bytes == _remainingReclaimableBytes,
+ err_msg("reclaimable bytes inconsistent, "
+ "remaining: "SIZE_FORMAT" sum: "SIZE_FORMAT,
+ _remainingReclaimableBytes, sum_of_reclaimable_bytes));
+ return true;
}
#endif
-void
-CollectionSetChooser::fillCache() {
- while (!_cache.is_full() && (_curMarkedIndex < _numMarkedRegions)) {
- HeapRegion* hr = _markedRegions.at(_curMarkedIndex);
+void CollectionSetChooser::fillCache() {
+ guarantee(false, "fillCache: don't call this any more");
+
+ while (!_cache.is_full() && (_curr_index < _length)) {
+ HeapRegion* hr = _markedRegions.at(_curr_index);
assert(hr != NULL,
err_msg("Unexpected NULL hr in _markedRegions at index %d",
- _curMarkedIndex));
- _curMarkedIndex += 1;
+ _curr_index));
+ _curr_index += 1;
assert(!hr->is_young(), "should not be young!");
- assert(hr->sort_index() == _curMarkedIndex-1, "sort_index invariant");
+ assert(hr->sort_index() == _curr_index-1, "sort_index invariant");
_markedRegions.at_put(hr->sort_index(), NULL);
_cache.insert(hr);
assert(!_cache.is_empty(), "cache should not be empty");
@@ -203,9 +239,7 @@
assert(verify(), "cache should be consistent");
}
-void
-CollectionSetChooser::sortMarkedHeapRegions() {
- guarantee(_cache.is_empty(), "cache should be empty");
+void CollectionSetChooser::sortMarkedHeapRegions() {
// First trim any unused portion of the top in the parallel case.
if (_first_par_unreserved_idx > 0) {
if (G1PrintParCleanupStats) {
@@ -217,43 +251,78 @@
_markedRegions.trunc_to(_first_par_unreserved_idx);
}
_markedRegions.sort(orderRegions);
- assert(_numMarkedRegions <= _markedRegions.length(), "Requirement");
- assert(_numMarkedRegions == 0
- || _markedRegions.at(_numMarkedRegions-1) != NULL,
- "Testing _numMarkedRegions");
- assert(_numMarkedRegions == _markedRegions.length()
- || _markedRegions.at(_numMarkedRegions) == NULL,
- "Testing _numMarkedRegions");
+ assert(_length <= _markedRegions.length(), "Requirement");
+ assert(_length == 0 || _markedRegions.at(_length - 1) != NULL,
+ "Testing _length");
+ assert(_length == _markedRegions.length() ||
+ _markedRegions.at(_length) == NULL, "Testing _length");
if (G1PrintParCleanupStats) {
- gclog_or_tty->print_cr(" Sorted %d marked regions.", _numMarkedRegions);
+ gclog_or_tty->print_cr(" Sorted %d marked regions.", _length);
}
- for (int i = 0; i < _numMarkedRegions; i++) {
+ for (int i = 0; i < _length; i++) {
assert(_markedRegions.at(i) != NULL, "Should be true by sorting!");
_markedRegions.at(i)->set_sort_index(i);
}
if (G1PrintRegionLivenessInfo) {
G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting");
- for (int i = 0; i < _numMarkedRegions; ++i) {
+ for (int i = 0; i < _length; ++i) {
HeapRegion* r = _markedRegions.at(i);
cl.doHeapRegion(r);
}
}
- assert(verify(), "should now be sorted");
+ assert(verify(), "CSet chooser verification");
}
-void
-CollectionSetChooser::addMarkedHeapRegion(HeapRegion* hr) {
+size_t CollectionSetChooser::calcMinOldCSetLength() {
+ // The min old CSet region bound is based on the maximum desired
+ // number of mixed GCs after a cycle. I.e., even if some old regions
+ // look expensive, we should add them to the CSet anyway to make
+ // sure we go through the available old regions in no more than the
+ // maximum desired number of mixed GCs.
+ //
+ // The calculation is based on the number of marked regions we added
+ // to the CSet chooser in the first place, not how many remain, so
+ // that the result is the same during all mixed GCs that follow a cycle.
+
+ const size_t region_num = (size_t) _length;
+ const size_t gc_num = (size_t) G1MaxMixedGCNum;
+ size_t result = region_num / gc_num;
+ // emulate ceiling
+ if (result * gc_num < region_num) {
+ result += 1;
+ }
+ return result;
+}
+
+size_t CollectionSetChooser::calcMaxOldCSetLength() {
+ // The max old CSet region bound is based on the threshold expressed
+ // as a percentage of the heap size. I.e., it should bound the
+ // number of old regions added to the CSet irrespective of how many
+ // of them are available.
+
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ const size_t region_num = g1h->n_regions();
+ const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
+ size_t result = region_num * perc / 100;
+ // emulate ceiling
+ if (100 * result < region_num * perc) {
+ result += 1;
+ }
+ return result;
+}
+
+void CollectionSetChooser::addMarkedHeapRegion(HeapRegion* hr) {
assert(!hr->isHumongous(),
"Humongous regions shouldn't be added to the collection set");
assert(!hr->is_young(), "should not be young!");
_markedRegions.append(hr);
- _numMarkedRegions++;
+ _length++;
+ _remainingReclaimableBytes += hr->reclaimable_bytes();
hr->calc_gc_efficiency();
}
-void
-CollectionSetChooser::
-prepareForAddMarkedHeapRegionsPar(size_t n_regions, size_t chunkSize) {
+void CollectionSetChooser::prepareForAddMarkedHeapRegionsPar(size_t n_regions,
+ size_t chunkSize) {
_first_par_unreserved_idx = 0;
int n_threads = ParallelGCThreads;
if (UseDynamicNumberOfGCThreads) {
@@ -274,8 +343,7 @@
_markedRegions.at_put_grow((int)(aligned_n_regions + max_waste - 1), NULL);
}
-jint
-CollectionSetChooser::getParMarkedHeapRegionChunk(jint n_regions) {
+jint CollectionSetChooser::getParMarkedHeapRegionChunk(jint n_regions) {
// Don't do this assert because this can be called at a point
// where the loop up stream will not execute again but might
// try to claim more chunks (loop test has not been done yet).
@@ -287,83 +355,37 @@
return res - n_regions;
}
-void
-CollectionSetChooser::setMarkedHeapRegion(jint index, HeapRegion* hr) {
+void CollectionSetChooser::setMarkedHeapRegion(jint index, HeapRegion* hr) {
assert(_markedRegions.at(index) == NULL, "precondition");
assert(!hr->is_young(), "should not be young!");
_markedRegions.at_put(index, hr);
hr->calc_gc_efficiency();
}
-void
-CollectionSetChooser::incNumMarkedHeapRegions(jint inc_by) {
- (void)Atomic::add(inc_by, &_numMarkedRegions);
-}
-
-void
-CollectionSetChooser::clearMarkedHeapRegions(){
- for (int i = 0; i < _markedRegions.length(); i++) {
- HeapRegion* r = _markedRegions.at(i);
- if (r != NULL) r->set_sort_index(-1);
+void CollectionSetChooser::updateTotals(jint region_num,
+ size_t reclaimable_bytes) {
+ // Only take the lock if we actually need to update the totals.
+ if (region_num > 0) {
+ assert(reclaimable_bytes > 0, "invariant");
+ // We could have just used atomics instead of taking the
+ // lock. However, we currently don't have an atomic add for size_t.
+ MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
+ _length += (int) region_num;
+ _remainingReclaimableBytes += reclaimable_bytes;
+ } else {
+ assert(reclaimable_bytes == 0, "invariant");
}
- _markedRegions.clear();
- _curMarkedIndex = 0;
- _numMarkedRegions = 0;
- _cache.clear();
-};
-
-void
-CollectionSetChooser::updateAfterFullCollection() {
- clearMarkedHeapRegions();
}
-// if time_remaining < 0.0, then this method should try to return
-// a region, whether it fits within the remaining time or not
-HeapRegion*
-CollectionSetChooser::getNextMarkedRegion(double time_remaining,
- double avg_prediction) {
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- G1CollectorPolicy* g1p = g1h->g1_policy();
- fillCache();
- if (_cache.is_empty()) {
- assert(_curMarkedIndex == _numMarkedRegions,
- "if cache is empty, list should also be empty");
- ergo_verbose0(ErgoCSetConstruction,
- "stop adding old regions to CSet",
- ergo_format_reason("cache is empty"));
- return NULL;
- }
-
- HeapRegion *hr = _cache.get_first();
- assert(hr != NULL, "if cache not empty, first entry should be non-null");
- double predicted_time = g1h->predict_region_elapsed_time_ms(hr, false);
-
- if (g1p->adaptive_young_list_length()) {
- if (time_remaining - predicted_time < 0.0) {
- g1h->check_if_region_is_too_expensive(predicted_time);
- ergo_verbose2(ErgoCSetConstruction,
- "stop adding old regions to CSet",
- ergo_format_reason("predicted old region time higher than remaining time")
- ergo_format_ms("predicted old region time")
- ergo_format_ms("remaining time"),
- predicted_time, time_remaining);
- return NULL;
- }
- } else {
- double threshold = 2.0 * avg_prediction;
- if (predicted_time > threshold) {
- ergo_verbose2(ErgoCSetConstruction,
- "stop adding old regions to CSet",
- ergo_format_reason("predicted old region time higher than threshold")
- ergo_format_ms("predicted old region time")
- ergo_format_ms("threshold"),
- predicted_time, threshold);
- return NULL;
+void CollectionSetChooser::clearMarkedHeapRegions() {
+ for (int i = 0; i < _markedRegions.length(); i++) {
+ HeapRegion* r = _markedRegions.at(i);
+ if (r != NULL) {
+ r->set_sort_index(-1);
}
}
-
- HeapRegion *hr2 = _cache.remove_first();
- assert(hr == hr2, "cache contents should not have changed");
-
- return hr;
-}
+ _markedRegions.clear();
+ _curr_index = 0;
+ _length = 0;
+ _remainingReclaimableBytes = 0;
+};
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -28,28 +28,6 @@
#include "gc_implementation/g1/heapRegion.hpp"
#include "utilities/growableArray.hpp"
-// We need to sort heap regions by collection desirability.
-// This sorting is currently done in two "stages". An initial sort is
-// done following a cleanup pause as soon as all of the marked but
-// non-empty regions have been identified and the completely empty
-// ones reclaimed.
-// This gives us a global sort on a GC efficiency metric
-// based on predictive data available at that time. However,
-// any of these regions that are collected will only be collected
-// during a future GC pause, by which time it is possible that newer
-// data might allow us to revise and/or refine the earlier
-// pause predictions, leading to changes in expected gc efficiency
-// order. To somewhat mitigate this obsolescence, more so in the
-// case of regions towards the end of the list, which will be
-// picked later, these pre-sorted regions from the _markedRegions
-// array are not used as is, but a small prefix thereof is
-// insertion-sorted again into a small cache, based on more
-// recent remembered set information. Regions are then drawn
-// from this cache to construct the collection set at each
-// incremental GC.
-// This scheme and/or its implementation may be subject to
-// revision in the future.
-
class CSetChooserCache VALUE_OBJ_CLASS_SPEC {
private:
enum {
@@ -103,24 +81,82 @@
class CollectionSetChooser: public CHeapObj {
GrowableArray<HeapRegion*> _markedRegions;
- int _curMarkedIndex;
- int _numMarkedRegions;
- CSetChooserCache _cache;
+
+ // The index of the next candidate old region to be considered for
+ // addition to the CSet.
+ int _curr_index;
+
+ // The number of candidate old regions added to the CSet chooser.
+ int _length;
- // True iff last collection pause ran of out new "age 0" regions, and
- // returned an "age 1" region.
- bool _unmarked_age_1_returned_as_new;
+ CSetChooserCache _cache;
+ jint _first_par_unreserved_idx;
- jint _first_par_unreserved_idx;
+ // If a region has more live bytes than this threshold, it will not
+ // be added to the CSet chooser and will not be a candidate for
+ // collection.
+ size_t _regionLiveThresholdBytes;
+
+ // The sum of reclaimable bytes over all the regions in the CSet chooser.
+ size_t _remainingReclaimableBytes;
public:
- HeapRegion* getNextMarkedRegion(double time_so_far, double avg_prediction);
+ // Return the current candidate region to be considered for
+ // collection without removing it from the CSet chooser.
+ HeapRegion* peek() {
+ HeapRegion* res = NULL;
+ if (_curr_index < _length) {
+ res = _markedRegions.at(_curr_index);
+ assert(res != NULL,
+ err_msg("Unexpected NULL hr in _markedRegions at index %d",
+ _curr_index));
+ }
+ return res;
+ }
+
+ // Remove the given region from the CSet chooser and move to the
+ // next one. The given region should be the current candidate region
+ // in the CSet chooser.
+ void remove_and_move_to_next(HeapRegion* hr) {
+ assert(hr != NULL, "pre-condition");
+ assert(_curr_index < _length, "pre-condition");
+ assert(_markedRegions.at(_curr_index) == hr, "pre-condition");
+ hr->set_sort_index(-1);
+ _markedRegions.at_put(_curr_index, NULL);
+ assert(hr->reclaimable_bytes() <= _remainingReclaimableBytes,
+ err_msg("remaining reclaimable bytes inconsistent "
+ "from region: "SIZE_FORMAT" remaining: "SIZE_FORMAT,
+ hr->reclaimable_bytes(), _remainingReclaimableBytes));
+ _remainingReclaimableBytes -= hr->reclaimable_bytes();
+ _curr_index += 1;
+ }
CollectionSetChooser();
void sortMarkedHeapRegions();
void fillCache();
+
+ // Determine whether to add the given region to the CSet chooser or
+ // not. Currently, we skip humongous regions (we never add them to
+ // the CSet, we only reclaim them during cleanup) and regions whose
+ // live bytes are over the threshold.
+ bool shouldAdd(HeapRegion* hr) {
+ assert(hr->is_marked(), "pre-condition");
+ assert(!hr->is_young(), "should never consider young regions");
+ return !hr->isHumongous() &&
+ hr->live_bytes() < _regionLiveThresholdBytes;
+ }
+
+ // Calculate the minimum number of old regions we'll add to the CSet
+ // during a mixed GC.
+ size_t calcMinOldCSetLength();
+
+ // Calculate the maximum number of old regions we'll add to the CSet
+ // during a mixed GC.
+ size_t calcMaxOldCSetLength();
+
+ // Serial version.
void addMarkedHeapRegion(HeapRegion *hr);
// Must be called before calls to getParMarkedHeapRegionChunk.
@@ -133,14 +169,21 @@
// Set the marked array entry at index to hr. Careful to claim the index
// first if in parallel.
void setMarkedHeapRegion(jint index, HeapRegion* hr);
- // Atomically increment the number of claimed regions by "inc_by".
- void incNumMarkedHeapRegions(jint inc_by);
+ // Atomically increment the number of added regions by region_num
+ // and the amount of reclaimable bytes by reclaimable_bytes.
+ void updateTotals(jint region_num, size_t reclaimable_bytes);
void clearMarkedHeapRegions();
- void updateAfterFullCollection();
+ // Return the number of candidate regions that remain to be collected.
+ size_t remainingRegions() { return _length - _curr_index; }
- bool unmarked_age_1_returned_as_new() { return _unmarked_age_1_returned_as_new; }
+ // Determine whether the CSet chooser has more candidate regions or not.
+ bool isEmpty() { return remainingRegions() == 0; }
+
+ // Return the reclaimable bytes that remain to be collected on
+ // all the candidate regions in the CSet chooser.
+ size_t remainingReclaimableBytes () { return _remainingReclaimableBytes; }
// Returns true if the used portion of "_markedRegions" is properly
// sorted, otherwise asserts false.
@@ -148,9 +191,17 @@
bool verify(void);
bool regionProperlyOrdered(HeapRegion* r) {
int si = r->sort_index();
- return (si == -1) ||
- (si > -1 && _markedRegions.at(si) == r) ||
- (si < -1 && _cache.region_in_cache(r));
+ if (si > -1) {
+ guarantee(_curr_index <= si && si < _length,
+ err_msg("curr: %d sort index: %d: length: %d",
+ _curr_index, si, _length));
+ guarantee(_markedRegions.at(si) == r,
+ err_msg("sort index: %d at: "PTR_FORMAT" r: "PTR_FORMAT,
+ si, _markedRegions.at(si), r));
+ } else {
+ guarantee(si == -1, err_msg("sort index: %d", si));
+ }
+ return true;
}
#endif
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -958,7 +958,7 @@
should_try_gc = false;
} else {
// Read the GC count while still holding the Heap_lock.
- gc_count_before = SharedHeap::heap()->total_collections();
+ gc_count_before = total_collections();
should_try_gc = true;
}
}
@@ -976,7 +976,7 @@
// failed to allocate. No point in trying to allocate
// further. We'll just return NULL.
MutexLockerEx x(Heap_lock);
- *gc_count_before_ret = SharedHeap::heap()->total_collections();
+ *gc_count_before_ret = total_collections();
return NULL;
}
} else {
@@ -1031,7 +1031,8 @@
// the check before we do the actual allocation. The reason for doing it
// before the allocation is that we avoid having to keep track of the newly
// allocated memory while we do a GC.
- if (g1_policy()->need_to_start_conc_mark("concurrent humongous allocation", word_size)) {
+ if (g1_policy()->need_to_start_conc_mark("concurrent humongous allocation",
+ word_size)) {
collect(GCCause::_g1_humongous_allocation);
}
@@ -1059,7 +1060,7 @@
should_try_gc = false;
} else {
// Read the GC count while still holding the Heap_lock.
- gc_count_before = SharedHeap::heap()->total_collections();
+ gc_count_before = total_collections();
should_try_gc = true;
}
}
@@ -1081,7 +1082,7 @@
// failed to allocate. No point in trying to allocate
// further. We'll just return NULL.
MutexLockerEx x(Heap_lock);
- *gc_count_before_ret = SharedHeap::heap()->total_collections();
+ *gc_count_before_ret = total_collections();
return NULL;
}
} else {
@@ -2311,10 +2312,12 @@
}
bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
- return
- ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
- (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
- cause == GCCause::_g1_humongous_allocation);
+ switch (cause) {
+ case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
+ case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
+ case GCCause::_g1_humongous_allocation: return true;
+ default: return false;
+ }
}
#ifndef PRODUCT
@@ -2408,47 +2411,66 @@
}
void G1CollectedHeap::collect(GCCause::Cause cause) {
- // The caller doesn't have the Heap_lock
- assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
+ assert_heap_not_locked();
unsigned int gc_count_before;
unsigned int full_gc_count_before;
- {
- MutexLocker ml(Heap_lock);
-
- // Read the GC count while holding the Heap_lock
- gc_count_before = SharedHeap::heap()->total_collections();
- full_gc_count_before = SharedHeap::heap()->total_full_collections();
- }
-
- if (should_do_concurrent_full_gc(cause)) {
- // Schedule an initial-mark evacuation pause that will start a
- // concurrent cycle. We're setting word_size to 0 which means that
- // we are not requesting a post-GC allocation.
- VM_G1IncCollectionPause op(gc_count_before,
- 0, /* word_size */
- true, /* should_initiate_conc_mark */
- g1_policy()->max_pause_time_ms(),
- cause);
- VMThread::execute(&op);
- } else {
- if (cause == GCCause::_gc_locker
- DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
-
- // Schedule a standard evacuation pause. We're setting word_size
- // to 0 which means that we are not requesting a post-GC allocation.
+ bool retry_gc;
+
+ do {
+ retry_gc = false;
+
+ {
+ MutexLocker ml(Heap_lock);
+
+ // Read the GC count while holding the Heap_lock
+ gc_count_before = total_collections();
+ full_gc_count_before = total_full_collections();
+ }
+
+ if (should_do_concurrent_full_gc(cause)) {
+ // Schedule an initial-mark evacuation pause that will start a
+ // concurrent cycle. We're setting word_size to 0 which means that
+ // we are not requesting a post-GC allocation.
VM_G1IncCollectionPause op(gc_count_before,
0, /* word_size */
- false, /* should_initiate_conc_mark */
+ true, /* should_initiate_conc_mark */
g1_policy()->max_pause_time_ms(),
cause);
VMThread::execute(&op);
+ if (!op.pause_succeeded()) {
+ // Another GC got scheduled and prevented us from scheduling
+ // the initial-mark GC. It's unlikely that the GC that
+ // pre-empted us was also an initial-mark GC. So, we'll retry
+ // the initial-mark GC.
+
+ if (full_gc_count_before == total_full_collections()) {
+ retry_gc = true;
+ } else {
+ // A Full GC happened while we were trying to schedule the
+ // initial-mark GC. No point in starting a new cycle given
+ // that the whole heap was collected anyway.
+ }
+ }
} else {
- // Schedule a Full GC.
- VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
- VMThread::execute(&op);
+ if (cause == GCCause::_gc_locker
+ DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
+
+ // Schedule a standard evacuation pause. We're setting word_size
+ // to 0 which means that we are not requesting a post-GC allocation.
+ VM_G1IncCollectionPause op(gc_count_before,
+ 0, /* word_size */
+ false, /* should_initiate_conc_mark */
+ g1_policy()->max_pause_time_ms(),
+ cause);
+ VMThread::execute(&op);
+ } else {
+ // Schedule a Full GC.
+ VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
+ VMThread::execute(&op);
+ }
}
- }
+ } while (retry_gc);
}
bool G1CollectedHeap::is_in(const void* p) const {
@@ -3149,12 +3171,12 @@
// We apply the relevant closures to all the oops in the
// system dictionary, the string table and the code cache.
- const int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
+ const int so = SO_AllClasses | SO_Strings | SO_CodeCache;
process_strong_roots(true, // activate StrongRootsScope
true, // we set "collecting perm gen" to true,
// so we don't reset the dirty cards in the perm gen.
- SharedHeap::ScanningOption(so), // roots scanning options
+ ScanningOption(so), // roots scanning options
&rootsCl,
&blobsCl,
&rootsCl);
@@ -3425,16 +3447,6 @@
}
}
-double G1CollectedHeap::predict_region_elapsed_time_ms(HeapRegion *hr,
- bool young) {
- return _g1_policy->predict_region_elapsed_time_ms(hr, young);
-}
-
-void G1CollectedHeap::check_if_region_is_too_expensive(double
- predicted_time_ms) {
- _g1_policy->check_if_region_is_too_expensive(predicted_time_ms);
-}
-
size_t G1CollectedHeap::pending_card_num() {
size_t extra_cards = 0;
JavaThread *curr = Threads::first();
@@ -3706,12 +3718,12 @@
g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
#endif // YOUNG_LIST_VERBOSE
- g1_policy()->choose_collection_set(target_pause_time_ms);
+ g1_policy()->finalize_cset(target_pause_time_ms);
_cm->note_start_of_gc();
// We should not verify the per-thread SATB buffers given that
// we have not filtered them yet (we'll do so during the
- // GC). We also call this after choose_collection_set() to
+ // GC). We also call this after finalize_cset() to
// ensure that the CSet has been finalized.
_cm->verify_no_cset_oops(true /* verify_stacks */,
true /* verify_enqueued_buffers */,
@@ -4734,7 +4746,7 @@
void
G1CollectedHeap::
g1_process_strong_roots(bool collecting_perm_gen,
- SharedHeap::ScanningOption so,
+ ScanningOption so,
OopClosure* scan_non_heap_roots,
OopsInHeapRegionClosure* scan_rs,
OopsInGenClosure* scan_perm,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -770,7 +770,7 @@
// the "i" of the calling parallel worker thread's work(i) function.
// In the sequential case this param will be ignored.
void g1_process_strong_roots(bool collecting_perm_gen,
- SharedHeap::ScanningOption so,
+ ScanningOption so,
OopClosure* scan_non_heap_roots,
OopsInHeapRegionClosure* scan_rs,
OopsInGenClosure* scan_perm,
@@ -1182,6 +1182,12 @@
bool free_regions_coming() { return _free_regions_coming; }
void wait_while_free_regions_coming();
+ // Determine whether the given region is one that we are using as an
+ // old GC alloc region.
+ bool is_old_gc_alloc_region(HeapRegion* hr) {
+ return hr == _retained_old_gc_alloc_region;
+ }
+
// Perform a collection of the heap; intended for use in implementing
// "System.gc". This probably implies as full a collection as the
// "CollectedHeap" supports.
@@ -1662,8 +1668,6 @@
public:
void stop_conc_gc_threads();
- double predict_region_elapsed_time_ms(HeapRegion* hr, bool young);
- void check_if_region_is_too_expensive(double predicted_time_ms);
size_t pending_card_num();
size_t max_pending_card_num();
size_t cards_scanned();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -206,7 +206,6 @@
_initiate_conc_mark_if_possible(false),
_during_initial_mark_pause(false),
- _should_revert_to_young_gcs(false),
_last_young_gc(false),
_last_gc_was_young(false),
@@ -295,9 +294,6 @@
_par_last_gc_worker_times_ms = new double[_parallel_gc_threads];
_par_last_gc_worker_other_times_ms = new double[_parallel_gc_threads];
- // start conservatively
- _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis;
-
int index;
if (ParallelGCThreads == 0)
index = 0;
@@ -629,16 +625,9 @@
// possible to maximize how many old regions we can add to it.
}
} else {
- if (gcs_are_young()) {
- young_list_target_length = _young_list_fixed_length;
- } else {
- // A bit arbitrary: during mixed GCs we allocate half
- // the young regions to try to add old regions to the CSet.
- young_list_target_length = _young_list_fixed_length / 2;
- // We choose to accept that we might go under the desired min
- // length given that we intentionally ask for a smaller young gen.
- desired_min_length = absolute_min_length;
- }
+ // The user asked for a fixed young gen so we'll fix the young gen
+ // whether the next GC is young or mixed.
+ young_list_target_length = _young_list_fixed_length;
}
// Make sure we don't go over the desired max length, nor under the
@@ -872,7 +861,6 @@
// transitions and make sure we start with young GCs after the Full GC.
set_gcs_are_young(true);
_last_young_gc = false;
- _should_revert_to_young_gcs = false;
clear_initiate_conc_mark_if_possible();
clear_during_initial_mark_pause();
_known_garbage_bytes = 0;
@@ -889,7 +877,7 @@
// Reset survivors SurvRateGroup.
_survivor_surv_rate_group->reset();
update_young_list_target_length();
- _collectionSetChooser->updateAfterFullCollection();
+ _collectionSetChooser->clearMarkedHeapRegions();
}
void G1CollectorPolicy::record_stop_world_start() {
@@ -1000,7 +988,6 @@
}
void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
- _should_revert_to_young_gcs = false;
_last_young_gc = true;
_in_marking_window = false;
}
@@ -1205,9 +1192,7 @@
last_pause_included_initial_mark = during_initial_mark_pause();
if (last_pause_included_initial_mark) {
record_concurrent_mark_init_end(0.0);
- }
-
- if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
+ } else if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
// Note: this might have already been set, if during the last
// pause we decided to start a cycle but at the beginning of
// this pause we decided to postpone it. That's OK.
@@ -1492,12 +1477,14 @@
}
if (_last_young_gc) {
+ // This is supposed to to be the "last young GC" before we start
+ // doing mixed GCs. Here we decide whether to start mixed GCs or not.
+
if (!last_pause_included_initial_mark) {
- ergo_verbose2(ErgoMixedGCs,
- "start mixed GCs",
- ergo_format_byte_perc("known garbage"),
- _known_garbage_bytes, _known_garbage_ratio * 100.0);
- set_gcs_are_young(false);
+ if (next_gc_should_be_mixed("start mixed GCs",
+ "do not start mixed GCs")) {
+ set_gcs_are_young(false);
+ }
} else {
ergo_verbose0(ErgoMixedGCs,
"do not start mixed GCs",
@@ -1507,39 +1494,14 @@
}
if (!_last_gc_was_young) {
- if (_should_revert_to_young_gcs) {
- ergo_verbose2(ErgoMixedGCs,
- "end mixed GCs",
- ergo_format_reason("mixed GCs end requested")
- ergo_format_byte_perc("known garbage"),
- _known_garbage_bytes, _known_garbage_ratio * 100.0);
- set_gcs_are_young(true);
- } else if (_known_garbage_ratio < 0.05) {
- ergo_verbose3(ErgoMixedGCs,
- "end mixed GCs",
- ergo_format_reason("known garbage percent lower than threshold")
- ergo_format_byte_perc("known garbage")
- ergo_format_perc("threshold"),
- _known_garbage_bytes, _known_garbage_ratio * 100.0,
- 0.05 * 100.0);
- set_gcs_are_young(true);
- } else if (adaptive_young_list_length() &&
- (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) {
- ergo_verbose5(ErgoMixedGCs,
- "end mixed GCs",
- ergo_format_reason("current GC efficiency lower than "
- "predicted young GC efficiency")
- ergo_format_double("GC efficiency factor")
- ergo_format_double("current GC efficiency")
- ergo_format_double("predicted young GC efficiency")
- ergo_format_byte_perc("known garbage"),
- get_gc_eff_factor(), cur_efficiency,
- predict_young_gc_eff(),
- _known_garbage_bytes, _known_garbage_ratio * 100.0);
+ // This is a mixed GC. Here we decide whether to continue doing
+ // mixed GCs or not.
+
+ if (!next_gc_should_be_mixed("continue mixed GCs",
+ "do not continue mixed GCs")) {
set_gcs_are_young(true);
}
}
- _should_revert_to_young_gcs = false;
if (_last_gc_was_young && !_during_marking) {
_young_gc_eff_seq->add(cur_efficiency);
@@ -1648,15 +1610,6 @@
_pending_cards_seq->add((double) _pending_cards);
_rs_lengths_seq->add((double) _max_rs_lengths);
-
- double expensive_region_limit_ms =
- (double) MaxGCPauseMillis - predict_constant_other_time_ms();
- if (expensive_region_limit_ms < 0.0) {
- // this means that the other time was predicted to be longer than
- // than the max pause time
- expensive_region_limit_ms = (double) MaxGCPauseMillis;
- }
- _expensive_region_limit_ms = expensive_region_limit_ms;
}
_in_marking_window = new_in_marking_window;
@@ -1838,13 +1791,11 @@
if (hr->is_marked())
bytes_to_copy = hr->max_live_bytes();
else {
- guarantee( hr->is_young() && hr->age_in_surv_rate_group() != -1,
- "invariant" );
+ assert(hr->is_young() && hr->age_in_surv_rate_group() != -1, "invariant");
int age = hr->age_in_surv_rate_group();
double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
}
-
return bytes_to_copy;
}
@@ -1860,22 +1811,6 @@
_recorded_rs_lengths = rs_lengths;
}
-void G1CollectorPolicy::check_if_region_is_too_expensive(double
- predicted_time_ms) {
- // I don't think we need to do this when in young GC mode since
- // marking will be initiated next time we hit the soft limit anyway...
- if (predicted_time_ms > _expensive_region_limit_ms) {
- ergo_verbose2(ErgoMixedGCs,
- "request mixed GCs end",
- ergo_format_reason("predicted region time higher than threshold")
- ergo_format_ms("predicted region time")
- ergo_format_ms("threshold"),
- predicted_time_ms, _expensive_region_limit_ms);
- // no point in doing another mixed GC
- _should_revert_to_young_gcs = true;
- }
-}
-
void G1CollectorPolicy::update_recent_gc_times(double end_time_sec,
double elapsed_ms) {
_recent_gc_times_ms->add(elapsed_ms);
@@ -2274,12 +2209,12 @@
}
class KnownGarbageClosure: public HeapRegionClosure {
+ G1CollectedHeap* _g1h;
CollectionSetChooser* _hrSorted;
public:
KnownGarbageClosure(CollectionSetChooser* hrSorted) :
- _hrSorted(hrSorted)
- {}
+ _g1h(G1CollectedHeap::heap()), _hrSorted(hrSorted) { }
bool doHeapRegion(HeapRegion* r) {
// We only include humongous regions in collection
@@ -2288,11 +2223,10 @@
// Do we have any marking information for this region?
if (r->is_marked()) {
- // We don't include humongous regions in collection
- // sets because we collect them immediately at the end of a marking
- // cycle. We also don't include young regions because we *must*
- // include them in the next collection pause.
- if (!r->isHumongous() && !r->is_young()) {
+ // We will skip any region that's currently used as an old GC
+ // alloc region (we should not consider those for collection
+ // before we fill them up).
+ if (_hrSorted->shouldAdd(r) && !_g1h->is_old_gc_alloc_region(r)) {
_hrSorted->addMarkedHeapRegion(r);
}
}
@@ -2301,8 +2235,10 @@
};
class ParKnownGarbageHRClosure: public HeapRegionClosure {
+ G1CollectedHeap* _g1h;
CollectionSetChooser* _hrSorted;
jint _marked_regions_added;
+ size_t _reclaimable_bytes_added;
jint _chunk_size;
jint _cur_chunk_idx;
jint _cur_chunk_end; // Cur chunk [_cur_chunk_idx, _cur_chunk_end)
@@ -2320,6 +2256,7 @@
assert(_cur_chunk_idx < _cur_chunk_end, "postcondition");
_hrSorted->setMarkedHeapRegion(_cur_chunk_idx, r);
_marked_regions_added++;
+ _reclaimable_bytes_added += r->reclaimable_bytes();
_cur_chunk_idx++;
}
@@ -2327,10 +2264,10 @@
ParKnownGarbageHRClosure(CollectionSetChooser* hrSorted,
jint chunk_size,
int worker) :
- _hrSorted(hrSorted), _chunk_size(chunk_size), _worker(worker),
- _marked_regions_added(0), _cur_chunk_idx(0), _cur_chunk_end(0),
- _invokes(0)
- {}
+ _g1h(G1CollectedHeap::heap()),
+ _hrSorted(hrSorted), _chunk_size(chunk_size), _worker(worker),
+ _marked_regions_added(0), _reclaimable_bytes_added(0),
+ _cur_chunk_idx(0), _cur_chunk_end(0), _invokes(0) { }
bool doHeapRegion(HeapRegion* r) {
// We only include humongous regions in collection
@@ -2340,17 +2277,17 @@
// Do we have any marking information for this region?
if (r->is_marked()) {
- // We don't include humongous regions in collection
- // sets because we collect them immediately at the end of a marking
- // cycle.
- // We also do not include young regions in collection sets
- if (!r->isHumongous() && !r->is_young()) {
+ // We will skip any region that's currently used as an old GC
+ // alloc region (we should not consider those for collection
+ // before we fill them up).
+ if (_hrSorted->shouldAdd(r) && !_g1h->is_old_gc_alloc_region(r)) {
add_region(r);
}
}
return false;
}
jint marked_regions_added() { return _marked_regions_added; }
+ size_t reclaimable_bytes_added() { return _reclaimable_bytes_added; }
int invokes() { return _invokes; }
};
@@ -2362,8 +2299,7 @@
ParKnownGarbageTask(CollectionSetChooser* hrSorted, jint chunk_size) :
AbstractGangTask("ParKnownGarbageTask"),
_hrSorted(hrSorted), _chunk_size(chunk_size),
- _g1(G1CollectedHeap::heap())
- {}
+ _g1(G1CollectedHeap::heap()) { }
void work(uint worker_id) {
ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted,
@@ -2374,7 +2310,9 @@
_g1->workers()->active_workers(),
HeapRegion::InitialClaimValue);
jint regions_added = parKnownGarbageCl.marked_regions_added();
- _hrSorted->incNumMarkedHeapRegions(regions_added);
+ size_t reclaimable_bytes_added =
+ parKnownGarbageCl.reclaimable_bytes_added();
+ _hrSorted->updateTotals(regions_added, reclaimable_bytes_added);
if (G1PrintParCleanupStats) {
gclog_or_tty->print_cr(" Thread %d called %d times, added %d regions to list.",
worker_id, parKnownGarbageCl.invokes(), regions_added);
@@ -2658,7 +2596,43 @@
}
#endif // !PRODUCT
-void G1CollectorPolicy::choose_collection_set(double target_pause_time_ms) {
+bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
+ const char* false_action_str) {
+ CollectionSetChooser* cset_chooser = _collectionSetChooser;
+ if (cset_chooser->isEmpty()) {
+ ergo_verbose0(ErgoMixedGCs,
+ false_action_str,
+ ergo_format_reason("candidate old regions not available"));
+ return false;
+ }
+ size_t reclaimable_bytes = cset_chooser->remainingReclaimableBytes();
+ size_t capacity_bytes = _g1->capacity();
+ double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+ double threshold = (double) G1OldReclaimableThresholdPercent;
+ if (perc < threshold) {
+ ergo_verbose4(ErgoMixedGCs,
+ false_action_str,
+ ergo_format_reason("reclaimable percentage lower than threshold")
+ ergo_format_region("candidate old regions")
+ ergo_format_byte_perc("reclaimable")
+ ergo_format_perc("threshold"),
+ cset_chooser->remainingRegions(),
+ reclaimable_bytes, perc, threshold);
+ return false;
+ }
+
+ ergo_verbose4(ErgoMixedGCs,
+ true_action_str,
+ ergo_format_reason("candidate old regions available")
+ ergo_format_region("candidate old regions")
+ ergo_format_byte_perc("reclaimable")
+ ergo_format_perc("threshold"),
+ cset_chooser->remainingRegions(),
+ reclaimable_bytes, perc, threshold);
+ return true;
+}
+
+void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
// Set this here - in case we're not doing young collections.
double non_young_start_time_sec = os::elapsedTime();
@@ -2672,7 +2646,6 @@
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
double predicted_pause_time_ms = base_time_ms;
-
double time_remaining_ms = target_pause_time_ms - base_time_ms;
ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
@@ -2682,22 +2655,6 @@
ergo_format_ms("target pause time"),
base_time_ms, time_remaining_ms, target_pause_time_ms);
- // the 10% and 50% values are arbitrary...
- double threshold = 0.10 * target_pause_time_ms;
- if (time_remaining_ms < threshold) {
- double prev_time_remaining_ms = time_remaining_ms;
- time_remaining_ms = 0.50 * target_pause_time_ms;
- ergo_verbose3(ErgoCSetConstruction,
- "adjust remaining time",
- ergo_format_reason("remaining time lower than threshold")
- ergo_format_ms("remaining time")
- ergo_format_ms("threshold")
- ergo_format_ms("adjusted remaining time"),
- prev_time_remaining_ms, threshold, time_remaining_ms);
- }
-
- size_t expansion_bytes = _g1->expansion_regions() * HeapRegion::GrainBytes;
-
HeapRegion* hr;
double young_start_time_sec = os::elapsedTime();
@@ -2752,78 +2709,97 @@
non_young_start_time_sec = young_end_time_sec;
if (!gcs_are_young()) {
- bool should_continue = true;
- NumberSeq seq;
- double avg_prediction = 100000000000000000.0; // something very large
-
- double prev_predicted_pause_time_ms = predicted_pause_time_ms;
- do {
- // Note that add_old_region_to_cset() increments the
- // _old_cset_region_length field and cset_region_length() returns the
- // sum of _eden_cset_region_length, _survivor_cset_region_length, and
- // _old_cset_region_length. So, as old regions are added to the
- // CSet, _old_cset_region_length will be incremented and
- // cset_region_length(), which is used below, will always reflect
- // the the total number of regions added up to this point to the CSet.
-
- hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
- avg_prediction);
- if (hr != NULL) {
- _g1->old_set_remove(hr);
- double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
- time_remaining_ms -= predicted_time_ms;
- predicted_pause_time_ms += predicted_time_ms;
- add_old_region_to_cset(hr);
- seq.add(predicted_time_ms);
- avg_prediction = seq.avg() + seq.sd();
+ CollectionSetChooser* cset_chooser = _collectionSetChooser;
+ assert(cset_chooser->verify(), "CSet Chooser verification - pre");
+ const size_t min_old_cset_length = cset_chooser->calcMinOldCSetLength();
+ const size_t max_old_cset_length = cset_chooser->calcMaxOldCSetLength();
+
+ size_t expensive_region_num = 0;
+ bool check_time_remaining = adaptive_young_list_length();
+ HeapRegion* hr = cset_chooser->peek();
+ while (hr != NULL) {
+ if (old_cset_region_length() >= max_old_cset_length) {
+ // Added maximum number of old regions to the CSet.
+ ergo_verbose2(ErgoCSetConstruction,
+ "finish adding old regions to CSet",
+ ergo_format_reason("old CSet region num reached max")
+ ergo_format_region("old")
+ ergo_format_region("max"),
+ old_cset_region_length(), max_old_cset_length);
+ break;
}
- should_continue = true;
- if (hr == NULL) {
- // No need for an ergo verbose message here,
- // getNextMarkRegion() does this when it returns NULL.
- should_continue = false;
+ double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
+ if (check_time_remaining) {
+ if (predicted_time_ms > time_remaining_ms) {
+ // Too expensive for the current CSet.
+
+ if (old_cset_region_length() >= min_old_cset_length) {
+ // We have added the minimum number of old regions to the CSet,
+ // we are done with this CSet.
+ ergo_verbose4(ErgoCSetConstruction,
+ "finish adding old regions to CSet",
+ ergo_format_reason("predicted time is too high")
+ ergo_format_ms("predicted time")
+ ergo_format_ms("remaining time")
+ ergo_format_region("old")
+ ergo_format_region("min"),
+ predicted_time_ms, time_remaining_ms,
+ old_cset_region_length(), min_old_cset_length);
+ break;
+ }
+
+ // We'll add it anyway given that we haven't reached the
+ // minimum number of old regions.
+ expensive_region_num += 1;
+ }
} else {
- if (adaptive_young_list_length()) {
- if (time_remaining_ms < 0.0) {
- ergo_verbose1(ErgoCSetConstruction,
- "stop adding old regions to CSet",
- ergo_format_reason("remaining time is lower than 0")
- ergo_format_ms("remaining time"),
- time_remaining_ms);
- should_continue = false;
- }
- } else {
- if (cset_region_length() >= _young_list_fixed_length) {
- ergo_verbose2(ErgoCSetConstruction,
- "stop adding old regions to CSet",
- ergo_format_reason("CSet length reached target")
- ergo_format_region("CSet")
- ergo_format_region("young target"),
- cset_region_length(), _young_list_fixed_length);
- should_continue = false;
- }
+ if (old_cset_region_length() >= min_old_cset_length) {
+ // In the non-auto-tuning case, we'll finish adding regions
+ // to the CSet if we reach the minimum.
+ ergo_verbose2(ErgoCSetConstruction,
+ "finish adding old regions to CSet",
+ ergo_format_reason("old CSet region num reached min")
+ ergo_format_region("old")
+ ergo_format_region("min"),
+ old_cset_region_length(), min_old_cset_length);
+ break;
}
}
- } while (should_continue);
-
- if (!adaptive_young_list_length() &&
- cset_region_length() < _young_list_fixed_length) {
- ergo_verbose2(ErgoCSetConstruction,
- "request mixed GCs end",
- ergo_format_reason("CSet length lower than target")
- ergo_format_region("CSet")
- ergo_format_region("young target"),
- cset_region_length(), _young_list_fixed_length);
- _should_revert_to_young_gcs = true;
+
+ // We will add this region to the CSet.
+ time_remaining_ms -= predicted_time_ms;
+ predicted_pause_time_ms += predicted_time_ms;
+ cset_chooser->remove_and_move_to_next(hr);
+ _g1->old_set_remove(hr);
+ add_old_region_to_cset(hr);
+
+ hr = cset_chooser->peek();
+ }
+ if (hr == NULL) {
+ ergo_verbose0(ErgoCSetConstruction,
+ "finish adding old regions to CSet",
+ ergo_format_reason("candidate old regions not available"));
}
- ergo_verbose2(ErgoCSetConstruction | ErgoHigh,
- "add old regions to CSet",
- ergo_format_region("old")
- ergo_format_ms("predicted old region time"),
- old_cset_region_length(),
- predicted_pause_time_ms - prev_predicted_pause_time_ms);
+ if (expensive_region_num > 0) {
+ // We print the information once here at the end, predicated on
+ // whether we added any apparently expensive regions or not, to
+ // avoid generating output per region.
+ ergo_verbose4(ErgoCSetConstruction,
+ "added expensive regions to CSet",
+ ergo_format_reason("old CSet region num not reached min")
+ ergo_format_region("old")
+ ergo_format_region("expensive")
+ ergo_format_region("min")
+ ergo_format_ms("remaining time"),
+ old_cset_region_length(),
+ expensive_region_num,
+ min_old_cset_length,
+ time_remaining_ms);
+ }
+
+ assert(cset_chooser->verify(), "CSet Chooser verification - post");
}
stop_incremental_cset_building();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -312,16 +312,13 @@
double _recorded_non_young_free_cset_time_ms;
double _sigma;
- double _expensive_region_limit_ms;
size_t _rs_lengths_prediction;
size_t _known_garbage_bytes;
double _known_garbage_ratio;
- double sigma() {
- return _sigma;
- }
+ double sigma() { return _sigma; }
// A function that prevents us putting too much stock in small sample
// sets. Returns a number between 2.0 and 1.0, depending on the number
@@ -491,8 +488,6 @@
get_new_prediction(_non_young_other_cost_per_region_ms_seq);
}
- void check_if_region_is_too_expensive(double predicted_time_ms);
-
double predict_young_collection_elapsed_time_ms(size_t adjustment);
double predict_base_elapsed_time_ms(size_t pending_cards);
double predict_base_elapsed_time_ms(size_t pending_cards,
@@ -707,7 +702,6 @@
// initial-mark work.
volatile bool _during_initial_mark_pause;
- bool _should_revert_to_young_gcs;
bool _last_young_gc;
// This set of variables tracks the collector efficiency, in order to
@@ -946,10 +940,17 @@
return _bytes_copied_during_gc;
}
+ // Determine whether the next GC should be mixed. Called to determine
+ // whether to start mixed GCs or whether to carry on doing mixed
+ // GCs. The two action strings are used in the ergo output when the
+ // method returns true or false.
+ bool next_gc_should_be_mixed(const char* true_action_str,
+ const char* false_action_str);
+
// Choose a new collection set. Marks the chosen regions as being
// "in_collection_set", and links them together. The head and number of
// the collection set are available via access methods.
- void choose_collection_set(double target_pause_time_ms);
+ void finalize_cset(double target_pause_time_ms);
// The head of the list (via "next_in_collection_set()") representing the
// current collection set.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -131,8 +131,8 @@
", " _name_ ": "SIZE_FORMAT" bytes (%1.2f %%)"
// Generates the format string
-#define ergo_format(_action_, _extra_format_) \
- " %1.3f: [G1Ergonomics (%s) " _action_ _extra_format_ "]"
+#define ergo_format(_extra_format_) \
+ " %1.3f: [G1Ergonomics (%s) %s" _extra_format_ "]"
// Conditionally, prints an ergonomic decision record. _extra_format_
// is the format string for the optional items we'd like to print
@@ -145,20 +145,21 @@
// them to the print method. For convenience, we have wrapper macros
// below which take a specific number of arguments and set the rest to
// a default value.
-#define ergo_verbose_common(_tag_, _action_, _extra_format_, \
+#define ergo_verbose_common(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
- do { \
- if (G1ErgoVerbose::enabled((_tag_))) { \
- gclog_or_tty->print_cr(ergo_format(_action_, _extra_format_), \
- os::elapsedTime(), \
- G1ErgoVerbose::to_string((_tag_)), \
- (_arg0_), (_arg1_), (_arg2_), \
- (_arg3_), (_arg4_), (_arg5_)); \
- } \
+ do { \
+ if (G1ErgoVerbose::enabled((_tag_))) { \
+ gclog_or_tty->print_cr(ergo_format(_extra_format_), \
+ os::elapsedTime(), \
+ G1ErgoVerbose::to_string((_tag_)), \
+ (_action_), \
+ (_arg0_), (_arg1_), (_arg2_), \
+ (_arg3_), (_arg4_), (_arg5_)); \
+ } \
} while (0)
-#define ergo_verbose(_tag_, _action_) \
+#define ergo_verbose(_tag_, _action_) \
ergo_verbose_common(_tag_, _action_, "", 0, 0, 0, 0, 0, 0)
#define ergo_verbose0(_tag_, _action_, _extra_format_) \
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -297,7 +297,23 @@
\
develop(uintx, G1DefaultMaxNewGenPercent, 80, \
"Percentage (0-100) of the heap size to use as maximum " \
- "young gen size.")
+ "young gen size.") \
+ \
+ develop(uintx, G1OldCSetRegionLiveThresholdPercent, 95, \
+ "Threshold for regions to be added to the collection set. " \
+ "Regions with more live bytes that this will not be collected.") \
+ \
+ develop(uintx, G1OldReclaimableThresholdPercent, 1, \
+ "Threshold for the remaining old reclaimable bytes, expressed " \
+ "as a percentage of the heap size. If the old reclaimable bytes " \
+ "are under this we will not collect them with more mixed GCs.") \
+ \
+ develop(uintx, G1MaxMixedGCNum, 4, \
+ "The maximum desired number of mixed GCs after a marking cycle.") \
+ \
+ develop(uintx, G1OldCSetRegionThresholdPercent, 10, \
+ "An upper bound for the number of old CSet regions expressed " \
+ "as a percentage of the heap size.")
G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -387,13 +387,12 @@
ct_bs->clear(MemRegion(bottom(), end()));
}
-// <PREDICTION>
void HeapRegion::calc_gc_efficiency() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- _gc_efficiency = (double) garbage_bytes() /
- g1h->predict_region_elapsed_time_ms(this, false);
+ G1CollectorPolicy* g1p = g1h->g1_policy();
+ _gc_efficiency = (double) reclaimable_bytes() /
+ g1p->predict_region_elapsed_time_ms(this, false);
}
-// </PREDICTION>
void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) {
assert(!isHumongous(), "sanity / pre-condition");
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -415,6 +415,16 @@
return used_at_mark_start_bytes - marked_bytes();
}
+ // Return the amount of bytes we'll reclaim if we collect this
+ // region. This includes not only the known garbage bytes in the
+ // region but also any unallocated space in it, i.e., [top, end),
+ // since it will also be reclaimed if we collect the region.
+ size_t reclaimable_bytes() {
+ size_t known_live_bytes = live_bytes();
+ assert(known_live_bytes <= capacity(), "sanity");
+ return capacity() - known_live_bytes;
+ }
+
// An upper bound on the number of live bytes in the region.
size_t max_live_bytes() { return used() - garbage_bytes(); }
@@ -648,10 +658,8 @@
init_top_at_mark_start();
}
- // <PREDICTION>
void calc_gc_efficiency(void);
double gc_efficiency() { return _gc_efficiency;}
- // </PREDICTION>
bool is_young() const { return _young_type != NotYoung; }
bool is_survivor() const { return _young_type == Survivor; }
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -1042,7 +1042,11 @@
size_policy->avg_survived()->sample(from()->used());
}
- update_time_of_last_gc(os::javaTimeMillis());
+ // We need to use a monotonically non-deccreasing time in ms
+ // or we will see time-warp warnings and os::javaTimeMillis()
+ // does not guarantee monotonicity.
+ jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ update_time_of_last_gc(now);
SpecializationStats::print();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -418,25 +418,17 @@
gc_count = Universe::heap()->total_collections();
result = young_gen()->allocate(size);
-
- // (1) If the requested object is too large to easily fit in the
- // young_gen, or
- // (2) If GC is locked out via GCLocker, young gen is full and
- // the need for a GC already signalled to GCLocker (done
- // at a safepoint),
- // ... then, rather than force a safepoint and (a potentially futile)
- // collection (attempt) for each allocation, try allocation directly
- // in old_gen. For case (2) above, we may in the future allow
- // TLAB allocation directly in the old gen.
if (result != NULL) {
return result;
}
- if (size >= (young_gen()->eden_space()->capacity_in_words(Thread::current()) / 2)) {
- result = old_gen()->allocate(size);
- if (result != NULL) {
- return result;
- }
+
+ // If certain conditions hold, try allocating from the old gen.
+ result = mem_allocate_old_gen(size);
+ if (result != NULL) {
+ return result;
}
+
+ // Failed to allocate without a gc.
if (GC_locker::is_active_and_needs_gc()) {
// If this thread is not in a jni critical section, we stall
// the requestor until the critical section has cleared and
@@ -460,7 +452,6 @@
}
if (result == NULL) {
-
// Generate a VM operation
VM_ParallelGCFailedAllocation op(size, gc_count);
VMThread::execute(&op);
@@ -523,6 +514,42 @@
return result;
}
+// A "death march" is a series of ultra-slow allocations in which a full gc is
+// done before each allocation, and after the full gc the allocation still
+// cannot be satisfied from the young gen. This routine detects that condition;
+// it should be called after a full gc has been done and the allocation
+// attempted from the young gen. The parameter 'addr' should be the result of
+// that young gen allocation attempt.
+void
+ParallelScavengeHeap::death_march_check(HeapWord* const addr, size_t size) {
+ if (addr != NULL) {
+ _death_march_count = 0; // death march has ended
+ } else if (_death_march_count == 0) {
+ if (should_alloc_in_eden(size)) {
+ _death_march_count = 1; // death march has started
+ }
+ }
+}
+
+HeapWord* ParallelScavengeHeap::mem_allocate_old_gen(size_t size) {
+ if (!should_alloc_in_eden(size) || GC_locker::is_active_and_needs_gc()) {
+ // Size is too big for eden, or gc is locked out.
+ return old_gen()->allocate(size);
+ }
+
+ // If a "death march" is in progress, allocate from the old gen a limited
+ // number of times before doing a GC.
+ if (_death_march_count > 0) {
+ if (_death_march_count < 64) {
+ ++_death_march_count;
+ return old_gen()->allocate(size);
+ } else {
+ _death_march_count = 0;
+ }
+ }
+ return NULL;
+}
+
// Failed allocation policy. Must be called from the VM thread, and
// only at a safepoint! Note that this method has policy for allocation
// flow, and NOT collection policy. So we do not check for gc collection
@@ -535,27 +562,22 @@
assert(!Universe::heap()->is_gc_active(), "not reentrant");
assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
- size_t mark_sweep_invocation_count = total_invocations();
-
- // We assume (and assert!) that an allocation at this point will fail
- // unless we collect.
+ // We assume that allocation in eden will fail unless we collect.
// First level allocation failure, scavenge and allocate in young gen.
GCCauseSetter gccs(this, GCCause::_allocation_failure);
- PSScavenge::invoke();
+ const bool invoked_full_gc = PSScavenge::invoke();
HeapWord* result = young_gen()->allocate(size);
// Second level allocation failure.
// Mark sweep and allocate in young generation.
- if (result == NULL) {
- // There is some chance the scavenge method decided to invoke mark_sweep.
- // Don't mark sweep twice if so.
- if (mark_sweep_invocation_count == total_invocations()) {
- invoke_full_gc(false);
- result = young_gen()->allocate(size);
- }
+ if (result == NULL && !invoked_full_gc) {
+ invoke_full_gc(false);
+ result = young_gen()->allocate(size);
}
+ death_march_check(result, size);
+
// Third level allocation failure.
// After mark sweep and young generation allocation failure,
// allocate in old generation.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -64,6 +64,7 @@
// Collection of generations that are adjacent in the
// space reserved for the heap.
AdjoiningGenerations* _gens;
+ unsigned int _death_march_count;
static GCTaskManager* _gc_task_manager; // The task manager.
@@ -71,8 +72,13 @@
static inline size_t total_invocations();
HeapWord* allocate_new_tlab(size_t size);
+ inline bool should_alloc_in_eden(size_t size) const;
+ inline void death_march_check(HeapWord* const result, size_t size);
+ HeapWord* mem_allocate_old_gen(size_t size);
+
public:
ParallelScavengeHeap() : CollectedHeap() {
+ _death_march_count = 0;
set_alignment(_perm_gen_alignment, intra_heap_alignment());
set_alignment(_young_gen_alignment, intra_heap_alignment());
set_alignment(_old_gen_alignment, intra_heap_alignment());
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -36,6 +36,12 @@
PSMarkSweep::total_invocations();
}
+inline bool ParallelScavengeHeap::should_alloc_in_eden(const size_t size) const
+{
+ const size_t eden_size = young_gen()->eden_space()->capacity_in_words();
+ return size < eden_size / 2;
+}
+
inline void ParallelScavengeHeap::invoke_scavenge()
{
PSScavenge::invoke();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -100,12 +100,12 @@
// This method contains no policy. You should probably
// be calling invoke() instead.
-void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
+bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
assert(ref_processor() != NULL, "Sanity");
if (GC_locker::check_active_before_gc()) {
- return;
+ return false;
}
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
@@ -382,6 +382,8 @@
#ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts();
#endif
+
+ return true;
}
bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -78,7 +78,7 @@
public:
static void invoke(bool clear_all_softrefs);
- static void invoke_no_policy(bool clear_all_softrefs);
+ static bool invoke_no_policy(bool clear_all_softrefs);
static void initialize();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1993,12 +1993,12 @@
// This method contains no policy. You should probably
// be calling invoke() instead.
-void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
+bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
assert(ref_processor() != NULL, "Sanity");
if (GC_locker::check_active_before_gc()) {
- return;
+ return false;
}
TimeStamp marking_start;
@@ -2248,6 +2248,8 @@
#ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts();
#endif
+
+ return true;
}
bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -1057,7 +1057,7 @@
}
static void invoke(bool maximum_heap_compaction);
- static void invoke_no_policy(bool maximum_heap_compaction);
+ static bool invoke_no_policy(bool maximum_heap_compaction);
static void post_initialize();
// Perform initialization for PSParallelCompact that requires
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -247,167 +247,6 @@
}
}
-//
-// This method is pretty bulky. It would be nice to split it up
-// into smaller submethods, but we need to be careful not to hurt
-// performance.
-//
-
-oop PSPromotionManager::copy_to_survivor_space(oop o) {
- assert(PSScavenge::should_scavenge(&o), "Sanity");
-
- oop new_obj = NULL;
-
- // NOTE! We must be very careful with any methods that access the mark
- // in o. There may be multiple threads racing on it, and it may be forwarded
- // at any time. Do not use oop methods for accessing the mark!
- markOop test_mark = o->mark();
-
- // The same test as "o->is_forwarded()"
- if (!test_mark->is_marked()) {
- bool new_obj_is_tenured = false;
- size_t new_obj_size = o->size();
-
- // Find the objects age, MT safe.
- int age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
- test_mark->displaced_mark_helper()->age() : test_mark->age();
-
- // Try allocating obj in to-space (unless too old)
- if (age < PSScavenge::tenuring_threshold()) {
- new_obj = (oop) _young_lab.allocate(new_obj_size);
- if (new_obj == NULL && !_young_gen_is_full) {
- // Do we allocate directly, or flush and refill?
- if (new_obj_size > (YoungPLABSize / 2)) {
- // Allocate this object directly
- new_obj = (oop)young_space()->cas_allocate(new_obj_size);
- } else {
- // Flush and fill
- _young_lab.flush();
-
- HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize);
- if (lab_base != NULL) {
- _young_lab.initialize(MemRegion(lab_base, YoungPLABSize));
- // Try the young lab allocation again.
- new_obj = (oop) _young_lab.allocate(new_obj_size);
- } else {
- _young_gen_is_full = true;
- }
- }
- }
- }
-
- // Otherwise try allocating obj tenured
- if (new_obj == NULL) {
-#ifndef PRODUCT
- if (Universe::heap()->promotion_should_fail()) {
- return oop_promotion_failed(o, test_mark);
- }
-#endif // #ifndef PRODUCT
-
- new_obj = (oop) _old_lab.allocate(new_obj_size);
- new_obj_is_tenured = true;
-
- if (new_obj == NULL) {
- if (!_old_gen_is_full) {
- // Do we allocate directly, or flush and refill?
- if (new_obj_size > (OldPLABSize / 2)) {
- // Allocate this object directly
- new_obj = (oop)old_gen()->cas_allocate(new_obj_size);
- } else {
- // Flush and fill
- _old_lab.flush();
-
- HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
- if(lab_base != NULL) {
- _old_lab.initialize(MemRegion(lab_base, OldPLABSize));
- // Try the old lab allocation again.
- new_obj = (oop) _old_lab.allocate(new_obj_size);
- }
- }
- }
-
- // This is the promotion failed test, and code handling.
- // The code belongs here for two reasons. It is slightly
- // different thatn the code below, and cannot share the
- // CAS testing code. Keeping the code here also minimizes
- // the impact on the common case fast path code.
-
- if (new_obj == NULL) {
- _old_gen_is_full = true;
- return oop_promotion_failed(o, test_mark);
- }
- }
- }
-
- assert(new_obj != NULL, "allocation should have succeeded");
-
- // Copy obj
- Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)new_obj, new_obj_size);
-
- // Now we have to CAS in the header.
- if (o->cas_forward_to(new_obj, test_mark)) {
- // We won any races, we "own" this object.
- assert(new_obj == o->forwardee(), "Sanity");
-
- // Increment age if obj still in new generation. Now that
- // we're dealing with a markOop that cannot change, it is
- // okay to use the non mt safe oop methods.
- if (!new_obj_is_tenured) {
- new_obj->incr_age();
- assert(young_space()->contains(new_obj), "Attempt to push non-promoted obj");
- }
-
- // Do the size comparison first with new_obj_size, which we
- // already have. Hopefully, only a few objects are larger than
- // _min_array_size_for_chunking, and most of them will be arrays.
- // So, the is->objArray() test would be very infrequent.
- if (new_obj_size > _min_array_size_for_chunking &&
- new_obj->is_objArray() &&
- PSChunkLargeArrays) {
- // we'll chunk it
- oop* const masked_o = mask_chunked_array_oop(o);
- push_depth(masked_o);
- TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_masked_pushes);
- } else {
- // we'll just push its contents
- new_obj->push_contents(this);
- }
- } else {
- // We lost, someone else "owns" this object
- guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
-
- // Try to deallocate the space. If it was directly allocated we cannot
- // deallocate it, so we have to test. If the deallocation fails,
- // overwrite with a filler object.
- if (new_obj_is_tenured) {
- if (!_old_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
- CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
- }
- } else if (!_young_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
- CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
- }
-
- // don't update this before the unallocation!
- new_obj = o->forwardee();
- }
- } else {
- assert(o->is_forwarded(), "Sanity");
- new_obj = o->forwardee();
- }
-
-#ifdef DEBUG
- // 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 " (" SIZE_FORMAT ")}",
- PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
- new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
- }
-#endif
-
- return new_obj;
-}
-
template <class T> void PSPromotionManager::process_array_chunk_work(
oop obj,
int start, int end) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -171,7 +171,7 @@
void set_old_gen_is_full(bool state) { _old_gen_is_full = state; }
// Promotion methods
- oop copy_to_survivor_space(oop o);
+ template<bool promote_immediately> oop copy_to_survivor_space(oop o);
oop oop_promotion_failed(oop obj, markOop obj_mark);
void reset();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -61,6 +61,170 @@
claim_or_forward_internal_depth(p);
}
+//
+// This method is pretty bulky. It would be nice to split it up
+// into smaller submethods, but we need to be careful not to hurt
+// performance.
+//
+template<bool promote_immediately>
+oop PSPromotionManager::copy_to_survivor_space(oop o) {
+ assert(PSScavenge::should_scavenge(&o), "Sanity");
+
+ oop new_obj = NULL;
+
+ // NOTE! We must be very careful with any methods that access the mark
+ // in o. There may be multiple threads racing on it, and it may be forwarded
+ // at any time. Do not use oop methods for accessing the mark!
+ markOop test_mark = o->mark();
+
+ // The same test as "o->is_forwarded()"
+ if (!test_mark->is_marked()) {
+ bool new_obj_is_tenured = false;
+ size_t new_obj_size = o->size();
+
+ if (!promote_immediately) {
+ // Find the objects age, MT safe.
+ int age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
+ test_mark->displaced_mark_helper()->age() : test_mark->age();
+
+ // Try allocating obj in to-space (unless too old)
+ if (age < PSScavenge::tenuring_threshold()) {
+ new_obj = (oop) _young_lab.allocate(new_obj_size);
+ if (new_obj == NULL && !_young_gen_is_full) {
+ // Do we allocate directly, or flush and refill?
+ if (new_obj_size > (YoungPLABSize / 2)) {
+ // Allocate this object directly
+ new_obj = (oop)young_space()->cas_allocate(new_obj_size);
+ } else {
+ // Flush and fill
+ _young_lab.flush();
+
+ HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize);
+ if (lab_base != NULL) {
+ _young_lab.initialize(MemRegion(lab_base, YoungPLABSize));
+ // Try the young lab allocation again.
+ new_obj = (oop) _young_lab.allocate(new_obj_size);
+ } else {
+ _young_gen_is_full = true;
+ }
+ }
+ }
+ }
+ }
+
+ // Otherwise try allocating obj tenured
+ if (new_obj == NULL) {
+#ifndef PRODUCT
+ if (Universe::heap()->promotion_should_fail()) {
+ return oop_promotion_failed(o, test_mark);
+ }
+#endif // #ifndef PRODUCT
+
+ new_obj = (oop) _old_lab.allocate(new_obj_size);
+ new_obj_is_tenured = true;
+
+ if (new_obj == NULL) {
+ if (!_old_gen_is_full) {
+ // Do we allocate directly, or flush and refill?
+ if (new_obj_size > (OldPLABSize / 2)) {
+ // Allocate this object directly
+ new_obj = (oop)old_gen()->cas_allocate(new_obj_size);
+ } else {
+ // Flush and fill
+ _old_lab.flush();
+
+ HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
+ if(lab_base != NULL) {
+ _old_lab.initialize(MemRegion(lab_base, OldPLABSize));
+ // Try the old lab allocation again.
+ new_obj = (oop) _old_lab.allocate(new_obj_size);
+ }
+ }
+ }
+
+ // This is the promotion failed test, and code handling.
+ // The code belongs here for two reasons. It is slightly
+ // different thatn the code below, and cannot share the
+ // CAS testing code. Keeping the code here also minimizes
+ // the impact on the common case fast path code.
+
+ if (new_obj == NULL) {
+ _old_gen_is_full = true;
+ return oop_promotion_failed(o, test_mark);
+ }
+ }
+ }
+
+ assert(new_obj != NULL, "allocation should have succeeded");
+
+ // Copy obj
+ Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)new_obj, new_obj_size);
+
+ // Now we have to CAS in the header.
+ if (o->cas_forward_to(new_obj, test_mark)) {
+ // We won any races, we "own" this object.
+ assert(new_obj == o->forwardee(), "Sanity");
+
+ // Increment age if obj still in new generation. Now that
+ // we're dealing with a markOop that cannot change, it is
+ // okay to use the non mt safe oop methods.
+ if (!new_obj_is_tenured) {
+ new_obj->incr_age();
+ assert(young_space()->contains(new_obj), "Attempt to push non-promoted obj");
+ }
+
+ // Do the size comparison first with new_obj_size, which we
+ // already have. Hopefully, only a few objects are larger than
+ // _min_array_size_for_chunking, and most of them will be arrays.
+ // So, the is->objArray() test would be very infrequent.
+ if (new_obj_size > _min_array_size_for_chunking &&
+ new_obj->is_objArray() &&
+ PSChunkLargeArrays) {
+ // we'll chunk it
+ oop* const masked_o = mask_chunked_array_oop(o);
+ push_depth(masked_o);
+ TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_masked_pushes);
+ } else {
+ // we'll just push its contents
+ new_obj->push_contents(this);
+ }
+ } else {
+ // We lost, someone else "owns" this object
+ guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
+
+ // Try to deallocate the space. If it was directly allocated we cannot
+ // deallocate it, so we have to test. If the deallocation fails,
+ // overwrite with a filler object.
+ if (new_obj_is_tenured) {
+ if (!_old_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
+ CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
+ }
+ } else if (!_young_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
+ CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
+ }
+
+ // don't update this before the unallocation!
+ new_obj = o->forwardee();
+ }
+ } else {
+ assert(o->is_forwarded(), "Sanity");
+ new_obj = o->forwardee();
+ }
+
+#ifdef DEBUG
+ // 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 " (" SIZE_FORMAT ")}",
+ PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
+ new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
+ }
+#endif
+
+ return new_obj;
+}
+
+
inline void PSPromotionManager::process_popped_location_depth(StarTask p) {
if (is_oop_masked(p)) {
assert(PSChunkLargeArrays, "invariant");
@@ -69,9 +233,9 @@
} else {
if (p.is_narrow()) {
assert(UseCompressedOops, "Error");
- PSScavenge::copy_and_push_safe_barrier(this, (narrowOop*)p);
+ PSScavenge::copy_and_push_safe_barrier<narrowOop, /*promote_immediately=*/false>(this, p);
} else {
- PSScavenge::copy_and_push_safe_barrier(this, (oop*)p);
+ PSScavenge::copy_and_push_safe_barrier<oop, /*promote_immediately=*/false>(this, p);
}
}
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
+#include "code/codeCache.hpp"
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
@@ -100,7 +101,7 @@
// Weak refs may be visited more than once.
if (PSScavenge::should_scavenge(p, _to_space)) {
- PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
+ PSScavenge::copy_and_push_safe_barrier<T, /*promote_immediately=*/false>(_promotion_manager, p);
}
}
virtual void do_oop(oop* p) { PSKeepAliveClosure::do_oop_work(p); }
@@ -214,36 +215,41 @@
//
// Note that this method should only be called from the vm_thread while
// at a safepoint!
-void PSScavenge::invoke() {
+bool PSScavenge::invoke() {
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
assert(!Universe::heap()->is_gc_active(), "not reentrant");
- ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+ ParallelScavengeHeap* const heap = (ParallelScavengeHeap*)Universe::heap();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
PSAdaptiveSizePolicy* policy = heap->size_policy();
IsGCActiveMark mark;
- bool scavenge_was_done = PSScavenge::invoke_no_policy();
+ const bool scavenge_done = PSScavenge::invoke_no_policy();
+ const bool need_full_gc = !scavenge_done ||
+ policy->should_full_GC(heap->old_gen()->free_in_bytes());
+ bool full_gc_done = false;
- PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
- if (UsePerfData)
- counters->update_full_follows_scavenge(0);
- if (!scavenge_was_done ||
- policy->should_full_GC(heap->old_gen()->free_in_bytes())) {
- if (UsePerfData)
- counters->update_full_follows_scavenge(full_follows_scavenge);
+ if (UsePerfData) {
+ PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters();
+ const int ffs_val = need_full_gc ? full_follows_scavenge : not_skipped;
+ counters->update_full_follows_scavenge(ffs_val);
+ }
+
+ if (need_full_gc) {
GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
CollectorPolicy* cp = heap->collector_policy();
const bool clear_all_softrefs = cp->should_clear_all_soft_refs();
if (UseParallelOldGC) {
- PSParallelCompact::invoke_no_policy(clear_all_softrefs);
+ full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
} else {
- PSMarkSweep::invoke_no_policy(clear_all_softrefs);
+ full_gc_done = PSMarkSweep::invoke_no_policy(clear_all_softrefs);
}
}
+
+ return full_gc_done;
}
// This method contains no policy. You should probably
@@ -602,6 +608,8 @@
NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
+ CodeCache::prune_scavenge_root_nmethods();
+
// Re-verify object start arrays
if (VerifyObjectStartArray &&
VerifyAfterGC) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -117,10 +117,9 @@
// Called by parallelScavengeHeap to init the tenuring threshold
static void initialize();
- // Scavenge entry point
- static void invoke();
- // Return true is a collection was done. Return
- // false if the collection was skipped.
+ // Scavenge entry point. This may invoke a full gc; return true if so.
+ static bool invoke();
+ // Return true if a collection was done; false otherwise.
static bool invoke_no_policy();
// If an attempt to promote fails, this method is invoked
@@ -135,7 +134,8 @@
template <class T> static inline bool should_scavenge(T* p, MutableSpace* to_space);
template <class T> static inline bool should_scavenge(T* p, bool check_to_space);
- template <class T> inline static void copy_and_push_safe_barrier(PSPromotionManager* pm, T* p);
+ template <class T, bool promote_immediately>
+ inline static void copy_and_push_safe_barrier(PSPromotionManager* pm, T* p);
// Is an object in the young generation
// This assumes that the HeapWord argument is in the heap,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -28,6 +28,7 @@
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
+#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
inline void PSScavenge::save_to_space_top_before_gc() {
@@ -65,7 +66,7 @@
// Attempt to "claim" oop at p via CAS, push the new obj if successful
// This version tests the oop* to make sure it is within the heap before
// attempting marking.
-template <class T>
+template <class T, bool promote_immediately>
inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
T* p) {
assert(should_scavenge(p, true), "revisiting object?");
@@ -73,7 +74,7 @@
oop o = oopDesc::load_decode_heap_oop_not_null(p);
oop new_obj = o->is_forwarded()
? o->forwardee()
- : pm->copy_to_survivor_space(o);
+ : pm->copy_to_survivor_space<promote_immediately>(o);
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
// We cannot mark without test, as some code passes us pointers
@@ -86,7 +87,8 @@
}
}
-class PSScavengeRootsClosure: public OopClosure {
+template<bool promote_immediately>
+class PSRootsClosure: public OopClosure {
private:
PSPromotionManager* _promotion_manager;
@@ -94,13 +96,16 @@
template <class T> void do_oop_work(T *p) {
if (PSScavenge::should_scavenge(p)) {
// We never card mark roots, maybe call a func without test?
- PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
+ PSScavenge::copy_and_push_safe_barrier<T, promote_immediately>(_promotion_manager, p);
}
}
public:
- PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
- void do_oop(oop* p) { PSScavengeRootsClosure::do_oop_work(p); }
- void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
+ PSRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
+ void do_oop(oop* p) { PSRootsClosure::do_oop_work(p); }
+ void do_oop(narrowOop* p) { PSRootsClosure::do_oop_work(p); }
};
+typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;
+typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;
+
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -51,6 +51,7 @@
PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
PSScavengeRootsClosure roots_closure(pm);
+ PSPromoteRootsClosure roots_to_old_closure(pm);
switch (_root_type) {
case universe:
@@ -91,7 +92,7 @@
case code_cache:
{
- CodeBlobToOopClosure each_scavengable_code_blob(&roots_closure, /*do_marking=*/ true);
+ CodeBlobToOopClosure each_scavengable_code_blob(&roots_to_old_closure, /*do_marking=*/ true);
CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
}
break;
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -62,7 +62,7 @@
return;
}
- jlong timestamp = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ double timestamp = fetch_timestamp();
MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
int index = compute_log_index();
_records[index].thread = NULL; // Its the GC thread so it's not that interesting.
@@ -70,9 +70,9 @@
_records[index].data.is_before = before;
stringStream st(_records[index].data.buffer(), _records[index].data.size());
if (before) {
- Universe::print_heap_before_gc(&st);
+ Universe::print_heap_before_gc(&st, true);
} else {
- Universe::print_heap_after_gc(&st);
+ Universe::print_heap_after_gc(&st, true);
}
}
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -240,9 +240,6 @@
if (_ro_space == NULL || _rw_space == NULL)
vm_exit_during_initialization("Could not allocate a shared space");
- // Cover both shared spaces entirely with cards.
- _rs->resize_covered_region(MemRegion(readonly_bottom, readwrite_end));
-
if (UseSharedSpaces) {
// Map in the regions in the shared file.
@@ -279,10 +276,14 @@
delete _rw_space;
_rw_space = NULL;
shared_end = (HeapWord*)(rs.base() + rs.size());
- _rs->resize_covered_region(MemRegion(shared_bottom, shared_bottom));
}
}
+ if (spec()->enable_shared_spaces()) {
+ // Cover both shared spaces entirely with cards.
+ _rs->resize_covered_region(MemRegion(readonly_bottom, readwrite_end));
+ }
+
// Reserved region includes shared spaces for oop.is_in_reserved().
_reserved.set_end(shared_end);
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -655,7 +655,12 @@
from()->set_concurrent_iteration_safe_limit(from()->top());
to()->set_concurrent_iteration_safe_limit(to()->top());
SpecializationStats::print();
- update_time_of_last_gc(os::javaTimeMillis());
+
+ // We need to use a monotonically non-deccreasing time in ms
+ // or we will see time-warp warnings and os::javaTimeMillis()
+ // does not guarantee monotonicity.
+ jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ update_time_of_last_gc(now);
}
class RemoveForwardPointerClosure: public ObjectClosure {
--- a/hotspot/src/share/vm/memory/gcLocker.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/gcLocker.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -31,7 +31,6 @@
volatile jint GC_locker::_lock_count = 0;
volatile bool GC_locker::_needs_gc = false;
volatile bool GC_locker::_doing_gc = false;
-jlong GC_locker::_wait_begin = 0;
#ifdef ASSERT
volatile jint GC_locker::_debug_jni_lock_count = 0;
@@ -69,9 +68,8 @@
_needs_gc = true;
if (PrintJNIGCStalls && PrintGCDetails) {
ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
- _wait_begin = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
- gclog_or_tty->print_cr(INT64_FORMAT ": Setting _needs_gc. Thread \"%s\" %d locked.",
- _wait_begin, Thread::current()->name(), _jni_lock_count);
+ gclog_or_tty->print_cr("%.3f: Setting _needs_gc. Thread \"%s\" %d locked.",
+ gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
}
}
@@ -85,8 +83,8 @@
if (needs_gc()) {
if (PrintJNIGCStalls && PrintGCDetails) {
ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
- gclog_or_tty->print_cr(INT64_FORMAT ": Allocation failed. Thread \"%s\" is stalled by JNI critical section, %d locked.",
- (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) - _wait_begin, Thread::current()->name(), _jni_lock_count);
+ gclog_or_tty->print_cr("%.3f: Allocation failed. Thread \"%s\" is stalled by JNI critical section, %d locked.",
+ gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
}
}
@@ -131,8 +129,8 @@
MutexUnlocker munlock(JNICritical_lock);
if (PrintJNIGCStalls && PrintGCDetails) {
ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
- gclog_or_tty->print_cr(INT64_FORMAT ": Thread \"%s\" is performing GC after exiting critical section, %d locked",
- (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) - _wait_begin, Thread::current()->name(), _jni_lock_count);
+ gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
+ gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
}
Universe::heap()->collect(GCCause::_gc_locker);
}
--- a/hotspot/src/share/vm/memory/gcLocker.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/gcLocker.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -63,9 +63,6 @@
// note: bool is typedef'd as jint
static volatile bool _doing_gc; // unlock_critical() is doing a GC
- static jlong _wait_begin; // Timestamp for the setting of _needs_gc.
- // Used only by printing code.
-
#ifdef ASSERT
// This lock count is updated for all operations and is used to
// validate the jni_lock_count that is computed during safepoints.
@@ -86,13 +83,26 @@
static void jni_lock(JavaThread* thread);
static void jni_unlock(JavaThread* thread);
+ static bool is_active_internal() {
+ verify_critical_count();
+ return _lock_count > 0 || _jni_lock_count > 0;
+ }
+
public:
// Accessors
- static bool is_active();
+ static bool is_active() {
+ assert(_needs_gc || SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
+ return is_active_internal();
+ }
static bool needs_gc() { return _needs_gc; }
// Shorthand
- static bool is_active_and_needs_gc() { return needs_gc() && is_active(); }
+ static bool is_active_and_needs_gc() {
+ // Use is_active_internal since _needs_gc can change from true to
+ // false outside of a safepoint, triggering the assert in
+ // is_active.
+ return needs_gc() && is_active_internal();
+ }
// In debug mode track the locking state at all times
static void increment_debug_jni_lock_count() {
--- a/hotspot/src/share/vm/memory/gcLocker.inline.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/gcLocker.inline.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -27,12 +27,6 @@
#include "memory/gcLocker.hpp"
-inline bool GC_locker::is_active() {
- assert(_needs_gc || SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
- verify_critical_count();
- return _lock_count > 0 || _jni_lock_count > 0;
-}
-
inline void GC_locker::lock() {
// cast away volatile
Atomic::inc(&_lock_count);
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -176,7 +176,11 @@
// Update time of last gc for all generations we collected
// (which curently is all the generations in the heap).
- gch->update_time_of_last_gc(os::javaTimeMillis());
+ // We need to use a monotonically non-deccreasing time in ms
+ // or we will see time-warp warnings and os::javaTimeMillis()
+ // does not guarantee monotonicity.
+ jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ gch->update_time_of_last_gc(now);
}
void GenMarkSweep::allocate_stacks() {
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1303,22 +1303,22 @@
}
}
-void Universe::print_heap_before_gc(outputStream* st) {
+void Universe::print_heap_before_gc(outputStream* st, bool ignore_extended) {
st->print_cr("{Heap before GC invocations=%u (full %u):",
heap()->total_collections(),
heap()->total_full_collections());
- if (!PrintHeapAtGCExtended) {
+ if (!PrintHeapAtGCExtended || ignore_extended) {
heap()->print_on(st);
} else {
heap()->print_extended_on(st);
}
}
-void Universe::print_heap_after_gc(outputStream* st) {
+void Universe::print_heap_after_gc(outputStream* st, bool ignore_extended) {
st->print_cr("Heap after GC invocations=%u (full %u):",
heap()->total_collections(),
heap()->total_full_collections());
- if (!PrintHeapAtGCExtended) {
+ if (!PrintHeapAtGCExtended || ignore_extended) {
heap()->print_on(st);
} else {
heap()->print_extended_on(st);
--- a/hotspot/src/share/vm/memory/universe.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -424,8 +424,8 @@
static void print_heap_at_SIGBREAK();
static void print_heap_before_gc() { print_heap_before_gc(gclog_or_tty); }
static void print_heap_after_gc() { print_heap_after_gc(gclog_or_tty); }
- static void print_heap_before_gc(outputStream* st);
- static void print_heap_after_gc(outputStream* st);
+ static void print_heap_before_gc(outputStream* st, bool ignore_extended = false);
+ static void print_heap_after_gc(outputStream* st, bool ignore_extended = false);
// Change the number of dummy objects kept reachable by the full gc dummy
// array; this should trigger relocation in a sliding compaction collector.
--- a/hotspot/src/share/vm/opto/chaitin.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -1946,18 +1946,29 @@
reg2offset_unchecked(OptoReg::add(_matcher._old_SP,-1)) - reg2offset_unchecked(_matcher._new_SP)+jintSize);
// Preserve area dump
+ int fixed_slots = C->fixed_slots();
+ OptoReg::Name begin_in_preserve = OptoReg::add(_matcher._old_SP, -(int)C->in_preserve_stack_slots());
+ OptoReg::Name return_addr = _matcher.return_addr();
+
reg = OptoReg::add(reg, -1);
- while( OptoReg::is_stack(reg)) {
+ while (OptoReg::is_stack(reg)) {
tty->print("#r%3.3d %s+%2d: ",reg,fp,reg2offset_unchecked(reg));
- if( _matcher.return_addr() == reg )
+ if (return_addr == reg) {
tty->print_cr("return address");
- else if( _matcher.return_addr() == OptoReg::add(reg,1) &&
- VerifyStackAtCalls )
- tty->print_cr("0xBADB100D +VerifyStackAtCalls");
- else if ((int)OptoReg::reg2stack(reg) < C->fixed_slots())
+ } else if (reg >= begin_in_preserve) {
+ // Preserved slots are present on x86
+ if (return_addr == OptoReg::add(reg, VMRegImpl::slots_per_word))
+ tty->print_cr("saved fp register");
+ else if (return_addr == OptoReg::add(reg, 2*VMRegImpl::slots_per_word) &&
+ VerifyStackAtCalls)
+ tty->print_cr("0xBADB100D +VerifyStackAtCalls");
+ else
+ tty->print_cr("in_preserve");
+ } else if ((int)OptoReg::reg2stack(reg) < fixed_slots) {
tty->print_cr("Fixed slot %d", OptoReg::reg2stack(reg));
- else
- tty->print_cr("pad2, in_preserve");
+ } else {
+ tty->print_cr("pad2, stack alignment");
+ }
reg = OptoReg::add(reg, -1);
}
--- a/hotspot/src/share/vm/opto/escape.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -1687,12 +1687,23 @@
// Observed 8 passes in jvm2008 compiler.compiler.
// Set limit to 20 to catch situation when something
// did go wrong and recompile the method without EA.
+ // Also limit build time to 30 sec (60 in debug VM).
#define CG_BUILD_ITER_LIMIT 20
+#ifdef ASSERT
+#define CG_BUILD_TIME_LIMIT 60.0
+#else
+#define CG_BUILD_TIME_LIMIT 30.0
+#endif
+
uint length = worklist.length();
int iterations = 0;
- while(_progress && (iterations++ < CG_BUILD_ITER_LIMIT)) {
+ elapsedTimer time;
+ while(_progress &&
+ (iterations++ < CG_BUILD_ITER_LIMIT) &&
+ (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+ time.start();
_progress = false;
for( uint next = 0; next < length; ++next ) {
int ni = worklist.at(next);
@@ -1701,18 +1712,19 @@
assert(n != NULL, "should be known node");
build_connection_graph(n, igvn);
}
+ time.stop();
}
- if (iterations >= CG_BUILD_ITER_LIMIT) {
- assert(iterations < CG_BUILD_ITER_LIMIT,
- err_msg("infinite EA connection graph build with %d nodes and worklist size %d",
- nodes_size(), length));
+ if ((iterations >= CG_BUILD_ITER_LIMIT) ||
+ (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
+ assert(false, err_msg("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
+ time.seconds(), iterations, nodes_size(), length));
// Possible infinite build_connection_graph loop,
- // retry compilation without escape analysis.
- C->record_failure(C2Compiler::retry_no_escape_analysis());
+ // bailout (no changes to ideal graph were made).
_collecting = false;
return false;
}
#undef CG_BUILD_ITER_LIMIT
+#undef CG_BUILD_TIME_LIMIT
// 5. Propagate escaped states.
worklist.clear();
@@ -2292,9 +2304,35 @@
PointsToNode::EscapeState arg_esc = ptnode_adr(arg->_idx)->escape_state();
if (!arg->is_top() && at->isa_ptr() && aat->isa_ptr() &&
(is_arraycopy || arg_esc < PointsToNode::ArgEscape)) {
-
+#ifdef ASSERT
assert(aat == Type::TOP || aat == TypePtr::NULL_PTR ||
aat->isa_ptr() != NULL, "expecting an Ptr");
+ if (!(is_arraycopy ||
+ call->as_CallLeaf()->_name != NULL &&
+ (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre") == 0 ||
+ strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 ))
+ ) {
+ call->dump();
+ assert(false, "EA: unexpected CallLeaf");
+ }
+#endif
+ if (arg_esc < PointsToNode::ArgEscape) {
+ set_escape_state(arg->_idx, PointsToNode::ArgEscape);
+ Node* arg_base = arg;
+ if (arg->is_AddP()) {
+ //
+ // The inline_native_clone() case when the arraycopy stub is called
+ // after the allocation before Initialize and CheckCastPP nodes.
+ // Or normal arraycopy for object arrays case.
+ //
+ // Set AddP's base (Allocate) as not scalar replaceable since
+ // pointer to the base (with offset) is passed as argument.
+ //
+ arg_base = get_addp_base(arg);
+ set_escape_state(arg_base->_idx, PointsToNode::ArgEscape);
+ }
+ }
+
bool arg_has_oops = aat->isa_oopptr() &&
(aat->isa_oopptr()->klass() == NULL || aat->isa_instptr() ||
(aat->isa_aryptr() && aat->isa_aryptr()->klass()->is_obj_array_klass()));
@@ -2307,85 +2345,33 @@
// arraycopy(char[],0,Object*,0,size);
// arraycopy(Object*,0,char[],0,size);
//
- // Don't add edges from dst's fields in such cases.
+ // Do nothing special in such cases.
//
- bool arg_is_arraycopy_dest = src_has_oops && is_arraycopy &&
- arg_has_oops && (i > TypeFunc::Parms);
-#ifdef ASSERT
- if (!(is_arraycopy ||
- call->as_CallLeaf()->_name != NULL &&
- (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre") == 0 ||
- strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 ))
- ) {
- call->dump();
- assert(false, "EA: unexpected CallLeaf");
- }
-#endif
- // Always process arraycopy's destination object since
- // we need to add all possible edges to references in
- // source object.
- if (arg_esc >= PointsToNode::ArgEscape &&
- !arg_is_arraycopy_dest) {
- continue;
- }
- set_escape_state(arg->_idx, PointsToNode::ArgEscape);
- Node* arg_base = arg;
- if (arg->is_AddP()) {
- //
- // The inline_native_clone() case when the arraycopy stub is called
- // after the allocation before Initialize and CheckCastPP nodes.
- // Or normal arraycopy for object arrays case.
- //
- // Set AddP's base (Allocate) as not scalar replaceable since
- // pointer to the base (with offset) is passed as argument.
- //
- arg_base = get_addp_base(arg);
- }
- VectorSet argset = *PointsTo(arg_base); // Clone set
- for( VectorSetI j(&argset); j.test(); ++j ) {
- uint pd = j.elem; // Destination object
- set_escape_state(pd, PointsToNode::ArgEscape);
-
- if (arg_is_arraycopy_dest) {
- PointsToNode* ptd = ptnode_adr(pd);
- // Conservatively reference an unknown object since
- // not all source's fields/elements may be known.
- add_edge_from_fields(pd, _phantom_object, Type::OffsetBot);
-
- Node *src = call->in(TypeFunc::Parms)->uncast();
- Node* src_base = src;
- if (src->is_AddP()) {
- src_base = get_addp_base(src);
- }
- // Create edges from destination's fields to
- // everything known source's fields could point to.
- for( VectorSetI s(PointsTo(src_base)); s.test(); ++s ) {
- uint ps = s.elem;
- bool has_bottom_offset = false;
- for (uint fd = 0; fd < ptd->edge_count(); fd++) {
- assert(ptd->edge_type(fd) == PointsToNode::FieldEdge, "expecting a field edge");
- int fdi = ptd->edge_target(fd);
- PointsToNode* pfd = ptnode_adr(fdi);
- int offset = pfd->offset();
- if (offset == Type::OffsetBot)
- has_bottom_offset = true;
- assert(offset != -1, "offset should be set");
- add_deferred_edge_to_fields(fdi, ps, offset);
- }
- // Destination object may not have access (no field edge)
- // to fields which are accessed in source object.
- // As result no edges will be created to those source's
- // fields and escape state of destination object will
- // not be propagated to those fields.
- //
- // Mark source object as global escape except in
- // the case with Type::OffsetBot field (which is
- // common case for array elements access) when
- // edges are created to all source's fields.
- if (!has_bottom_offset) {
- set_escape_state(ps, PointsToNode::GlobalEscape);
- }
- }
+ if (is_arraycopy && (i > TypeFunc::Parms) &&
+ src_has_oops && arg_has_oops) {
+ // Destination object's fields reference an unknown object.
+ Node* arg_base = arg;
+ if (arg->is_AddP()) {
+ arg_base = get_addp_base(arg);
+ }
+ for (VectorSetI s(PointsTo(arg_base)); s.test(); ++s) {
+ uint ps = s.elem;
+ set_escape_state(ps, PointsToNode::ArgEscape);
+ add_edge_from_fields(ps, _phantom_object, Type::OffsetBot);
+ }
+ // Conservatively all values in source object fields globally escape
+ // since we don't know if values in destination object fields
+ // escape (it could be traced but it is too expensive).
+ Node* src = call->in(TypeFunc::Parms)->uncast();
+ Node* src_base = src;
+ if (src->is_AddP()) {
+ src_base = get_addp_base(src);
+ }
+ for (VectorSetI s(PointsTo(src_base)); s.test(); ++s) {
+ uint ps = s.elem;
+ set_escape_state(ps, PointsToNode::ArgEscape);
+ // Use OffsetTop to indicate fields global escape.
+ add_edge_from_fields(ps, _phantom_object, Type::OffsetTop);
}
}
}
--- a/hotspot/src/share/vm/opto/output.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -167,7 +167,7 @@
// Determine if we need to generate a stack overflow check.
// Do it if the method is not a stub function and
// has java calls or has frame size > vm_page_size/8.
- return (stub_function() == NULL &&
+ return (UseStackBanging && stub_function() == NULL &&
(has_java_calls() || frame_size_in_bytes > os::vm_page_size()>>3));
}
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -2999,7 +2999,8 @@
char type = field->field_type();
if (!is_primitive_field_type(type)) {
oop fld_o = o->obj_field(field->field_offset());
- if (fld_o != NULL) {
+ // ignore any objects that aren't visible to profiler
+ if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
// reflection code may have a reference to a klassOop.
// - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
if (fld_o->is_klass()) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -102,8 +102,6 @@
char* Arguments::_meta_index_path = NULL;
char* Arguments::_meta_index_dir = NULL;
-static bool force_client_mode = false;
-
// Check if head of 'option' matches 'name', and sets 'tail' remaining part of option string
static bool match_option(const JavaVMOption *option, const char* name,
@@ -1345,7 +1343,7 @@
return;
}
- if (os::is_server_class_machine() && !force_client_mode ) {
+ if (os::is_server_class_machine()) {
// If no other collector is requested explicitly,
// let the VM select the collector based on
// machine class and automatic selection policy.
@@ -1370,12 +1368,9 @@
// by ergonomics.
if (MaxHeapSize <= max_heap_for_compressed_oops()) {
#if !defined(COMPILER1) || defined(TIERED)
-// disable UseCompressedOops by default on MacOS X until 7118647 is fixed
-#ifndef __APPLE__
if (FLAG_IS_DEFAULT(UseCompressedOops)) {
FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
-#endif // !__APPLE__
#endif
#ifdef _WIN64
if (UseLargePages && UseCompressedOops) {
@@ -2940,11 +2935,6 @@
// Construct the path to the archive
char jvm_path[JVM_MAXPATHLEN];
os::jvm_path(jvm_path, sizeof(jvm_path));
-#ifdef TIERED
- if (strstr(jvm_path, "client") != NULL) {
- force_client_mode = true;
- }
-#endif // TIERED
char *end = strrchr(jvm_path, *os::file_separator());
if (end != NULL) *end = '\0';
char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) +
--- a/hotspot/src/share/vm/runtime/dtraceJSDT.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/dtraceJSDT.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -82,7 +82,7 @@
int handle = pd_activate((void*)probes,
module_name, providers_count, providers);
- if (handle <= 0) {
+ if (handle < 0) {
delete probes;
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(),
"Unable to register DTrace probes (internal error).");
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -3013,7 +3013,7 @@
product(intx, SafepointTimeoutDelay, 10000, \
"Delay in milliseconds for option SafepointTimeout") \
\
- product(intx, NmethodSweepFraction, 4, \
+ product(intx, NmethodSweepFraction, 16, \
"Number of invocations of sweeper to cover all nmethods") \
\
product(intx, NmethodSweepCheckInterval, 5, \
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -804,6 +804,7 @@
if (thread->deopt_mark() != NULL) {
Deoptimization::cleanup_deopt_info(thread, NULL);
}
+ Events::log_exception(thread, "StackOverflowError at " INTPTR_FORMAT, pc);
return StubRoutines::throw_StackOverflowError_entry();
}
@@ -820,8 +821,10 @@
if (vt_stub->is_abstract_method_error(pc)) {
assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
+ Events::log_exception(thread, "AbstractMethodError at " INTPTR_FORMAT, pc);
return StubRoutines::throw_AbstractMethodError_entry();
} else {
+ Events::log_exception(thread, "NullPointerException at vtable entry " INTPTR_FORMAT, pc);
return StubRoutines::throw_NullPointerException_at_call_entry();
}
} else {
@@ -838,6 +841,7 @@
if (!cb->is_nmethod()) {
guarantee(cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(),
"exception happened outside interpreter, nmethods and vtable stubs (1)");
+ Events::log_exception(thread, "NullPointerException in code blob at " INTPTR_FORMAT, pc);
// There is no handler here, so we will simply unwind.
return StubRoutines::throw_NullPointerException_at_call_entry();
}
@@ -849,6 +853,7 @@
// => the nmethod is not yet active (i.e., the frame
// is not set up yet) => use return address pushed by
// caller => don't push another return address
+ Events::log_exception(thread, "NullPointerException in IC check " INTPTR_FORMAT, pc);
return StubRoutines::throw_NullPointerException_at_call_entry();
}
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -266,7 +266,17 @@
// The last invocation iterates until there are no more nmethods
for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) {
+ if (SafepointSynchronize::is_synchronizing()) { // Safepoint request
+ if (PrintMethodFlushing && Verbose) {
+ tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations);
+ }
+ MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ assert(Thread::current()->is_Java_thread(), "should be java thread");
+ JavaThread* thread = (JavaThread*)Thread::current();
+ ThreadBlockInVM tbivm(thread);
+ thread->java_suspend_self();
+ }
// 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.
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -3220,11 +3220,6 @@
return status;
}
- // Must be run after init_ft which initializes ft_enabled
- if (TRACE_INITIALIZE() != JNI_OK) {
- vm_exit_during_initialization("Failed to initialize tracing backend");
- }
-
// Should be done after the heap is fully created
main_thread->cache_global_variables();
@@ -3366,6 +3361,7 @@
initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
} else {
warning("java.lang.OutOfMemoryError has not been initialized");
warning("java.lang.NullPointerException has not been initialized");
@@ -3373,6 +3369,7 @@
warning("java.lang.ArrayStoreException has not been initialized");
warning("java.lang.ArithmeticException has not been initialized");
warning("java.lang.StackOverflowError has not been initialized");
+ warning("java.lang.IllegalArgumentException has not been initialized");
}
}
@@ -3402,6 +3399,11 @@
quicken_jni_functions();
+ // Must be run after init_ft which initializes ft_enabled
+ if (TRACE_INITIALIZE() != JNI_OK) {
+ vm_exit_during_initialization("Failed to initialize tracing backend");
+ }
+
// Set flag that basic initialization has completed. Used by exceptions and various
// debug stuff, that does not work until all basic classes have been initialized.
set_init_completed();
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -455,7 +455,7 @@
void ReservedSpace::protect_noaccess_prefix(const size_t size) {
assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
- (size_t(_base + _size) > OopEncodingHeapMax) &&
+ (Universe::narrow_oop_base() != NULL) &&
Universe::narrow_oop_use_implicit_null_checks()),
"noaccess_prefix should be used only with non zero based compressed oops");
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -28,9 +28,16 @@
#include "services/diagnosticArgument.hpp"
void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
- if (is_set()) {
+ /* NOTE:Some argument types doesn't require a value,
+ * for instance boolean arguments: "enableFeatureX". is
+ * equivalent to "enableFeatureX=true". In these cases,
+ * str will be null. This is perfectly valid.
+ * All argument types must perform null checks on str.
+ */
+
+ if (is_set() && !allow_multiple()) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Duplicates in diagnostic command arguments");
+ "Duplicates in diagnostic command arguments\n");
}
parse_value(str, len, CHECK);
set_is_set(true);
@@ -38,9 +45,9 @@
template <> void DCmdArgument<jlong>::parse_value(const char* str,
size_t len, TRAPS) {
- if (sscanf(str, INT64_FORMAT, &_value) != 1) {
+ if (str == NULL || sscanf(str, INT64_FORMAT, &_value) != 1) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Integer parsing error in diagnostic command arguments");
+ "Integer parsing error in diagnostic command arguments\n");
}
}
@@ -89,16 +96,20 @@
template <> void DCmdArgument<char*>::parse_value(const char* str,
size_t len, TRAPS) {
- _value = NEW_C_HEAP_ARRAY(char, len+1);
- strncpy(_value, str, len);
- _value[len] = 0;
+ if (str == NULL) {
+ _value = NULL;
+ } else {
+ _value = NEW_C_HEAP_ARRAY(char, len+1);
+ strncpy(_value, str, len);
+ _value[len] = 0;
+ }
}
template <> void DCmdArgument<char*>::init_value(TRAPS) {
- if (has_default()) {
+ if (has_default() && _default_string != NULL) {
this->parse_value(_default_string, strlen(_default_string), THREAD);
if (HAS_PENDING_EXCEPTION) {
- fatal("Default string must be parsable");
+ fatal("Default string must be parsable");
}
} else {
set_value(NULL);
@@ -111,3 +122,153 @@
set_value(NULL);
}
}
+
+template <> void DCmdArgument<NanoTimeArgument>::parse_value(const char* str,
+ size_t len, TRAPS) {
+ if (str == NULL) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: syntax error");
+ }
+
+ int argc = sscanf(str, INT64_FORMAT , &_value._time);
+ if (argc != 1) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: syntax error");
+ }
+ size_t idx = 0;
+ while(idx < len && isdigit(str[idx])) {
+ idx++;
+ }
+ if (idx == len) {
+ // only accept missing unit if the value is 0
+ if (_value._time != 0) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: unit required");
+ } else {
+ _value._nanotime = 0;
+ strcpy(_value._unit, "ns");
+ return;
+ }
+ } else if(len - idx > 2) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: illegal unit");
+ } else {
+ strncpy(_value._unit, &str[idx], len - idx);
+ /*Write an extra null termination. This is safe because _value._unit
+ * is declared as char[3], and length is checked to be not larger than
+ * two above. Also, this is necessary, since length might be 1, and the
+ * default value already in the string is ns, which is two chars.
+ */
+ _value._unit[len-idx] = '\0';
+ }
+
+ if (strcmp(_value._unit, "ns") == 0) {
+ _value._nanotime = _value._time;
+ } else if (strcmp(_value._unit, "us") == 0) {
+ _value._nanotime = _value._time * 1000;
+ } else if (strcmp(_value._unit, "ms") == 0) {
+ _value._nanotime = _value._time * 1000 * 1000;
+ } else if (strcmp(_value._unit, "s") == 0) {
+ _value._nanotime = _value._time * 1000 * 1000 * 1000;
+ } else if (strcmp(_value._unit, "m") == 0) {
+ _value._nanotime = _value._time * 60 * 1000 * 1000 * 1000;
+ } else if (strcmp(_value._unit, "h") == 0) {
+ _value._nanotime = _value._time * 60 * 60 * 1000 * 1000 * 1000;
+ } else if (strcmp(_value._unit, "d") == 0) {
+ _value._nanotime = _value._time * 24 * 60 * 60 * 1000 * 1000 * 1000;
+ } else {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: illegal unit");
+ }
+}
+
+template <> void DCmdArgument<NanoTimeArgument>::init_value(TRAPS) {
+ if (has_default()) {
+ this->parse_value(_default_string, strlen(_default_string), THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ fatal("Default string must be parsable");
+ }
+ } else {
+ _value._time = 0;
+ _value._nanotime = 0;
+ strcmp(_value._unit, "ns");
+ }
+}
+
+template <> void DCmdArgument<NanoTimeArgument>::destroy_value() { }
+
+// WARNING StringArrayArgument can only be used as an option, it cannot be
+// used as an argument with the DCmdParser
+
+template <> void DCmdArgument<StringArrayArgument*>::parse_value(const char* str,
+ size_t len, TRAPS) {
+ _value->add(str,len);
+}
+
+template <> void DCmdArgument<StringArrayArgument*>::init_value(TRAPS) {
+ _value = new StringArrayArgument();
+ _allow_multiple = true;
+ if (has_default()) {
+ fatal("StringArrayArgument cannot have default value");
+ }
+}
+
+template <> void DCmdArgument<StringArrayArgument*>::destroy_value() {
+ if (_value != NULL) {
+ delete _value;
+ set_value(NULL);
+ }
+}
+
+template <> void DCmdArgument<MemorySizeArgument>::parse_value(const char* str,
+ size_t len, TRAPS) {
+ if (str == NULL) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: syntax error");
+ }
+
+ if (*str == '-') {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Parsing error memory size value: negative values not allowed");
+ }
+ int res = sscanf(str, UINT64_FORMAT "%c", &_value._val, &_value._multiplier);
+ if (res == 2) {
+ switch (_value._multiplier) {
+ case 'k': case 'K':
+ _value._size = _value._val * 1024;
+ break;
+ case 'm': case 'M':
+ _value._size = _value._val * 1024 * 1024;
+ break;
+ case 'g': case 'G':
+ _value._size = _value._val * 1024 * 1024 * 1024;
+ break;
+ default:
+ _value._size = _value._val;
+ _value._multiplier = ' ';
+ //default case should be to break with no error, since user
+ //can write size in bytes, or might have a delimiter and next arg
+ break;
+ }
+ } else if (res == 1) {
+ _value._size = _value._val;
+ } else {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Parsing error memory size value: invalid value");
+ }
+}
+
+template <> void DCmdArgument<MemorySizeArgument>::init_value(TRAPS) {
+ if (has_default()) {
+ this->parse_value(_default_string, strlen(_default_string), THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ fatal("Default string must be parsable");
+ }
+ } else {
+ _value._size = 0;
+ _value._val = 0;
+ _value._multiplier = ' ';
+ }
+}
+
+template <> void DCmdArgument<MemorySizeArgument>::destroy_value() { }
--- a/hotspot/src/share/vm/services/diagnosticArgument.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/services/diagnosticArgument.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -31,6 +31,49 @@
#include "runtime/thread.hpp"
#include "utilities/exceptions.hpp"
+class StringArrayArgument : public CHeapObj {
+private:
+ GrowableArray<char*>* _array;
+public:
+ StringArrayArgument() {
+ _array = new(ResourceObj::C_HEAP)GrowableArray<char *>(32, true);
+ assert(_array != NULL, "Sanity check");
+ }
+ void add(const char* str, size_t len) {
+ if (str != NULL) {
+ char* ptr = NEW_C_HEAP_ARRAY(char, len+1);
+ strncpy(ptr, str, len);
+ ptr[len] = 0;
+ _array->append(ptr);
+ }
+ }
+ GrowableArray<char*>* array() {
+ return _array;
+ }
+ ~StringArrayArgument() {
+ for (int i=0; i<_array->length(); i++) {
+ if(_array->at(i) != NULL) { // Safety check
+ FREE_C_HEAP_ARRAY(char, _array->at(i));
+ }
+ }
+ delete _array;
+ }
+};
+
+class NanoTimeArgument {
+public:
+ jlong _nanotime;
+ jlong _time;
+ char _unit[3];
+};
+
+class MemorySizeArgument {
+public:
+ u8 _size;
+ u8 _val;
+ char _multiplier;
+};
+
class GenDCmdArgument : public ResourceObj {
protected:
GenDCmdArgument* _next;
@@ -40,6 +83,7 @@
const char* _default_string;
bool _is_set;
bool _is_mandatory;
+ bool _allow_multiple;
GenDCmdArgument(const char* name, const char* description, const char* type,
const char* default_string, bool mandatory) {
_name = name;
@@ -48,6 +92,7 @@
_default_string = default_string;
_is_mandatory = mandatory;
_is_set = false;
+ _allow_multiple = false;
};
public:
const char* name() { return _name; }
@@ -56,6 +101,7 @@
const char* default_string() { return _default_string; }
bool is_set() { return _is_set; }
void set_is_set(bool b) { _is_set = b; }
+ bool allow_multiple() { return _allow_multiple; }
bool is_mandatory() { return _is_mandatory; }
bool has_value() { return _is_set || _default_string != NULL; }
bool has_default() { return _default_string != NULL; }
--- a/hotspot/src/share/vm/services/diagnosticFramework.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -61,7 +61,7 @@
bool DCmdArgIter::next(TRAPS) {
if (_len == 0) return false;
// skipping spaces
- while (_cursor < _len - 1 && isspace(_buffer[_cursor])) {
+ while (_cursor < _len - 1 && _buffer[_cursor] == _delim) {
_cursor++;
}
// handling end of command line
--- a/hotspot/src/share/vm/services/diagnosticFramework.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/services/diagnosticFramework.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -195,6 +195,7 @@
DCmdParser() {
_options = NULL;
_arguments_list = NULL;
+ _delim = ' ';
}
void add_dcmd_option(GenDCmdArgument* arg);
void add_dcmd_argument(GenDCmdArgument* arg);
--- a/hotspot/src/share/vm/services/gcNotifier.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/services/gcNotifier.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -180,17 +180,43 @@
}
void GCNotifier::sendNotification(TRAPS) {
+ GCNotifier::sendNotificationInternal(THREAD);
+ // Clearing pending exception to avoid premature termination of
+ // the service thread
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ }
+}
+
+class NotificationMark : public StackObj {
+ // This class is used in GCNotifier::sendNotificationInternal to ensure that
+ // the GCNotificationRequest object is properly cleaned up, whatever path
+ // is used to exit the method.
+ GCNotificationRequest* _request;
+public:
+ NotificationMark(GCNotificationRequest* r) {
+ _request = r;
+ }
+ ~NotificationMark() {
+ assert(_request != NULL, "Sanity check");
+ delete _request;
+ }
+};
+
+void GCNotifier::sendNotificationInternal(TRAPS) {
ResourceMark rm(THREAD);
+ HandleMark hm(THREAD);
GCNotificationRequest *request = getRequest();
- if(request != NULL) {
- Handle objGcInfo = createGcInfo(request->gcManager,request->gcStatInfo,THREAD);
+ if (request != NULL) {
+ NotificationMark nm(request);
+ Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD);
Handle objName = java_lang_String::create_from_platform_dependent_str(request->gcManager->name(), CHECK);
Handle objAction = java_lang_String::create_from_platform_dependent_str(request->gcAction, CHECK);
Handle objCause = java_lang_String::create_from_platform_dependent_str(request->gcCause, CHECK);
klassOop k = Management::sun_management_GarbageCollectorImpl_klass(CHECK);
- instanceKlassHandle gc_mbean_klass (THREAD, k);
+ instanceKlassHandle gc_mbean_klass(THREAD, k);
instanceOop gc_mbean = request->gcManager->get_memory_manager_instance(THREAD);
instanceHandle gc_mbean_h(THREAD, gc_mbean);
@@ -213,11 +239,6 @@
vmSymbols::createGCNotification_signature(),
&args,
CHECK);
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- }
-
- delete request;
}
}
--- a/hotspot/src/share/vm/services/gcNotifier.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/services/gcNotifier.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -60,6 +60,7 @@
static GCNotificationRequest *last_request;
static void addRequest(GCNotificationRequest *request);
static GCNotificationRequest *getRequest();
+ static void sendNotificationInternal(TRAPS);
public:
static void pushNotification(GCMemoryManager *manager, const char *action, const char *cause);
static bool has_event();
--- a/hotspot/src/share/vm/utilities/debug.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/debug.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -600,6 +600,10 @@
tty->flush();
}
+extern "C" void events() {
+ Command c("events");
+ Events::print();
+}
// Given a heap address that was valid before the most recent GC, if
// the oop that used to contain it is still live, prints the new
@@ -759,7 +763,7 @@
tty->print_cr("misc.");
tty->print_cr(" flush() - flushes the log file");
- tty->print_cr(" events() - dump last 50 events");
+ tty->print_cr(" events() - dump events from ring buffers");
tty->print_cr("compiler debugging");
--- a/hotspot/src/share/vm/utilities/decoder.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/decoder.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -25,7 +25,9 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
#include "runtime/mutexLocker.hpp"
+#include "runtime/os.hpp"
#include "utilities/decoder.hpp"
+#include "utilities/vmError.hpp"
#if defined(_WINDOWS)
#include "decoder_windows.hpp"
@@ -35,74 +37,94 @@
#include "decoder_elf.hpp"
#endif
-NullDecoder* Decoder::_decoder = NULL;
-NullDecoder Decoder::_do_nothing_decoder;
-Mutex* Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
- "DecoderLock");
+AbstractDecoder* Decoder::_shared_decoder = NULL;
+AbstractDecoder* Decoder::_error_handler_decoder = NULL;
+NullDecoder Decoder::_do_nothing_decoder;
+Mutex* Decoder::_shared_decoder_lock = new Mutex(Mutex::native,
+ "SharedDecoderLock");
-// _decoder_lock should already acquired before enter this method
-NullDecoder* Decoder::get_decoder() {
- assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
+AbstractDecoder* Decoder::get_shared_instance() {
+ assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(),
"Require DecoderLock to enter");
- if (_decoder != NULL) {
- return _decoder;
+ if (_shared_decoder == NULL) {
+ _shared_decoder = create_decoder();
}
+ return _shared_decoder;
+}
- // Decoder is a secondary service. Although, it is good to have,
- // but we can live without it.
+AbstractDecoder* Decoder::get_error_handler_instance() {
+ if (_error_handler_decoder == NULL) {
+ _error_handler_decoder = create_decoder();
+ }
+ return _error_handler_decoder;
+}
+
+
+AbstractDecoder* Decoder::create_decoder() {
+ AbstractDecoder* decoder;
#if defined(_WINDOWS)
- _decoder = new (std::nothrow) WindowsDecoder();
+ decoder = new (std::nothrow) WindowsDecoder();
#elif defined (__APPLE__)
- _decoder = new (std::nothrow)MachODecoder();
+ decoder = new (std::nothrow)MachODecoder();
#else
- _decoder = new (std::nothrow)ElfDecoder();
+ decoder = new (std::nothrow)ElfDecoder();
#endif
- if (_decoder == NULL || _decoder->has_error()) {
- if (_decoder != NULL) {
- delete _decoder;
+ if (decoder == NULL || decoder->has_error()) {
+ if (decoder != NULL) {
+ delete decoder;
}
- _decoder = &_do_nothing_decoder;
+ decoder = &_do_nothing_decoder;
}
- return _decoder;
+ return decoder;
}
bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
- NullDecoder* decoder = get_decoder();
+ assert(_shared_decoder_lock != NULL, "Just check");
+ bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+ AbstractDecoder* decoder = error_handling_thread ?
+ get_error_handler_instance(): get_shared_instance();
assert(decoder != NULL, "null decoder");
return decoder->decode(addr, buf, buflen, offset, modulepath);
}
bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
- NullDecoder* decoder = get_decoder();
+ assert(_shared_decoder_lock != NULL, "Just check");
+ bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+ AbstractDecoder* decoder = error_handling_thread ?
+ get_error_handler_instance(): get_shared_instance();
assert(decoder != NULL, "null decoder");
return decoder->demangle(symbol, buf, buflen);
}
bool Decoder::can_decode_C_frame_in_vm() {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
- NullDecoder* decoder = get_decoder();
+ assert(_shared_decoder_lock != NULL, "Just check");
+ bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+ AbstractDecoder* decoder = error_handling_thread ?
+ get_error_handler_instance(): get_shared_instance();
assert(decoder != NULL, "null decoder");
return decoder->can_decode_C_frame_in_vm();
}
-// shutdown real decoder and replace it with
-// _do_nothing_decoder
+/*
+ * Shutdown shared decoder and replace it with
+ * _do_nothing_decoder. Do nothing with error handler
+ * instance, since the JVM is going down.
+ */
void Decoder::shutdown() {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
+ assert(_shared_decoder_lock != NULL, "Just check");
+ MutexLockerEx locker(_shared_decoder_lock, true);
- if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
- delete _decoder;
+ if (_shared_decoder != NULL &&
+ _shared_decoder != &_do_nothing_decoder) {
+ delete _shared_decoder;
}
- _decoder = &_do_nothing_decoder;
+ _shared_decoder = &_do_nothing_decoder;
}
--- a/hotspot/src/share/vm/utilities/decoder.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/decoder.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
-class NullDecoder: public CHeapObj {
+class AbstractDecoder : public CHeapObj {
public:
// status code for decoding native C frame
enum decoder_status {
@@ -43,6 +43,34 @@
helper_init_error // SymInitialize failed (Windows only)
};
+ // decode an pc address to corresponding function name and an offset from the beginning of
+ // the function
+ virtual bool decode(address pc, char* buf, int buflen, int* offset,
+ const char* modulepath = NULL) = 0;
+ // demangle a C++ symbol
+ virtual bool demangle(const char* symbol, char* buf, int buflen) = 0;
+ // if the decoder can decode symbols in vm
+ virtual bool can_decode_C_frame_in_vm() const = 0;
+
+ virtual decoder_status status() const {
+ return _decoder_status;
+ }
+
+ virtual bool has_error() const {
+ return is_error(_decoder_status);
+ }
+
+ static bool is_error(decoder_status status) {
+ return (status > 0);
+ }
+
+protected:
+ decoder_status _decoder_status;
+};
+
+// Do nothing decoder
+class NullDecoder : public AbstractDecoder {
+public:
NullDecoder() {
_decoder_status = not_available;
}
@@ -61,40 +89,34 @@
virtual bool can_decode_C_frame_in_vm() const {
return false;
}
-
- virtual decoder_status status() const {
- return _decoder_status;
- }
-
- virtual bool has_error() const {
- return is_error(_decoder_status);
- }
-
- static bool is_error(decoder_status status) {
- return (status > 0);
- }
-
-protected:
- decoder_status _decoder_status;
};
-class Decoder: AllStatic {
+class Decoder : AllStatic {
public:
static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
static bool demangle(const char* symbol, char* buf, int buflen);
static bool can_decode_C_frame_in_vm();
+ // shutdown shared instance
static void shutdown();
protected:
- static NullDecoder* get_decoder();
+ // shared decoder instance, _shared_instance_lock is needed
+ static AbstractDecoder* get_shared_instance();
+ // a private instance for error handler. Error handler can be
+ // triggered almost everywhere, including signal handler, where
+ // no lock can be taken. So the shared decoder can not be used
+ // in this scenario.
+ static AbstractDecoder* get_error_handler_instance();
+ static AbstractDecoder* create_decoder();
private:
- static NullDecoder* _decoder;
- static NullDecoder _do_nothing_decoder;
+ static AbstractDecoder* _shared_decoder;
+ static AbstractDecoder* _error_handler_decoder;
+ static NullDecoder _do_nothing_decoder;
protected:
- static Mutex* _decoder_lock;
+ static Mutex* _shared_decoder_lock;
};
#endif // SHARE_VM_UTILITIES_DECODER_HPP
--- a/hotspot/src/share/vm/utilities/decoder_elf.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/decoder_elf.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -30,7 +30,7 @@
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
-class ElfDecoder: public NullDecoder {
+class ElfDecoder : public AbstractDecoder {
public:
ElfDecoder() {
--- a/hotspot/src/share/vm/utilities/events.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/events.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -68,6 +68,10 @@
}
}
+void Events::print() {
+ print_all(tty);
+}
+
void Events::init() {
if (LogEvents) {
_messages = new StringEventLog("Events");
--- a/hotspot/src/share/vm/utilities/events.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/events.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -35,20 +35,12 @@
// This facility is extremly useful for post-mortem debugging. The eventlog
// often provides crucial information about events leading up to the crash.
//
-// All arguments past the format string must be passed as an intptr_t.
-//
-// To log a single event use:
-// Events::log("New nmethod has been created " INTPTR_FORMAT, nm);
-//
-// To log a block of events use:
-// EventMark m("GarbageCollecting %d", (intptr_t)gc_number);
-//
-// The constructor to eventlog indents the eventlog until the
-// destructor has been executed.
-//
-// IMPLEMENTATION RESTRICTION:
-// Max 3 arguments are saved for each logged event.
-//
+// Abstractly the logs can record whatever they way but normally they
+// would record at least a timestamp and the current Thread, along
+// with whatever data they need in a ring buffer. Commonly fixed
+// length text messages are recorded for simplicity but other
+// strategies could be used. Several logs are provided by default but
+// new instances can be created as needed.
// The base event log dumping class that is registered for dumping at
// crash time. This is a very generic interface that is mainly here
@@ -79,7 +71,7 @@
template <class T> class EventLogBase : public EventLog {
template <class X> class EventRecord {
public:
- jlong timestamp;
+ double timestamp;
Thread* thread;
X data;
};
@@ -102,6 +94,10 @@
_records = new EventRecord<T>[length];
}
+ double fetch_timestamp() {
+ return os::elapsedTime();
+ }
+
// move the ring buffer to next open slot and return the index of
// the slot to use for the current message. Should only be called
// while mutex is held.
@@ -130,7 +126,7 @@
void print(outputStream* out, T& e);
void print(outputStream* out, EventRecord<T>& e) {
- out->print("Event: " INT64_FORMAT " ", e.timestamp);
+ out->print("Event: %.3f ", e.timestamp);
if (e.thread != NULL) {
out->print("Thread " INTPTR_FORMAT " ", e.thread);
}
@@ -155,7 +151,7 @@
void logv(Thread* thread, const char* format, va_list ap) {
if (!should_log()) return;
- jlong timestamp = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ double timestamp = fetch_timestamp();
MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
int index = compute_log_index();
_records[index].thread = thread;
@@ -193,9 +189,8 @@
public:
static void print_all(outputStream* out);
- static void print() {
- print_all(tty);
- }
+ // Dump all events to the tty
+ static void print();
// Logs a generic message with timestamp and format as printf.
static void log(Thread* thread, const char* format, ...);
@@ -255,6 +250,7 @@
out->print_cr("%s (%d events):", _name, _count);
if (_count == 0) {
out->print_cr("No events");
+ out->cr();
return;
}
--- a/hotspot/src/share/vm/utilities/preserveException.cpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/preserveException.cpp Wed Jul 05 18:03:08 2017 +0200
@@ -32,9 +32,9 @@
thread = Thread::current();
_thread = thread;
_preserved_exception_oop = Handle(thread, _thread->pending_exception());
- _thread->clear_pending_exception(); // Needed to avoid infinite recursion
_preserved_exception_line = _thread->exception_line();
_preserved_exception_file = _thread->exception_file();
+ _thread->clear_pending_exception(); // Needed to avoid infinite recursion
}
--- a/hotspot/src/share/vm/utilities/vmError.hpp Thu Feb 16 13:01:32 2012 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.hpp Wed Jul 05 18:03:08 2017 +0200
@@ -27,11 +27,12 @@
#include "utilities/globalDefinitions.hpp"
-
+class Decoder;
class VM_ReportJavaOutOfMemory;
class VMError : public StackObj {
friend class VM_ReportJavaOutOfMemory;
+ friend class Decoder;
enum ErrorType {
internal_error = 0xe0000000,
--- a/jdk/.hgtags Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/.hgtags Wed Jul 05 18:03:08 2017 +0200
@@ -147,3 +147,4 @@
54202e0148ec7d4570cab5bc9b00d216a7677569 jdk8-b23
34029a0c69bba882264a29fc822f8283fd15f104 jdk8-b24
ec17fbe5b8fbc52da070eec43b4711d9354b2ab8 jdk8-b25
+5aca406e87cb9144a9405be312dadd728a9c6fe2 jdk8-b26
--- a/jdk/make/com/sun/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/com/sun/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -47,7 +47,6 @@
org rowset net/httpserver
SUBDIRS_misc = $(SCRIPT_SUBDIR) tracing servicetag nio demo
-# Omit mirror since it's built with the apt tool.
SUBDIRS_tools = tools
include $(BUILDDIR)/common/Subdirs.gmk
--- a/jdk/make/com/sun/nio/sctp/Exportedfiles.gmk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/com/sun/nio/sctp/Exportedfiles.gmk Wed Jul 05 18:03:08 2017 +0200
@@ -29,11 +29,11 @@
ifneq ($(PLATFORM), windows)
FILES_export = \
- sun/nio/ch/SctpAssocChange.java \
- sun/nio/ch/SctpChannelImpl.java \
- sun/nio/ch/SctpNet.java \
- sun/nio/ch/SctpPeerAddrChange.java \
- sun/nio/ch/SctpResultContainer.java \
- sun/nio/ch/SctpServerChannelImpl.java \
- sun/nio/ch/SctpStdSocketOption.java
+ sun/nio/ch/sctp/AssociationChange.java \
+ sun/nio/ch/sctp/SctpChannelImpl.java \
+ sun/nio/ch/sctp/SctpNet.java \
+ sun/nio/ch/sctp/PeerAddrChange.java \
+ sun/nio/ch/sctp/ResultContainer.java \
+ sun/nio/ch/sctp/SctpServerChannelImpl.java \
+ sun/nio/ch/sctp/SctpStdSocketOption.java
endif
--- a/jdk/make/com/sun/nio/sctp/FILES_java.gmk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/com/sun/nio/sctp/FILES_java.gmk Wed Jul 05 18:03:08 2017 +0200
@@ -42,25 +42,25 @@
com/sun/nio/sctp/SendFailedNotification.java \
com/sun/nio/sctp/ShutdownNotification.java \
\
- sun/nio/ch/SctpMessageInfoImpl.java \
- sun/nio/ch/SctpStdSocketOption.java
+ sun/nio/ch/sctp/MessageInfoImpl.java \
+ sun/nio/ch/sctp/SctpStdSocketOption.java
ifneq ($(PLATFORM), windows)
FILES_java += \
- sun/nio/ch/SctpAssocChange.java \
- sun/nio/ch/SctpAssociationImpl.java \
- sun/nio/ch/SctpChannelImpl.java \
- sun/nio/ch/SctpMultiChannelImpl.java \
- sun/nio/ch/SctpNet.java \
- sun/nio/ch/SctpNotification.java \
- sun/nio/ch/SctpPeerAddrChange.java \
- sun/nio/ch/SctpResultContainer.java \
- sun/nio/ch/SctpSendFailed.java \
- sun/nio/ch/SctpServerChannelImpl.java \
- sun/nio/ch/SctpShutdown.java
+ sun/nio/ch/sctp/AssociationChange.java \
+ sun/nio/ch/sctp/AssociationImpl.java \
+ sun/nio/ch/sctp/PeerAddrChange.java \
+ sun/nio/ch/sctp/ResultContainer.java \
+ sun/nio/ch/sctp/SctpChannelImpl.java \
+ sun/nio/ch/sctp/SctpMultiChannelImpl.java \
+ sun/nio/ch/sctp/SctpNet.java \
+ sun/nio/ch/sctp/SctpNotification.java \
+ sun/nio/ch/sctp/SctpServerChannelImpl.java \
+ sun/nio/ch/sctp/SendFailed.java \
+ sun/nio/ch/sctp/Shutdown.java
else
FILES_java += \
- sun/nio/ch/SctpChannelImpl.java \
- sun/nio/ch/SctpMultiChannelImpl.java \
- sun/nio/ch/SctpServerChannelImpl.java
+ sun/nio/ch/sctp/SctpChannelImpl.java \
+ sun/nio/ch/sctp/SctpMultiChannelImpl.java \
+ sun/nio/ch/sctp/SctpServerChannelImpl.java
endif
--- a/jdk/make/com/sun/nio/sctp/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/com/sun/nio/sctp/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -47,14 +47,16 @@
#
# Find platform-specific C source files
#
-vpath %.c $(PLATFORM_SRC)/native/sun/nio/ch
+vpath %.c $(PLATFORM_SRC)/native/sun/nio/ch/sctp
#
# Include nio.h, net_util.h, sun_nio_ch_IOStatus.h, etc
#
OTHER_INCLUDES += \
-I$(SHARE_SRC)/native/sun/nio/ch \
+ -I$(SHARE_SRC)/native/sun/nio/ch/sctp \
-I$(SHARE_SRC)/native/java/net \
+ -I$(PLATFORM_SRC)/native/sun/nio/ch \
-I$(PLATFORM_SRC)/native/java/net \
-I$(CLASSHDRDIR)/../../../../java/java.nio/nio/CClassHeaders
@@ -75,5 +77,5 @@
clean clobber::
$(RM) -r $(CLASSDESTDIR)/com/sun/nio/sctp
- $(RM) -r $(CLASSDESTDIR)/sun/nio/ch
+ $(RM) -r $(CLASSDESTDIR)/sun/nio/ch/sctp
--- a/jdk/make/com/sun/nio/sctp/mapfile-vers Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/com/sun/nio/sctp/mapfile-vers Wed Jul 05 18:03:08 2017 +0200
@@ -25,30 +25,30 @@
SUNWprivate_1.1 {
global:
- Java_sun_nio_ch_SctpNet_init;
- Java_sun_nio_ch_SctpNet_socket0;
- Java_sun_nio_ch_SctpNet_bindx;
- Java_sun_nio_ch_SctpNet_branch0;
- Java_sun_nio_ch_SctpNet_listen0;
- Java_sun_nio_ch_SctpNet_connect0;
- Java_sun_nio_ch_SctpNet_close0;
- Java_sun_nio_ch_SctpNet_preClose0;
- Java_sun_nio_ch_SctpNet_getLocalAddresses0;
- Java_sun_nio_ch_SctpNet_getRemoteAddresses0;
- Java_sun_nio_ch_SctpNet_getPrimAddrOption0;
- Java_sun_nio_ch_SctpNet_setPrimAddrOption0;
- Java_sun_nio_ch_SctpNet_setPeerPrimAddrOption0;
- Java_sun_nio_ch_SctpNet_getInitMsgOption0;
- Java_sun_nio_ch_SctpNet_setInitMsgOption0;
- Java_sun_nio_ch_SctpNet_getIntOption0;
- Java_sun_nio_ch_SctpNet_setIntOption0;
- Java_sun_nio_ch_SctpNet_shutdown0;
- Java_sun_nio_ch_SctpChannelImpl_initIDs;
- Java_sun_nio_ch_SctpChannelImpl_checkConnect;
- Java_sun_nio_ch_SctpChannelImpl_receive0;
- Java_sun_nio_ch_SctpChannelImpl_send0;
- Java_sun_nio_ch_SctpServerChannelImpl_initIDs;
- Java_sun_nio_ch_SctpServerChannelImpl_accept0;
+ Java_sun_nio_ch_sctp_SctpNet_init;
+ Java_sun_nio_ch_sctp_SctpNet_socket0;
+ Java_sun_nio_ch_sctp_SctpNet_bindx;
+ Java_sun_nio_ch_sctp_SctpNet_branch0;
+ Java_sun_nio_ch_sctp_SctpNet_listen0;
+ Java_sun_nio_ch_sctp_SctpNet_connect0;
+ Java_sun_nio_ch_sctp_SctpNet_close0;
+ Java_sun_nio_ch_sctp_SctpNet_preClose0;
+ Java_sun_nio_ch_sctp_SctpNet_getLocalAddresses0;
+ Java_sun_nio_ch_sctp_SctpNet_getRemoteAddresses0;
+ Java_sun_nio_ch_sctp_SctpNet_getPrimAddrOption0;
+ Java_sun_nio_ch_sctp_SctpNet_setPrimAddrOption0;
+ Java_sun_nio_ch_sctp_SctpNet_setPeerPrimAddrOption0;
+ Java_sun_nio_ch_sctp_SctpNet_getInitMsgOption0;
+ Java_sun_nio_ch_sctp_SctpNet_setInitMsgOption0;
+ Java_sun_nio_ch_sctp_SctpNet_getIntOption0;
+ Java_sun_nio_ch_sctp_SctpNet_setIntOption0;
+ Java_sun_nio_ch_sctp_SctpNet_shutdown0;
+ Java_sun_nio_ch_sctp_SctpChannelImpl_initIDs;
+ Java_sun_nio_ch_sctp_SctpChannelImpl_checkConnect;
+ Java_sun_nio_ch_sctp_SctpChannelImpl_receive0;
+ Java_sun_nio_ch_sctp_SctpChannelImpl_send0;
+ Java_sun_nio_ch_sctp_SctpServerChannelImpl_initIDs;
+ Java_sun_nio_ch_sctp_SctpServerChannelImpl_accept0;
JNI_OnLoad;
local:
*;
--- a/jdk/make/common/Release.gmk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/common/Release.gmk Wed Jul 05 18:03:08 2017 +0200
@@ -132,7 +132,6 @@
JDK_MAN_PAGES = \
$(JRE_MAN_PAGES) \
appletviewer.1 \
- apt.1 \
extcheck.1 \
idlj.1 \
jar.1 \
@@ -264,7 +263,6 @@
com/sun/java/swing \
com/sun/javadoc \
com/sun/jmx \
- com/sun/mirror \
com/sun/source \
com/sun/naming \
com/sun/security/auth \
@@ -346,7 +344,6 @@
com/sun/javadoc \
com/sun/jdi \
com/sun/jarsigner \
- com/sun/mirror \
com/sun/source \
com/sun/tools/classfile \
com/sun/tools/doclets \
@@ -356,16 +353,16 @@
com/sun/tools/hat \
com/sun/tools/javac \
com/sun/tools/javadoc \
- com/sun/tools/apt \
com/sun/tools/javah \
com/sun/tools/javap \
com/sun/tools/corba \
com/sun/tools/internal/xjc \
com/sun/tools/internal/ws \
- META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory \
- META-INF/services/com.sun.tools.xjc.Plugin \
+ META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \
+ META-INF/services/com.sun.tools.internal.xjc.Plugin \
com/sun/istack/internal/tools \
- com/sun/istack/internal/ws \
+ com/sun/tools/internal/jxc/ap \
+ com/sun/tools/internal/ws/wscompile/plugin/at_generated \
com/sun/codemodel \
com/sun/tools/internal/jxc \
com/sun/xml/internal/rngom \
@@ -438,7 +435,6 @@
java-rmi.cgi \
javac$(EXE_SUFFIX) \
javadoc$(EXE_SUFFIX) \
- apt$(EXE_SUFFIX) \
javah$(EXE_SUFFIX) \
javap$(EXE_SUFFIX) \
jcmd$(EXE_SUFFIX) \
@@ -525,13 +521,10 @@
$(ECHO) "com/sun/javadoc/" >> $@
$(ECHO) "com/sun/jdi/" >> $@
$(ECHO) "com/sun/jarsigner/" >> $@
- $(ECHO) "com/sun/mirror/" >> $@
$(ECHO) "com/sun/source/" >> $@
$(ECHO) "com/sun/istack/internal/tools/" >> $@
- $(ECHO) "com/sun/istack/internal/ws/" >> $@
$(ECHO) "META-INF/services/com.sun.jdi.connect.Connector" >> $@
$(ECHO) "META-INF/services/com.sun.jdi.connect.spi.TransportService" >> $@
- $(ECHO) "META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory" >> $@
$(ECHO) "META-INF/services/com.sun.tools.xjc.Plugin" >> $@
$(ECHO) "com/sun/tools/" >> $@
$(ECHO) "sun/jvmstat/" >> $@
@@ -1000,7 +993,7 @@
@#
@# files that might not exist need to be touched.
@#
- $(TOUCH) $(CLASSBINDIR)/META-INF/services/com.sun.tools.xjc.Plugin
+ $(TOUCH) $(CLASSBINDIR)/META-INF/services/com.sun.tools.internal.xjc.Plugin
@#
@# lib/tools.jar
@#
--- a/jdk/make/common/internal/Defs-jaxws.gmk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/common/internal/Defs-jaxws.gmk Wed Jul 05 18:03:08 2017 +0200
@@ -34,7 +34,6 @@
javax/xml/ws \
javax/jws \
javax/annotation \
- com/sun/istack/internal \
com/sun/xml/internal/bind \
com/sun/xml/internal/fastinfoset \
com/sun/xml/internal/messaging \
@@ -42,13 +41,13 @@
com/sun/xml/internal/txw2 \
com/sun/xml/internal/ws \
com/sun/xml/internal/stream/buffer
+
NOT_USED_PACKAGES += \
com/sun/tools/internal/txw2
IMPORT_TOOLS_PACKAGES += \
com/sun/codemodel \
com/sun/istack/internal/tools \
- com/sun/istack/internal/ws \
com/sun/xml/internal/rngom \
com/sun/xml/internal/xsom \
com/sun/xml/internal/dtdparser \
@@ -56,6 +55,9 @@
com/sun/tools/internal/ws \
com/sun/tools/internal/jxc \
org/relaxng \
- META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory \
- META-INF/services/com.sun.tools.internal.xjc.Plugin
+ META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \
+ META-INF/services/com.sun.tools.internal.xjc.Plugin \
+ com/sun/tools/internal/jxc/ap \
+ com/sun/tools/internal/ws/wscompile/plugin/at_generated
+
--- a/jdk/make/common/internal/Defs-langtools.gmk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/common/internal/Defs-langtools.gmk Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2012, 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
@@ -32,9 +32,7 @@
IMPORT_TOOLS_PACKAGES += \
com/sun/javadoc \
- com/sun/mirror \
com/sun/source \
- com/sun/tools/apt \
com/sun/tools/classfile \
com/sun/tools/doclets \
com/sun/tools/javac \
--- a/jdk/make/docs/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/docs/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2012, 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
@@ -358,64 +358,6 @@
#############################################################
#
-# mirrordocs
-#
-
-# Part of langtools
-ifdef LANGTOOLS_DIST
- ALL_OTHER_TARGETS += mirrordocs
-endif
-
-MIRROR_DOCDIR := $(JDK_API_DOCSDIR)/apt/mirror
-MIRROR2COREAPI := ../../$(JDKJRE2COREAPI)
-MIRROR_DOCTITLE := Mirror API
-MIRROR_WINDOWTITLE := Mirror API
-MIRROR_HEADER := <strong>Mirror API</strong>
-MIRROR_BOTTOM := $(call CommonBottom,$(MIRROR_FIRST_COPYRIGHT_YEAR))
-MIRROR_GROUPNAME := Packages
-MIRROR_OVERVIEW := $(IMPORTSRCDIR)/com/sun/mirror/overview.html
-MIRROR_REGEXP := com.sun.mirror.*
-# MIRROR_PKGS is located in NON_CORE_PKGS.gmk
-
-# The index.html, options, and packages files
-MIRROR_INDEX_FILE = $(MIRROR_DOCDIR)/index.html
-MIRROR_OPTIONS_FILE = $(DOCSTMPDIR)/mirror.options
-MIRROR_PACKAGES_FILE = $(DOCSTMPDIR)/mirror.packages
-
-mirrordocs: $(MIRROR_INDEX_FILE)
-
-# Set relative location to core api document root
-$(MIRROR_INDEX_FILE): GET2DOCSDIR=$(MIRROR2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(MIRROR_INDEX_FILE): $(MIRROR_OPTIONS_FILE) $(MIRROR_PACKAGES_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(MIRROR_OPTIONS_FILE),$(MIRROR_PACKAGES_FILE))
- $(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
- @$(MIRROR_OPTIONS_FILE) @$(MIRROR_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(MIRROR_OPTIONS_FILE): $(MIRROR_OVERVIEW)
- $(prep-target)
- @($(call OptionOnly,$(COMMON_JAVADOCFLAGS)) ; \
- $(call OptionPair,-sourcepath,$(RELEASEDOCS_SOURCEPATH)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-overview,$(MIRROR_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(MIRROR_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(MIRROR_WINDOWTITLE) $(DRAFT_WINTITLE));\
- $(call OptionPair,-header,$(MIRROR_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(MIRROR_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-group,$(MIRROR_GROUPNAME),$(MIRROR_REGEXP)); \
- $(call OptionTrip,-linkoffline,$(MIRROR2COREAPI),$(COREAPI_DOCSDIR)); \
- ) >> $@
-
-# Create a file with the package names in it
-$(MIRROR_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(MIRROR_PKGS))
- $(prep-target)
- $(call PackageFilter,$(MIRROR_PKGS))
-
-#############################################################
-#
# docletapidocs
#
--- a/jdk/make/docs/NON_CORE_PKGS.gmk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/docs/NON_CORE_PKGS.gmk Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2012, 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
@@ -71,11 +71,6 @@
TAGLETAPI_FILE = com/sun/tools/doclets/Taglet.java
-MIRROR_PKGS = com.sun.mirror.apt \
- com.sun.mirror.declaration \
- com.sun.mirror.type \
- com.sun.mirror.util
-
ATTACH_PKGS = com.sun.tools.attach \
com.sun.tools.attach.spi
--- a/jdk/make/java/management/mapfile-vers Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/java/management/mapfile-vers Wed Jul 05 18:03:08 2017 +0200
@@ -54,9 +54,6 @@
Java_sun_management_GcInfoBuilder_getLastGcInfo0;
Java_sun_management_GcInfoBuilder_getNumGcExtAttributes;
Java_sun_management_HotSpotDiagnostic_dumpHeap;
- Java_sun_management_HotSpotDiagnostic_executeDiagnosticCommand0;
- Java_sun_management_HotSpotDiagnostic_getDiagnosticCommandInfo0;
- Java_sun_management_HotSpotDiagnostic_getDiagnosticCommands0;
Java_sun_management_HotspotThread_getInternalThreadCount;
Java_sun_management_HotspotThread_getInternalThreadTimes0;
Java_sun_management_MemoryImpl_getMemoryManagers0;
--- a/jdk/make/launchers/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/launchers/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2012, 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,6 @@
define make-all-launchers
$(make-appletviewer)
-$(call make-launcher, apt, com.sun.tools.apt.Main, , )
$(call make-launcher, extcheck, com.sun.tools.extcheck.Main, , )
$(call make-launcher, idlj, com.sun.tools.corba.se.idl.toJavaPortable.Compile, , )
$(call make-launcher, jar, sun.tools.jar.Main, , )
--- a/jdk/make/launchers/Makefile.launcher Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/make/launchers/Makefile.launcher Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2012, 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
@@ -47,10 +47,6 @@
endif
# Some tools need the wildcard expansion option
-ifeq ($(PROGRAM),apt)
- WILDCARDS=true
- NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
-endif
ifeq ($(PROGRAM),javac)
WILDCARDS=true
MAIN_JAVA_ARGS += -J-Xss4m -J-ea:com.sun.tools...
--- a/jdk/src/linux/doc/man/apt.1 Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-." Copyright (c) 2004, 2011, 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.
-."
-.TH apt 1 "10 May 2011"
-
-.LP
-.SH "NAME"
-.LP
-.LP
-\f2apt\fP \- annotation processing tool
-.LP
-.SH "SYNOPSIS"
-.LP
-.LP
-\f2apt [\-classpath \fP\f2classpath\fP] [\-sourcepath \f2sourcepath\fP] [\-d \f2directory\fP] [\-s \f2directory\fP] [\-factorypath \f2path\fP] [\-factory \f2class\fP] [\-print] [\-nocompile] [\-A\f2key\fP[\f2=val\fP] ...] [\f2javac option\fP] sourcefiles [@files]
-.LP
-.SH "PARAMETERS"
-.LP
-.LP
-Options may be in any order. For a discussion of parameters which apply to a specific option, see OPTIONS below.
-.LP
-.RS 3
-.TP 3
-sourcefiles
-Zero or more source files to be processed.
-.TP 3
-@files
-One or more files that list source files or other options
-.RE
-
-.LP
-.SH "DESCRIPTION"
-.LP
-.LP
-\f3Note\fP: The \f2apt\fP tool and its associated API contained in the package \f2com.sun.mirror\fP have been deprecated since JDK 7 and are planned to be removed in the next major JDK release. Use the options available in the \f2javac(1)\fP tool and the APIs contained in the packages \f2javax.annotation.processing\fP and \f2javax.lang.model\fP to process annotations.
-.LP
-.LP
-The tool \f2apt\fP, annotation processing tool, includes reflective APIs and supporting infrastructure to process program annotations. The \f2apt\fP reflective APIs provide a build\-time, source\-based, read\-only view of program structure. These reflective APIs are designed to cleanly model the Java(TM) programming language's type system after the addition of generics. First, \f2apt\fP runs annotation processors that can produce new source code and other files. Next, \f2apt\fP can cause compilation of both original and generated source files, easing development. The reflective APIs and other APIs used to interact with the tool are subpackages of \f2com.sun.mirror\fP.
-.LP
-.LP
-A fuller discussion of how the tool operates as well as instructions for developing with \f2apt\fP are in
-.na
-\f4Getting Started with \fP\f4apt\fP. @
-.fi
-http://download.oracle.com/javase/7/docs/technotes/guides/apt/GettingStarted.html
-.LP
-.SH "OPTIONS"
-.LP
-.SS
-apt specific options
-.LP
-.RS 3
-.TP 3
-\-s dir
-Specify the directory root under which processor\-generated source files will be placed; files are placed in subdirectories based on package namespace.
-.TP 3
-\-nocompile
-Do not compile source files to class files.
-.TP 3
-\-print
-Print out textual representation of specified types; perform no annotation processing or compilation.
-.TP 3
-\-A[key[=val]]
-Options to pass to annotation processors \-\- these are not interpreted by \f2apt\fP directly, but are made available for use by individual processors
-.TP 3
-\-factorypath path
-Specify where to find annotation processor factories; if this option is used, the classpath is \f2not\fP searched for factories.
-.TP 3
-\-factory classname
-Name of annotation processor factory to use; bypasses default discovery process
-.TP 3
-\-version
-Print version information.
-.TP 3
-\-X
-Display information about non\-standard options.
-.RE
-
-.LP
-.SS
-Options shared with javac
-.LP
-.RS 3
-.TP 3
-\-d dir
-Specify where to place processor and javac generated class files
-.TP 3
-\-cp path or \-classpath path
-Specify where to find user class files and annotation processor factories. If \f2\-factorypath\fP is given, the classpath is not searched for factories.
-.RE
-
-.LP
-.LP
-Consult the javac(1) man page for information on \f2javac\fP options.
-.LP
-.SS
-Non\-Standard Options
-.LP
-.RS 3
-.TP 3
-\-XListAnnotationTypes
-List found annotation types.
-.TP 3
-\-XListDeclarations
-List specified and included declarations.
-.TP 3
-\-XPrintAptRounds
-Print information about initial and recursive \f2apt\fP rounds.
-.TP 3
-\-XPrintFactoryInfo
-Print information about which annotations a factory is asked to process.
-.TP 3
-\-XclassesAsDecls
-Treat both class and source files as declarations to process.
-.RE
-
-.LP
-.LP
-\f3Note\fP: Because these options are non\-standard, they are subject to change without notice.
-.LP
-.SH "NOTES"
-.LP
-.LP
-The \f2apt\fP tool and its associated API contained in the package \f2com.sun.mirror\fP have been deprecated since JDK 7 and are planned to be removed in the next major JDK release. Use the options available in the \f2javac(1)\fP tool and the APIs contained in the packages \f2javax.annotation.processing\fP and \f2javax.lang.model\fP to process annotations.
-.LP
-.SH "SEE ALSO"
-.LP
-.RS 3
-.TP 2
-o
-javac(1), java(1)
-.RE
-
-.LP
-
--- a/jdk/src/linux/doc/man/ja/apt.1 Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-." Copyright (c) 2004, 2011, 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.
-."
-.TH apt 1 "07 May 2011"
-
-.LP
-.SH "NAME"
-.LP
-.LP
-\f2apt\fP \- Ãí¼á½èÍý¥Ä¡¼¥ë
-.LP
-.SH "·Á¼°"
-.LP
-.LP
-\f2apt [\-classpath \fP\f2classpath\fP] [\-sourcepath \f2sourcepath\fP] [\-d \f2directory\fP] [\-s \f2directory\fP] [\-factorypath \f2path\fP] [\-factory \f2class\fP] [\-print] [\-nocompile] [\-A\f2key\fP[\f2=val\fP] ...] [\f2javac option\fP] sourcefiles [@files]
-.LP
-.SH "¥Ñ¥é¥á¡¼¥¿"
-.LP
-.LP
-¥ª¥×¥·¥ç¥ó¤Î»ØÄê½ç½ø¤Ë·è¤Þ¤ê¤Ï¤¢¤ê¤Þ¤»¤ó¡£ÆÃÄê¤Î¥ª¥×¥·¥ç¥ó¤ËŬÍѤµ¤ì¤ë¥Ñ¥é¥á¡¼¥¿¤Ë¤Ä¤¤¤Æ¤Ï¡¢²¼µ¤Î¡Ö¥ª¥×¥·¥ç¥ó¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.RS 3
-.TP 3
-sourcefiles
-¥¼¥í¡¢1 ¤Ä¡¢¤Þ¤¿¤ÏÊ£¿ô¤Î½èÍýÂоݤΥ½¡¼¥¹¥Õ¥¡¥¤¥ë
-.TP 3
-@files
-¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¾¤Î¥ª¥×¥·¥ç¥ó¤ò°ìÍ÷ɽ¼¨¤¹¤ë 1 ¤Ä¤Þ¤¿¤ÏÊ£¿ô¤Î¥Õ¥¡¥¤¥ë
-.RE
-
-.LP
-.SH "ÀâÌÀ"
-.LP
-.LP
-\f3Ãí\fP: \f2apt\fP ¥Ä¡¼¥ë¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2com.sun.mirror\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤½¤ì¤Ë´ØÏ¢¤·¤¿ API ¤Ï¡¢JDK 7 °Ê¹ßÈó¿ä¾©¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢JDK ¤Î¼¡¤Î¥á¥¸¥ã¡¼¥ê¥ê¡¼¥¹¤Çºï½ü¤µ¤ì¤ëͽÄê¤Ç¤¹¡£\f2javac(1)\fP ¥Ä¡¼¥ë¤ÇÍøÍѲÄǽ¤Ê¥ª¥×¥·¥ç¥ó¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2javax.annotation.processing\fP ¤ª¤è¤Ó \f2javax.lang.model\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë API ¤ò»ÈÍѤ·¤Æ¡¢Ãí¼á¤ò½èÍý¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.LP
-Ãí¼á½èÍý¥Ä¡¼¥ë \f2apt\fP ¤Ï¡¢¥ê¥Õ¥ì¥¯¥È API ¤È¥µ¥Ý¡¼¥È¥¤¥ó¥Õ¥é¥¹¥È¥é¥¯¥Á¥ã¡¼¤«¤é¹½À®¤µ¤ì¡¢¥×¥í¥°¥é¥àÃí¼á¤ò½èÍý¤·¤Þ¤¹¡£\f2apt\fP ¥ê¥Õ¥ì¥¯¥È API ¤Ï¡¢ ¹½ÃÛ»þ¤Î¥½¡¼¥¹¥Ù¡¼¥¹¤Ç¡¢¥×¥í¥°¥é¥à¹½Â¤¤Ë´Ø¤¹¤ëÆɤ߼è¤êÀìÍѥӥ塼¤òÄ󶡤·¤Þ¤¹¡£¤³¤ì¤é¤Î¥ê¥Õ¥ì¥¯¥È API ¤Ï¡¢Áí¾Î¤òÄɲä·¤¿¸å¤Ë¡¢Java(TM) ¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Î·¿¥·¥¹¥Æ¥à¤òÀµ¤·¤¯¥â¥Ç¥ë²½¤¹¤ë¤è¤¦¤ËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ºÇ½é¤Ë¡¢\f2apt\fP ¤Ï¡¢¿·¤·¤¤¥½¡¼¥¹¥³¡¼¥É¤È¾¤Î¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ëÃí¼á¥×¥í¥»¥Ã¥µ¤ò¼Â¹Ô¤·¤Þ¤¹¡£¼¡¤Ë¡¢\f2apt\fP ¤Ï¡¢¸µ¤Î¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÈÀ¸À®¤·¤¿¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÎξÊý¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤¿¤á¡¢³«È¯¤¬³Ú¤Ë¤Ê¤ê¤Þ¤¹¡£¥Ä¡¼¥ë¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Ë»ÈÍѤµ¤ì¤ë¥ê¥Õ¥ì¥¯¥È API ¤Ê¤É¤Î API ¤Ï¡¢\f2com.sun.mirror\fP ¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Ç¤¹¡£
-.LP
-.LP
-¥Ä¡¼¥ë¤Îµ¡Ç½¤Ë´Ø¤¹¤ë¾ÜºÙ¤È¡¢\f2apt\fP ¤ò»ÈÍѤ·¤¿³«È¯ÊýË¡¤Ë¤Ä¤¤¤Æ¤Ï¡¢
-.na
-\f4¡Öapt ÆþÌç¡×\fP @
-.fi
-http://java.sun.com/javase/6/docs/technotes/guides/apt/GettingStarted.html¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.SH "¥ª¥×¥·¥ç¥ó"
-.LP
-.SS
-apt ¸ÇͤΥª¥×¥·¥ç¥ó
-.LP
-.RS 3
-.TP 3
-\-s dir
-¥×¥í¥»¥Ã¥µ¤ÎÀ¸À®¤¹¤ë¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤òÃÖ¤¯¥Ç¥£¥ì¥¯¥È¥ê¥ë¡¼¥È¤ò»ØÄꤷ¤Þ¤¹¡£ ¥Õ¥¡¥¤¥ë¤Ï¡¢¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¶õ´Ö¤Ë´ð¤Å¤¤¤Æ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ËÃÖ¤«¤ì¤Þ¤¹¡£
-.TP 3
-\-nocompile
-¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ò¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤Ë¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤»¤ó¡£
-.TP 3
-\-print
-»ØÄꤷ¤¿¥¿¥¤¥×¤Î¥Æ¥¥¹¥Èɽ¸½¤ò½ÐÎϤ·¤Þ¤¹¡£ Ãí¼á½èÍý¤Þ¤¿¤Ï¥³¥ó¥Ñ¥¤¥ë¤Ï¹Ô¤¤¤Þ¤»¤ó¡£
-.TP 3
-\-A[key[=val]]
-Ãí¼á¥×¥í¥»¥Ã¥µ¤ØÅϤ¹¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\f2apt\fP ¤¬Ä¾Àܲò¼á¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢¤½¤ì¤¾¤ì¤Î¥×¥í¥»¥Ã¥µ¤Ë¤è¤Ã¤Æ»ÈÍѤǤ¤ë¤è¤¦¤ËÊѤ¨¤é¤ì¤Þ¤¹¡£
-.TP 3
-\-factorypath path
-Ãí¼á¥×¥í¥»¥Ã¥µ¥Õ¥¡¥¯¥È¥ê¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢¥¯¥é¥¹¥Ñ¥¹¤Î¥Õ¥¡¥¯¥È¥ê¤Ï¸¡º÷¤µ¤ì¤Þ¤»¤ó¡£
-.TP 3
-\-factory classname
-»ÈÍѤ¹¤ëÃí¼á¥×¥í¥»¥Ã¥µ¥Õ¥¡¥¯¥È¥ê¤Î̾Á°¤Ç¤¹¡£ ¥Ç¥Õ¥©¥ë¥È¤Î¸¡½Ð¥×¥í¥»¥¹¤ò¾Êά¤·¤Þ¤¹¡£
-.TP 3
-\-version
-¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤ò½ÐÎϤ·¤Þ¤¹¡£
-.TP 3
-\-X
-Èóɸ½à¥ª¥×¥·¥ç¥ó¤Ë´Ø¤¹¤ë¾ðÊó¤òɽ¼¨¤·¤Þ¤¹¡£
-.RE
-
-.LP
-.SS
-javac ¤È¶¦ÍѤ¹¤ë¥ª¥×¥·¥ç¥ó
-.LP
-.RS 3
-.TP 3
-\-d dir
-¥×¥í¥»¥Ã¥µ¤È javac À¸À®¤Î¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤òÃÖ¤¯¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£
-.TP 3
-\-cp path ¤Þ¤¿¤Ï \-classpath path
-¥æ¡¼¥¶¡¼¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤ÈÃí¼á¥×¥í¥»¥Ã¥µ¥Õ¥¡¥¯¥È¥ê¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£\f2\-factorypath\fP ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥¯¥é¥¹¥Ñ¥¹¤Î¥Õ¥¡¥¯¥È¥ê¤Ï¸¡º÷¤µ¤ì¤Þ¤»¤ó¡£
-.RE
-
-.LP
-.LP
-\f2javac\fP ¥ª¥×¥·¥ç¥ó¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢javac(1) ¤Î¥Þ¥Ë¥å¥¢¥ë¥Ú¡¼¥¸¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.SS
-Èóɸ½à¥ª¥×¥·¥ç¥ó
-.LP
-.RS 3
-.TP 3
-\-XListAnnotationTypes
-Ãí¼á¤Î·¿¤Ë¸¡½Ð¤µ¤ì¤ë¥ê¥¹¥È.
-.TP 3
-\-XListDeclarations
-»ØÄꤪ¤è¤ÓÀë¸À¤¬¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤ë¥ê¥¹¥È.
-.TP 3
-\-XPrintAptRounds
-½é´ü¤ª¤è¤ÓºÆµ¢Åª¤Ê \f2apt\fP ¥é¥¦¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤ò½ÐÎϤ¹¤ë.
-.TP 3
-\-XPrintFactoryInfo
-½èÍý¤òÍ׵᤹¤ë¥Õ¥¡¥¯¥È¥ê¤ÎÃí¼á¤Ë´Ø¤¹¤ë¾ðÊó¤ò½ÐÎϤ¹¤ë.
-.TP 3
-\-XclassesAsDecls
-¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤È¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÎξÊý¤ò¡¢½èÍýÂоݤÎÀë¸À¤È¤·¤Æ½èÍý¤·¤Þ¤¹¡£
-.RE
-
-.LP
-.LP
-\f3Ãí\fP: ¤³¤ì¤é¤ÏÈóɸ½à¥ª¥×¥·¥ç¥ó¤Ê¤Î¤Ç¡¢Í½¹ð¤Ê¤¯Êѹ¹¤µ¤ì¤ë²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹¡£
-.LP
-.SH "Ãí"
-.LP
-.LP
-\f2apt\fP ¥Ä¡¼¥ë¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2com.sun.mirror\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤½¤ì¤Ë´ØÏ¢¤·¤¿ API ¤Ï¡¢JDK 7 °Ê¹ßÈó¿ä¾©¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢JDK ¤Î¼¡¤Î¥á¥¸¥ã¡¼¥ê¥ê¡¼¥¹¤Çºï½ü¤µ¤ì¤ëͽÄê¤Ç¤¹¡£\f2javac(1)\fP ¥Ä¡¼¥ë¤ÇÍøÍѲÄǽ¤Ê¥ª¥×¥·¥ç¥ó¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2javax.annotation.processing\fP ¤ª¤è¤Ó \f2javax.lang.model\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë API ¤ò»ÈÍѤ·¤Æ¡¢Ãí¼á¤ò½èÍý¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.SH "´ØÏ¢¹àÌÜ"
-.LP
-.RS 3
-.TP 2
-o
-javac(1), java(1)
-.RE
-
-.LP
-
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBEKey.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBEKey.java Wed Jul 05 18:03:08 2017 +0200
@@ -55,9 +55,12 @@
// Should allow an empty password.
passwd = new char[0];
}
- for (int i=0; i<passwd.length; i++) {
- if ((passwd[i] < '\u0020') || (passwd[i] > '\u007E')) {
- throw new InvalidKeySpecException("Password is not ASCII");
+ // Accept "\0" to signify "zero-length password with no terminator".
+ if (!(passwd.length == 1 && passwd[0] == 0)) {
+ for (int i=0; i<passwd.length; i++) {
+ if ((passwd[i] < '\u0020') || (passwd[i] > '\u007E')) {
+ throw new InvalidKeySpecException("Password is not ASCII");
+ }
}
}
this.key = new byte[passwd.length];
--- a/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java Wed Jul 05 18:03:08 2017 +0200
@@ -60,11 +60,16 @@
static byte[] derive(char[] chars, byte[] salt,
int ic, int n, int type) {
- // Add in trailing NULL terminator.
+ // Add in trailing NULL terminator. Special case:
+ // no terminator if password is "\0".
int length = chars.length*2;
- if (length != 0) {
+ if (length == 2 && chars[0] == 0) {
+ chars = new char[0];
+ length = 0;
+ } else {
length += 2;
}
+
byte[] passwd = new byte[length];
for (int i = 0, j = 0; i < chars.length; i++, j+=2) {
passwd[j] = (byte) ((chars[i] >>> 8) & 0xFF);
@@ -133,6 +138,9 @@
}
private static void concat(byte[] src, byte[] dst, int start, int len) {
+ if (src.length == 0) {
+ return;
+ }
int loop = len / src.length;
int off, i;
for (i = 0, off = 0; i < loop; i++, off += src.length)
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java Wed Jul 05 18:03:08 2017 +0200
@@ -137,6 +137,11 @@
g.setColor(progressBar.getForeground());
barRectHeight -= 2;
barRectWidth -= 2;
+
+ if (barRectWidth <= 0 || barRectHeight <= 0) {
+ return;
+ }
+
Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke((float)(vertical ? barRectWidth : barRectHeight),
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
--- a/jdk/src/share/classes/com/sun/management/DiagnosticCommandArgumentInfo.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import java.beans.ConstructorProperties;
-
-/**
- * Diagnostic Command Argument information. It contains the description
- * of one parameter of the diagnostic command. A parameter can either be an
- * option or an argument. Options are identified by the option name while
- * arguments are identified by their position in the command line. The generic
- * syntax of a diagnostic command is:
- * <blockquote>
- * <command name> [<option>=<value>] [<argument_value>]
- * </blockquote>
- * Example:
- * <blockquote>
- * command_name option1=value1 option2=value argumentA argumentB argumentC
- * </blockquote>
- * In this command line, the diagnostic command receives five parameters, two
- * options named {@code option1} and {@code option2}, and three arguments.
- * argumentA's position is 0, argumentB's position is 1 and argumentC's
- * position is 2.
- *
- * @author Frederic Parain
- * @since 7u4
- */
-
-public class DiagnosticCommandArgumentInfo {
- private final String name;
- private final String description;
- private final String type;
- private final String defaultValue;
- private final boolean mandatory;
- private final boolean option;
- private final int position;
-
- /**
- * Returns the argument name
- *
- * @return the argument name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the argument description
- *
- * @return the argument description
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Returns the argument type
- *
- * @return the argument type
- */
- public String getType() {
- return type;
- }
-
- /**
- * Returns the default value as a String if a default value
- * is defined, null otherwise.
- *
- * @return the default value as a String if a default value
- * is defined, null otherwise.
- */
- public String getDefault() {
- return defaultValue;
- }
-
- /**
- * Returns {@code true} if the argument is mandatory,
- * {@code false} otherwise
- *
- * @return {@code true} if the argument is mandatory,
- * {@code false} otherwise
- */
- public boolean isMandatory() {
- return mandatory;
- }
-
- /**
- * Returns {@code true} if the argument is an option,
- * {@code false} otherwise. Options have to be specified using the
- * <key>=<value> syntax on the command line, while other
- * arguments are specified with a single <value> field and are
- * identified by their position on command line.
- *
- * @return {@code true} if the argument is an option,
- * {@code false} otherwise
- */
- public boolean isOption() {
- return option;
- }
-
- /**
- * Returns the expected position of this argument if it is not an option,
- * -1 otherwise. Argument position if defined from left to right,
- * starting at zero and ignoring the diagnostic command name and
- * options.
- *
- * @return the expected position of this argument if it is not an option,
- * -1 otherwise.
- */
- public int getPosition() {
- return position;
- }
-
- @ConstructorProperties({"name","description","type","default",
- "mandatory","option","position"})
- public DiagnosticCommandArgumentInfo(String name, String description,
- String type, String defaultValue,
- boolean mandatory, boolean option,
- int position) {
- this.name = name;
- this.description = description;
- this.type = type;
- this.defaultValue = defaultValue;
- this.mandatory = mandatory;
- this.option = option;
- this.position = position;
- }
-}
--- a/jdk/src/share/classes/com/sun/management/DiagnosticCommandInfo.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import java.beans.ConstructorProperties;
-import java.util.List;
-
-/**
- * Diagnostic command information. It contains the description of a
- * diagnostic command.
- *
- * @author Frederic Parain
- * @since 7u4
- */
-
-public class DiagnosticCommandInfo {
- private final String name;
- private final String description;
- private final String impact;
- private final boolean enabled;
- private final List<DiagnosticCommandArgumentInfo> arguments;
-
- /**
- * Returns the diagnostic command name
- *
- * @return the diagnostic command name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the diagnostic command description
- *
- * @return the diagnostic command description
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Returns the potential impact of the diagnostic command execution
- * on the Java virtual machine behavior
- *
- * @return the potential impact of the diagnostic command execution
- * on the Java virtual machine behavior
- */
- public String getImpact() {
- return impact;
- }
-
- /**
- * Returns {@code true} if the diagnostic command is enabled,
- * {@code false} otherwise. The enabled/disabled
- * status of a diagnostic command can evolve during
- * the lifetime of the Java virtual machine.
- *
- * @return {@code true} if the diagnostic command is enabled,
- * {@code false} otherwise
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Returns the list of the diagnostic command arguments description.
- * If the diagnostic command has no arguments, it returns an empty list.
- *
- * @return a list of the diagnostic command arguments description
- */
- public List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
- return arguments;
- }
-
- @ConstructorProperties({"name", "description","impact","enabled",
- "argumentsInfo"})
- public DiagnosticCommandInfo(String name, String description,
- String impact, boolean enabled,
- List<DiagnosticCommandArgumentInfo> arguments)
- {
- this.name = name;
- this.description = description;
- this.impact = impact;
- this.enabled = enabled;
- this.arguments = arguments;
- }
-}
--- a/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -31,11 +31,6 @@
/**
* Diagnostic management interface for the HotSpot Virtual Machine.
*
- * <p>{@linkplain #getDiagnosticCommands Diagnostic commands}
- * are actions that can be invoked dynamically and
- * executed in a target Java virtual machine, mainly for troubleshooting
- * and diagnosis.
- *
* <p>The diagnostic MBean is registered to the platform MBeanServer
* as are other platform MBeans.
*
@@ -116,108 +111,4 @@
* ManagementPermission("control").
*/
public void setVMOption(String name, String value);
-
- /**
- * Returns the {@linkplain DiagnosticCommandInfo#getName() names}
- * of all diagnostic commands.
- * A diagnostic command is an action that can be invoked dynamically
- * mainly for troubleshooting and diagnosis. The list of diagnostic
- * commands may change at runtime. A diagnostic command may be
- * {@linkplain DiagnosticCommandInfo#isEnabled disabled} but will
- * not be removed from a previously returned list.
- *
- * @return the names of all diagnostic commands.
- *
- * @since 7u4
- */
- public List<String> getDiagnosticCommands();
-
- /**
- * Returns a {@code DiagnosticCommandInfo} object describing the
- * diagnostic command of the specified name {@code command}
- *
- * @param command a diagnostic command name
- * @return a {@code DiagnosticCommandInfo} object
- * @throws java.lang.IllegalArgumentException if the {@code command}
- * doesn't match any diagnostic command registered in the
- * targeted Java virtual machine.
- *
- * @since 7u4
- */
- public DiagnosticCommandInfo getDiagnosticCommandInfo(String command);
-
- /**
- * Returns a list of {@code DiagnosticCommandInfo} object describing
- * all diagnostic commands available on the targeted Java virtual machine
- *
- * @return a list of {@code DiagnosticCommandInfo} objects
- *
- * @since 7u4
- */
- public List<DiagnosticCommandInfo> getDiagnosticCommandInfo();
-
- /**
- * Returns a list of {@code DiagnosticCommandInfo} object describing
- * all diagnostic commands specified in the {@code commands} list.
- *
- * @param commands {@code List} of {@code String} containing diagnostic
- * command names
- * @return a {@code List} of {@code DiagnosticCommandInfo} objects
- *
- * @throws java.lang.IllegalArgumentException if at least one
- * command specified in the {@code commands } list
- * doesn't match any diagnostic command registered in the
- * targeted Java virtual machine.
- *
- * @since 7u4
- */
- public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(List<String> commands);
-
- /**
- * Executes the command line {@code commandLine}. The command line must
- * start with a diagnostic command name, optionally followed by parameters.
- * Each command has its own syntax but the generic syntax for a diagnostic
- * command line is:
- * <blockquote>
- * <command name> [<option>=<value>] [<argument_value>]
- * </blockquote>
- *
- * @param commandLine command line to execute
- * @return a {@code String} object containing the diagnostic command
- * output.
- *
- * @throws java.lang.IllegalArgumentException if the command line doesn't
- * match any diagnostic command registered in the virtual machine
- * of if the parameters don't match the diagnostic command syntax.
- * @throws java.lang.SecurityException
- * if a security manager exists and the caller does not have
- * ManagementPermission("control").
- *
- * @since 7u4
- */
- public String execute(String commandLine);
-
- /**
- * Invokes the diagnostic command named {@code cmd} with the parameters
- * specified in {@code args}. Each command has its own syntax but
- * the generic syntax for parameters is:
- * <blockquote>
- * [<option>=<value>] [<argument_value>]
- * </blockquote>
- *
- * @param cmd a diagnostic command name
- * @param args the command parameters
- * @return a {@code String} object containing the diagnostic command
- * output.
- *
- * @throws java.lang.IllegalArgumentException if the command line doesn't
- * match any diagnostic command registered in the virtual machine
- * of if the parameters don't match the diagnostic command syntax.
- * @throws java.lang.SecurityException
- * if a security manager exists and the caller does not have
- * ManagementPermission("control").
- *
- * @since 7u4
- */
- public String execute(String cmd, String... args);
}
--- a/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java Wed Jul 05 18:03:08 2017 +0200
@@ -94,7 +94,7 @@
if (streamNumber < 0 || streamNumber > 65536)
throw new IllegalArgumentException("Invalid stream number");
- return new sun.nio.ch.SctpMessageInfoImpl(null, address, streamNumber);
+ return new sun.nio.ch.sctp.MessageInfoImpl(null, address, streamNumber);
}
/**
* Creates a {@code MessageInfo} instance suitable for use when
@@ -133,8 +133,8 @@
if (streamNumber < 0 || streamNumber > 65536)
throw new IllegalArgumentException("Invalid stream number");
- return new sun.nio.ch.SctpMessageInfoImpl(association, address,
- streamNumber);
+ return new sun.nio.ch.sctp.MessageInfoImpl(association,
+ address, streamNumber);
}
/**
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java Wed Jul 05 18:03:08 2017 +0200
@@ -162,7 +162,7 @@
*/
public static SctpChannel open() throws
IOException {
- return new sun.nio.ch.SctpChannelImpl((SelectorProvider)null);
+ return new sun.nio.ch.sctp.SctpChannelImpl((SelectorProvider)null);
}
/**
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java Wed Jul 05 18:03:08 2017 +0200
@@ -162,7 +162,7 @@
*/
public static SctpMultiChannel open() throws
IOException {
- return new sun.nio.ch.SctpMultiChannelImpl((SelectorProvider)null);
+ return new sun.nio.ch.sctp.SctpMultiChannelImpl((SelectorProvider)null);
}
/**
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java Wed Jul 05 18:03:08 2017 +0200
@@ -98,7 +98,7 @@
*/
public static SctpServerChannel open() throws
IOException {
- return new sun.nio.ch.SctpServerChannelImpl((SelectorProvider)null);
+ return new sun.nio.ch.sctp.SctpServerChannelImpl((SelectorProvider)null);
}
/**
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpStandardSocketOptions.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpStandardSocketOptions.java Wed Jul 05 18:03:08 2017 +0200
@@ -25,7 +25,7 @@
package com.sun.nio.sctp;
import java.net.SocketAddress;
-import sun.nio.ch.SctpStdSocketOption;
+import sun.nio.ch.sctp.SctpStdSocketOption;
/**
* SCTP channels supports the socket options defined by this class
@@ -50,7 +50,7 @@
*/
public static final SctpSocketOption<Boolean> SCTP_DISABLE_FRAGMENTS = new
SctpStdSocketOption<Boolean>("SCTP_DISABLE_FRAGMENTS", Boolean.class,
- sun.nio.ch.SctpStdSocketOption.SCTP_DISABLE_FRAGMENTS);
+ sun.nio.ch.sctp.SctpStdSocketOption.SCTP_DISABLE_FRAGMENTS);
/**
* Enables or disables explicit message completion.
@@ -69,7 +69,7 @@
*/
public static final SctpSocketOption<Boolean> SCTP_EXPLICIT_COMPLETE = new
SctpStdSocketOption<Boolean>("SCTP_EXPLICIT_COMPLETE", Boolean.class,
- sun.nio.ch.SctpStdSocketOption.SCTP_EXPLICIT_COMPLETE);
+ sun.nio.ch.sctp.SctpStdSocketOption.SCTP_EXPLICIT_COMPLETE);
/**
* Fragmented interleave controls how the presentation of messages occur
@@ -120,7 +120,7 @@
public static final SctpSocketOption<Integer> SCTP_FRAGMENT_INTERLEAVE =
new SctpStdSocketOption<Integer>("SCTP_FRAGMENT_INTERLEAVE",
Integer.class,
- sun.nio.ch.SctpStdSocketOption.SCTP_FRAGMENT_INTERLEAVE);
+ sun.nio.ch.sctp.SctpStdSocketOption.SCTP_FRAGMENT_INTERLEAVE);
/**
* The maximum number of streams requested by the local endpoint during
@@ -171,7 +171,7 @@
*/
public static final SctpSocketOption<Boolean> SCTP_NODELAY =
new SctpStdSocketOption<Boolean>("SCTP_NODELAY", Boolean.class,
- sun.nio.ch.SctpStdSocketOption.SCTP_NODELAY);
+ sun.nio.ch.sctp.SctpStdSocketOption.SCTP_NODELAY);
/**
* Requests that the local SCTP stack use the given peer address as
@@ -246,7 +246,7 @@
*/
public static final SctpSocketOption<Integer> SO_SNDBUF =
new SctpStdSocketOption<Integer>("SO_SNDBUF", Integer.class,
- sun.nio.ch.SctpStdSocketOption.SO_SNDBUF);
+ sun.nio.ch.sctp.SctpStdSocketOption.SO_SNDBUF);
/**
* The size of the socket receive buffer.
@@ -273,7 +273,7 @@
*/
public static final SctpSocketOption<Integer> SO_RCVBUF =
new SctpStdSocketOption<Integer>("SO_RCVBUF", Integer.class,
- sun.nio.ch.SctpStdSocketOption.SO_RCVBUF);
+ sun.nio.ch.sctp.SctpStdSocketOption.SO_RCVBUF);
/**
* Linger on close if data is present.
@@ -304,7 +304,7 @@
*/
public static final SctpSocketOption<Integer> SO_LINGER =
new SctpStdSocketOption<Integer>("SO_LINGER", Integer.class,
- sun.nio.ch.SctpStdSocketOption.SO_LINGER);
+ sun.nio.ch.sctp.SctpStdSocketOption.SO_LINGER);
/**
* This class is used to set the maximum number of inbound/outbound streams
--- a/jdk/src/share/classes/java/awt/List.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/awt/List.java Wed Jul 05 18:03:08 2017 +0200
@@ -115,7 +115,7 @@
* @see #addItem(String)
* @see #getItem(int)
*/
- Vector items = new Vector();
+ Vector<String> items = new Vector<>();
/**
* This field will represent the number of visible rows in the
@@ -306,7 +306,7 @@
// to insure that it cannot be overridden by client subclasses.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
final String getItemImpl(int index) {
- return (String)items.elementAt(index);
+ return items.elementAt(index);
}
/**
@@ -415,7 +415,7 @@
if (peer != null) {
peer.removeAll();
}
- items = new Vector();
+ items = new Vector<>();
selected = new int[0];
}
@@ -490,9 +490,9 @@
public synchronized int[] getSelectedIndexes() {
ListPeer peer = (ListPeer)this.peer;
if (peer != null) {
- selected = ((ListPeer)peer).getSelectedIndexes();
+ selected = peer.getSelectedIndexes();
}
- return (int[])selected.clone();
+ return selected.clone();
}
/**
@@ -908,7 +908,7 @@
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
- return (ItemListener[])(getListeners(ItemListener.class));
+ return getListeners(ItemListener.class);
}
/**
@@ -975,7 +975,7 @@
* @since 1.4
*/
public synchronized ActionListener[] getActionListeners() {
- return (ActionListener[])(getListeners(ActionListener.class));
+ return getListeners(ActionListener.class);
}
/**
--- a/jdk/src/share/classes/java/awt/Window.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/awt/Window.java Wed Jul 05 18:03:08 2017 +0200
@@ -398,10 +398,10 @@
initIDs();
}
- String s = (String) java.security.AccessController.doPrivileged(
+ String s = java.security.AccessController.doPrivileged(
new GetPropertyAction("java.awt.syncLWRequests"));
systemSyncLWRequests = (s != null && s.equals("true"));
- s = (String) java.security.AccessController.doPrivileged(
+ s = java.security.AccessController.doPrivileged(
new GetPropertyAction("java.awt.Window.locationByPlatform"));
locationByPlatformProp = (s != null && s.equals("true"));
}
@@ -1378,7 +1378,7 @@
// make sure the privileged action is only
// for getting the property! We don't want the
// above checkTopLevelWindow call to always succeed!
- warningString = (String) AccessController.doPrivileged(
+ warningString = AccessController.doPrivileged(
new GetPropertyAction("awt.appletWarning",
"Java Applet Window"));
}
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java Wed Jul 05 18:03:08 2017 +0200
@@ -921,9 +921,9 @@
*/
private static ICC_Profile getStandardProfile(final String name) {
- return (ICC_Profile) AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<ICC_Profile>() {
+ public ICC_Profile run() {
ICC_Profile p = null;
try {
p = getInstance (name);
--- a/jdk/src/share/classes/java/awt/event/InputEvent.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/awt/event/InputEvent.java Wed Jul 05 18:03:08 2017 +0200
@@ -321,14 +321,15 @@
* @param when a long int that gives the time the event occurred.
* Passing negative or zero value
* is not recommended
- * @param modifiers the modifier keys down during event (e.g. shift, ctrl,
- * alt, meta)
- * Passing negative parameter is not recommended.
- * Zero value means no modifiers.
- * Either extended _DOWN_MASK or old _MASK modifiers
- * should be used, but both models should not be mixed
- * in one event. Use of the extended modifiers is
- * preferred
+ * @param modifiers a modifier mask describing the modifier keys and mouse
+ * buttons (for example, shift, ctrl, alt, and meta) that
+ * are down during the event.
+ * Only extended modifiers are allowed to be used as a
+ * value for this parameter (see the {@link InputEvent#getModifiersEx}
+ * class for the description of extended modifiers).
+ * Passing negative parameter
+ * is not recommended.
+ * Zero value means that no modifiers were passed
* @throws IllegalArgumentException if <code>source</code> is null
* @see #getSource()
* @see #getID()
@@ -416,9 +417,13 @@
/**
* Returns the extended modifier mask for this event.
+ * <P>
+ * Extended modifiers are the modifiers that ends with the _DOWN_MASK suffix,
+ * such as ALT_DOWN_MASK, BUTTON1_DOWN_MASK, and others.
+ * <P>
* Extended modifiers represent the state of all modal keys,
* such as ALT, CTRL, META, and the mouse buttons just after
- * the event occurred
+ * the event occurred.
* <P>
* For example, if the user presses <b>button 1</b> followed by
* <b>button 2</b>, and then releases them in the same order,
--- a/jdk/src/share/classes/java/awt/event/MouseEvent.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/awt/event/MouseEvent.java Wed Jul 05 18:03:08 2017 +0200
@@ -488,14 +488,15 @@
* @param when A long integer that gives the time the event occurred.
* Passing negative or zero value
* is not recommended
- * @param modifiers The modifier keys down during event (e.g. shift, ctrl,
- * alt, meta)
+ * @param modifiers a modifier mask describing the modifier keys and mouse
+ * buttons (for example, shift, ctrl, alt, and meta) that
+ * are down during the event.
+ * Only extended modifiers are allowed to be used as a
+ * value for this parameter (see the {@link InputEvent#getModifiersEx}
+ * class for the description of extended modifiers).
* Passing negative parameter
* is not recommended.
- * Zero value means that no modifiers were passed.
- * Use either an extended _DOWN_MASK or old _MASK modifiers,
- * however do not mix models in the one event.
- * The extended modifiers are preferred for using
+ * Zero value means that no modifiers were passed
* @param x The horizontal x coordinate for the mouse location.
* It is allowed to pass negative values
* @param y The vertical y coordinate for the mouse location.
@@ -586,14 +587,15 @@
* @param when A long integer that gives the time the event occurred.
* Passing negative or zero value
* is not recommended
- * @param modifiers The modifier keys down during event (e.g. shift, ctrl,
- * alt, meta)
+ * @param modifiers a modifier mask describing the modifier keys and mouse
+ * buttons (for example, shift, ctrl, alt, and meta) that
+ * are down during the event.
+ * Only extended modifiers are allowed to be used as a
+ * value for this parameter (see the {@link InputEvent#getModifiersEx}
+ * class for the description of extended modifiers).
* Passing negative parameter
* is not recommended.
- * Zero value means that no modifiers were passed.
- * Use either an extended _DOWN_MASK or old _MASK modifiers,
- * however do not mix models in the one event.
- * The extended modifiers are preferred for using
+ * Zero value means that no modifiers were passed
* @param x The horizontal x coordinate for the mouse location.
* It is allowed to pass negative values
* @param y The vertical y coordinate for the mouse location.
@@ -657,14 +659,15 @@
* @param when A long integer that gives the time the event occurred.
* Passing negative or zero value
* is not recommended
- * @param modifiers The modifier keys down during event (e.g. shift, ctrl,
- * alt, meta)
+ * @param modifiers a modifier mask describing the modifier keys and mouse
+ * buttons (for example, shift, ctrl, alt, and meta) that
+ * are down during the event.
+ * Only extended modifiers are allowed to be used as a
+ * value for this parameter (see the {@link InputEvent#getModifiersEx}
+ * class for the description of extended modifiers).
* Passing negative parameter
* is not recommended.
- * Zero value means that no modifiers were passed.
- * Use either an extended _DOWN_MASK or old _MASK modifiers,
- * however do not mix models in the one event.
- * The extended modifiers are preferred for using
+ * Zero value means that no modifiers were passed
* @param x The horizontal x coordinate for the mouse location.
* It is allowed to pass negative values
* @param y The vertical y coordinate for the mouse location.
--- a/jdk/src/share/classes/java/lang/management/ManagementPermission.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/lang/management/ManagementPermission.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -46,12 +46,17 @@
* <tr>
* <td>control</td>
* <td>Ability to control the runtime characteristics of the Java virtual
- * machine, for example, setting the -verbose:gc and -verbose:class flag,
- * setting the threshold of a memory pool, and enabling and disabling
- * the thread contention monitoring support.
+ * machine, for example, enabling and disabling the verbose output for
+ * the class loading or memory system, setting the threshold of a memory
+ * pool, and enabling and disabling the thread contention monitoring
+ * support. Some actions controlled by this permission can disclose
+ * information about the running application, like the -verbose:class
+ * flag.
* </td>
* <td>This allows an attacker to control the runtime characteristics
- * of the Java virtual machine and cause the system to misbehave.
+ * of the Java virtual machine and cause the system to misbehave. An
+ * attacker can also access some information related to the running
+ * application.
* </td>
* </tr>
* <tr>
--- a/jdk/src/share/classes/java/util/jar/Attributes.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/util/jar/Attributes.java Wed Jul 05 18:03:08 2017 +0200
@@ -71,7 +71,7 @@
* @param size the initial number of attributes
*/
public Attributes(int size) {
- map = new HashMap(size);
+ map = new HashMap<>(size);
}
/**
@@ -81,7 +81,7 @@
* @param attr the specified Attributes
*/
public Attributes(Attributes attr) {
- map = new HashMap(attr);
+ map = new HashMap<>(attr);
}
@@ -296,9 +296,9 @@
* XXX Need to handle UTF8 values and break up lines longer than 72 bytes
*/
void write(DataOutputStream os) throws IOException {
- Iterator it = entrySet().iterator();
+ Iterator<Map.Entry<Object, Object>> it = entrySet().iterator();
while (it.hasNext()) {
- Map.Entry e = (Map.Entry)it.next();
+ Map.Entry<Object, Object> e = it.next();
StringBuffer buffer = new StringBuffer(
((Name)e.getKey()).toString());
buffer.append(": ");
@@ -340,9 +340,9 @@
// write out all attributes except for the version
// we wrote out earlier
- Iterator it = entrySet().iterator();
+ Iterator<Map.Entry<Object, Object>> it = entrySet().iterator();
while (it.hasNext()) {
- Map.Entry e = (Map.Entry)it.next();
+ Map.Entry<Object, Object> e = it.next();
String name = ((Name)e.getKey()).toString();
if ((version != null) && ! (name.equalsIgnoreCase(vername))) {
@@ -499,7 +499,7 @@
*/
public boolean equals(Object o) {
if (o instanceof Name) {
- Comparator c = ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER;
+ Comparator<String> c = ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER;
return c.compare(name, ((Name)o).name) == 0;
} else {
return false;
--- a/jdk/src/share/classes/java/util/jar/JarOutputStream.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/util/jar/JarOutputStream.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -135,7 +135,7 @@
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static int get16(byte[] b, int off) {
- return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
+ return Byte.toUnsignedInt(b[off]) | ( Byte.toUnsignedInt(b[off+1]) << 8);
}
/*
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Wed Jul 05 18:03:08 2017 +0200
@@ -48,21 +48,21 @@
/* a table mapping names to code signers, for jar entries that have
had their actual hashes verified */
- private Hashtable verifiedSigners;
+ private Hashtable<String, CodeSigner[]> verifiedSigners;
/* a table mapping names to code signers, for jar entries that have
passed the .SF/.DSA/.EC -> MANIFEST check */
- private Hashtable sigFileSigners;
+ private Hashtable<String, CodeSigner[]> sigFileSigners;
/* a hash table to hold .SF bytes */
- private Hashtable sigFileData;
+ private Hashtable<String, byte[]> sigFileData;
/** "queue" of pending PKCS7 blocks that we couldn't parse
* until we parsed the .SF file */
- private ArrayList pendingBlocks;
+ private ArrayList<SignatureFileVerifier> pendingBlocks;
/* cache of CodeSigner objects */
- private ArrayList signerCache;
+ private ArrayList<CodeSigner[]> signerCache;
/* Are we parsing a block? */
private boolean parsingBlockOrSF = false;
@@ -94,10 +94,10 @@
public JarVerifier(byte rawBytes[]) {
manifestRawBytes = rawBytes;
- sigFileSigners = new Hashtable();
- verifiedSigners = new Hashtable();
- sigFileData = new Hashtable(11);
- pendingBlocks = new ArrayList();
+ sigFileSigners = new Hashtable<>();
+ verifiedSigners = new Hashtable<>();
+ sigFileData = new Hashtable<>(11);
+ pendingBlocks = new ArrayList<>();
baos = new ByteArrayOutputStream();
manifestDigests = new ArrayList<>();
}
@@ -248,10 +248,9 @@
sigFileData.put(key, bytes);
// check pending blocks, we can now process
// anyone waiting for this .SF file
- Iterator it = pendingBlocks.iterator();
+ Iterator<SignatureFileVerifier> it = pendingBlocks.iterator();
while (it.hasNext()) {
- SignatureFileVerifier sfv =
- (SignatureFileVerifier) it.next();
+ SignatureFileVerifier sfv = it.next();
if (sfv.needSignatureFile(key)) {
if (debug != null) {
debug.println(
@@ -270,7 +269,7 @@
String key = uname.substring(0, uname.lastIndexOf("."));
if (signerCache == null)
- signerCache = new ArrayList();
+ signerCache = new ArrayList<>();
if (manDig == null) {
synchronized(manifestRawBytes) {
@@ -287,7 +286,7 @@
if (sfv.needSignatureFileBytes()) {
// see if we have already parsed an external .SF file
- byte[] bytes = (byte[]) sigFileData.get(key);
+ byte[] bytes = sigFileData.get(key);
if (bytes == null) {
// put this block on queue for later processing
@@ -343,7 +342,7 @@
*/
public CodeSigner[] getCodeSigners(String name)
{
- return (CodeSigner[])verifiedSigners.get(name);
+ return verifiedSigners.get(name);
}
public CodeSigner[] getCodeSigners(JarFile jar, JarEntry entry)
@@ -376,15 +375,14 @@
CodeSigner[] signers) {
if (signers != null) {
- ArrayList certChains = new ArrayList();
+ ArrayList<java.security.cert.Certificate> certChains = new ArrayList<>();
for (int i = 0; i < signers.length; i++) {
certChains.addAll(
signers[i].getSignerCertPath().getCertificates());
}
// Convert into a Certificate[]
- return (java.security.cert.Certificate[])
- certChains.toArray(
+ return certChains.toArray(
new java.security.cert.Certificate[certChains.size()]);
}
return null;
@@ -418,8 +416,8 @@
// MANIFEST.MF is always treated as signed and verified,
// move its signers from sigFileSigners to verifiedSigners.
if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) {
- verifiedSigners.put(JarFile.MANIFEST_NAME,
- sigFileSigners.remove(JarFile.MANIFEST_NAME));
+ CodeSigner[] codeSigners = sigFileSigners.remove(JarFile.MANIFEST_NAME);
+ verifiedSigners.put(JarFile.MANIFEST_NAME, codeSigners);
}
}
@@ -493,10 +491,10 @@
// Extended JavaUtilJarAccess CodeSource API Support
- private Map urlToCodeSourceMap = new HashMap();
- private Map signerToCodeSource = new HashMap();
+ private Map<URL, Map<CodeSigner[], CodeSource>> urlToCodeSourceMap = new HashMap<>();
+ private Map<CodeSigner[], CodeSource> signerToCodeSource = new HashMap<>();
private URL lastURL;
- private Map lastURLMap;
+ private Map<CodeSigner[], CodeSource> lastURLMap;
/*
* Create a unique mapping from codeSigner cache entries to CodeSource.
@@ -504,19 +502,19 @@
* and shared JAR file although in practice there will be a single URL in use.
*/
private synchronized CodeSource mapSignersToCodeSource(URL url, CodeSigner[] signers) {
- Map map;
+ Map<CodeSigner[], CodeSource> map;
if (url == lastURL) {
map = lastURLMap;
} else {
- map = (Map) urlToCodeSourceMap.get(url);
+ map = urlToCodeSourceMap.get(url);
if (map == null) {
- map = new HashMap();
+ map = new HashMap<>();
urlToCodeSourceMap.put(url, map);
}
lastURLMap = map;
lastURL = url;
}
- CodeSource cs = (CodeSource) map.get(signers);
+ CodeSource cs = map.get(signers);
if (cs == null) {
cs = new VerifierCodeSource(csdomain, url, signers);
signerToCodeSource.put(signers, cs);
@@ -524,16 +522,16 @@
return cs;
}
- private CodeSource[] mapSignersToCodeSources(URL url, List signers, boolean unsigned) {
- List sources = new ArrayList();
+ private CodeSource[] mapSignersToCodeSources(URL url, List<CodeSigner[]> signers, boolean unsigned) {
+ List<CodeSource> sources = new ArrayList<>();
for (int i = 0; i < signers.size(); i++) {
- sources.add(mapSignersToCodeSource(url, (CodeSigner[]) signers.get(i)));
+ sources.add(mapSignersToCodeSource(url, signers.get(i)));
}
if (unsigned) {
sources.add(mapSignersToCodeSource(url, null));
}
- return (CodeSource[]) sources.toArray(new CodeSource[sources.size()]);
+ return sources.toArray(new CodeSource[sources.size()]);
}
private CodeSigner[] emptySigner = new CodeSigner[0];
@@ -553,7 +551,7 @@
* but this handles a CodeSource of any type, just in case.
*/
CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
- List sourceList = new ArrayList();
+ List<CodeSource> sourceList = new ArrayList<>();
for (int i = 0; i < sources.length; i++) {
sourceList.add(sources[i]);
}
@@ -574,6 +572,7 @@
* signing data that can be compared by object reference identity.
*/
private static class VerifierCodeSource extends CodeSource {
+ private static final long serialVersionUID = -9047366145967768825L;
URL vlocation;
CodeSigner[] vsigners;
@@ -641,16 +640,16 @@
return vcerts;
}
}
- private Map signerMap;
+ private Map<String, CodeSigner[]> signerMap;
- private synchronized Map signerMap() {
+ private synchronized Map<String, CodeSigner[]> signerMap() {
if (signerMap == null) {
/*
* Snapshot signer state so it doesn't change on us. We care
* only about the asserted signatures. Verification of
* signature validity happens via the JarEntry apis.
*/
- signerMap = new HashMap(verifiedSigners.size() + sigFileSigners.size());
+ signerMap = new HashMap<>(verifiedSigners.size() + sigFileSigners.size());
signerMap.putAll(verifiedSigners);
signerMap.putAll(sigFileSigners);
}
@@ -658,15 +657,15 @@
}
public synchronized Enumeration<String> entryNames(JarFile jar, final CodeSource[] cs) {
- final Map map = signerMap();
- final Iterator itor = map.entrySet().iterator();
+ final Map<String, CodeSigner[]> map = signerMap();
+ final Iterator<Map.Entry<String, CodeSigner[]>> itor = map.entrySet().iterator();
boolean matchUnsigned = false;
/*
* Grab a single copy of the CodeSigner arrays. Check
* to see if we can optimize CodeSigner equality test.
*/
- List req = new ArrayList(cs.length);
+ List<CodeSigner[]> req = new ArrayList<>(cs.length);
for (int i = 0; i < cs.length; i++) {
CodeSigner[] match = findMatchingSigners(cs[i]);
if (match != null) {
@@ -678,8 +677,8 @@
}
}
- final List signersReq = req;
- final Enumeration enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
+ final List<CodeSigner[]> signersReq = req;
+ final Enumeration<String> enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
return new Enumeration<String>() {
@@ -691,14 +690,14 @@
}
while (itor.hasNext()) {
- Map.Entry e = (Map.Entry) itor.next();
- if (signersReq.contains((CodeSigner[]) e.getValue())) {
- name = (String) e.getKey();
+ Map.Entry<String, CodeSigner[]> e = itor.next();
+ if (signersReq.contains(e.getValue())) {
+ name = e.getKey();
return true;
}
}
while (enum2.hasMoreElements()) {
- name = (String) enum2.nextElement();
+ name = enum2.nextElement();
return true;
}
return false;
@@ -719,13 +718,13 @@
* Like entries() but screens out internal JAR mechanism entries
* and includes signed entries with no ZIP data.
*/
- public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration e) {
- final Map map = new HashMap();
+ public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<? extends ZipEntry> e) {
+ final Map<String, CodeSigner[]> map = new HashMap<>();
map.putAll(signerMap());
- final Enumeration enum_ = e;
+ final Enumeration<? extends ZipEntry> enum_ = e;
return new Enumeration<JarEntry>() {
- Enumeration signers = null;
+ Enumeration<String> signers = null;
JarEntry entry;
public boolean hasMoreElements() {
@@ -733,7 +732,7 @@
return true;
}
while (enum_.hasMoreElements()) {
- ZipEntry ze = (ZipEntry) enum_.nextElement();
+ ZipEntry ze = enum_.nextElement();
if (JarVerifier.isSigningRelated(ze.getName())) {
continue;
}
@@ -744,7 +743,7 @@
signers = Collections.enumeration(map.keySet());
}
while (signers.hasMoreElements()) {
- String name = (String) signers.nextElement();
+ String name = signers.nextElement();
entry = jar.newEntry(new ZipEntry(name));
return true;
}
@@ -764,7 +763,7 @@
}
};
}
- private Enumeration emptyEnumeration = new Enumeration<String>() {
+ private Enumeration<String> emptyEnumeration = new Enumeration<String>() {
public boolean hasMoreElements() {
return false;
@@ -797,8 +796,8 @@
}
private Enumeration<String> unsignedEntryNames(JarFile jar) {
- final Map map = signerMap();
- final Enumeration entries = jar.entries();
+ final Map<String, CodeSigner[]> map = signerMap();
+ final Enumeration<JarEntry> entries = jar.entries();
return new Enumeration<String>() {
String name;
@@ -813,7 +812,7 @@
}
while (entries.hasMoreElements()) {
String value;
- ZipEntry e = (ZipEntry) entries.nextElement();
+ ZipEntry e = entries.nextElement();
value = e.getName();
if (e.isDirectory() || isSigningRelated(value)) {
continue;
@@ -836,14 +835,14 @@
}
};
}
- private List jarCodeSigners;
+ private List<CodeSigner[]> jarCodeSigners;
- private synchronized List getJarCodeSigners() {
+ private synchronized List<CodeSigner[]> getJarCodeSigners() {
CodeSigner[] signers;
if (jarCodeSigners == null) {
- HashSet set = new HashSet();
+ HashSet<CodeSigner[]> set = new HashSet<>();
set.addAll(signerMap().values());
- jarCodeSigners = new ArrayList();
+ jarCodeSigners = new ArrayList<>();
jarCodeSigners.addAll(set);
}
return jarCodeSigners;
@@ -858,7 +857,7 @@
public CodeSource getCodeSource(URL url, String name) {
CodeSigner[] signers;
- signers = (CodeSigner[]) signerMap().get(name);
+ signers = signerMap().get(name);
return mapSignersToCodeSource(url, signers);
}
--- a/jdk/src/share/classes/java/util/jar/Manifest.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/util/jar/Manifest.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -339,7 +339,7 @@
return -1;
}
}
- return buf[pos++] & 0xff;
+ return Byte.toUnsignedInt(buf[pos++]);
}
public int read(byte[] b, int off, int len) throws IOException {
--- a/jdk/src/share/classes/java/util/zip/InflaterInputStream.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/util/zip/InflaterInputStream.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -119,7 +119,7 @@
*/
public int read() throws IOException {
ensureOpen();
- return read(singleByteBuf, 0, 1) == -1 ? -1 : singleByteBuf[0] & 0xff;
+ return read(singleByteBuf, 0, 1) == -1 ? -1 : Byte.toUnsignedInt(singleByteBuf[0]);
}
/**
--- a/jdk/src/share/classes/java/util/zip/ZipInputStream.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/java/util/zip/ZipInputStream.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -435,7 +435,7 @@
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static final int get16(byte b[], int off) {
- return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
+ return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
}
/*
--- a/jdk/src/share/classes/javax/crypto/CipherSpi.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/crypto/CipherSpi.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -775,7 +775,7 @@
int outOfs = output.arrayOffset() + outPos;
byte[] inArray = new byte[getTempArraySize(inLen)];
int total = 0;
- while (inLen > 0) {
+ do {
int chunk = Math.min(inLen, inArray.length);
input.get(inArray, 0, chunk);
int n;
@@ -787,7 +787,7 @@
total += n;
outOfs += n;
inLen -= chunk;
- }
+ } while (inLen > 0);
output.position(outPos + total);
return total;
} else { // output is not backed by an accessible byte[]
@@ -804,7 +804,7 @@
int outSize = outArray.length;
int total = 0;
boolean resized = false;
- while (inLen > 0) {
+ do {
int chunk = Math.min(inLen, outSize);
if ((a1 == false) && (resized == false)) {
input.get(inArray, 0, chunk);
@@ -834,7 +834,7 @@
int newOut = engineGetOutputSize(chunk);
outArray = new byte[newOut];
}
- }
+ } while (inLen > 0);
input.position(inLimit);
return total;
}
--- a/jdk/src/share/classes/javax/net/ssl/ExtendedSSLSession.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/ExtendedSSLSession.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
* The signature algorithm name must be a standard Java Security
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
* See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification & Reference </a>
* for information about standard algorithm names.
* <p>
@@ -71,7 +71,7 @@
* The signature algorithm name must be a standard Java Security
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
* See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification & Reference </a>
* for information about standard algorithm names.
*
--- a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -242,7 +242,7 @@
*
* @param algorithm The standard string name of the endpoint
* identification algorithm (or null). See Appendix A in the <a href=
- * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification & Reference </a>
* for information about standard algorithm names.
*
--- a/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java Wed Jul 05 18:03:08 2017 +0200
@@ -180,8 +180,7 @@
if (severity == null) {
throw new NullPointerException("severity is null");
}
- return super.put((PrinterStateReason) reason,
- (Severity) severity);
+ return super.put(reason, severity);
}
/**
--- a/jdk/src/share/classes/javax/print/attribute/standard/ReferenceUriSchemesSupported.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/print/attribute/standard/ReferenceUriSchemesSupported.java Wed Jul 05 18:03:08 2017 +0200
@@ -141,7 +141,7 @@
* Returns the string table for class ReferenceUriSchemesSupported.
*/
protected String[] getStringTable() {
- return (String[])myStringTable.clone();
+ return myStringTable.clone();
}
/**
--- a/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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,10 +107,17 @@
* defined in RFC 1779 and RFC 2253
* (and listed in {@link #getName(String format) getName(String format)}),
* as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
- * GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose OIDs are
- * defined in RFC 3280 and its successor.
+ * GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
+ * Identifiers (OIDs) are defined in RFC 3280 and its successor.
* Any other attribute type must be specified as an OID.
*
+ * <p>This implementation enforces a more restrictive OID syntax than
+ * defined in RFC 1779 and 2253. It uses the more correct syntax defined in
+ * <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
+ * specifies that OIDs contain at least 2 digits:
+ *
+ * <p>{@code numericoid = number 1*( DOT number ) }
+ *
* @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
* @exception NullPointerException if the <code>name</code>
* is <code>null</code>
@@ -135,10 +142,17 @@
* keywords recognized by <code>X500Principal(String)</code>. Keywords
* MUST be specified in all upper-case, otherwise they will be ignored.
* Improperly specified keywords are ignored; however if a keyword in the
- * name maps to an improperly specified OID, an
+ * name maps to an improperly specified Object Identifier (OID), an
* <code>IllegalArgumentException</code> is thrown. It is permissible to
* have 2 different keywords that map to the same OID.
*
+ * <p>This implementation enforces a more restrictive OID syntax than
+ * defined in RFC 1779 and 2253. It uses the more correct syntax defined in
+ * <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
+ * specifies that OIDs contain at least 2 digits:
+ *
+ * <p>{@code numericoid = number 1*( DOT number ) }
+ *
* @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
* @param keywordMap an attribute type keyword map, where each key is a
* keyword String that maps to a corresponding object identifier in String
--- a/jdk/src/share/classes/javax/security/auth/x500/package.html Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/security/auth/x500/package.html Wed Jul 05 18:03:08 2017 +0200
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 2012, 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
@@ -30,17 +30,26 @@
<body bgcolor="white">
This package contains the classes that should be used to store
- X500 Principal and X500 Private Crendentials in a
+ X500 Principal and X500 Private Credentials in a
<i>Subject</i>.
-<!--
<h2>Package Specification</h2>
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
<ul>
- <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
+ <li><a href="http://www.ietf.org/rfc/rfc1779.txt">
+ RFC 1779: A String Representation of Distinguished Names</a></li>
+ <li><a href="http://www.ietf.org/rfc/rfc2253.txt">
+ RFC 2253: Lightweight Directory Access Protocol (v3):
+ UTF-8 String Representation of Distinguished Names</a></li>
+ <li><a href="http://www.ietf.org/rfc/rfc3280.txt">
+ RFC 3280: Internet X.509 Public Key Infrastructure
+ Certificate and Certificate Revocation List (CRL) Profile</a></li>
+ <li><a href="http://www.ietf.org/rfc/rfc4512.txt">
+ RFC 4512: Lightweight Directory Access Protocol (LDAP):
+ Directory Information Models</a></li>
</ul>
+<!--
<h2>Related Documentation</h2>
For overviews, tutorials, examples, guides, and tool documentation, please see:
--- a/jdk/src/share/classes/javax/swing/JOptionPane.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/swing/JOptionPane.java Wed Jul 05 18:03:08 2017 +0200
@@ -34,7 +34,6 @@
import java.awt.Frame;
import java.awt.Point;
import java.awt.HeadlessException;
-import java.awt.Toolkit;
import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -994,8 +993,7 @@
// if the user closed the window without selecting a button
// (newValue = null in that case). Otherwise, close the dialog.
if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
- (event.getPropertyName().equals(VALUE_PROPERTY) ||
- event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) &&
+ (event.getPropertyName().equals(VALUE_PROPERTY)) &&
event.getNewValue() != null &&
event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
dialog.setVisible(false);
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java Wed Jul 05 18:03:08 2017 +0200
@@ -1236,6 +1236,7 @@
int index = list.locationToIndex(e.getPoint());
optionPane.setInputValue(list.getModel().getElementAt(index));
+ optionPane.setValue(JOptionPane.OK_OPTION);
}
}
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java Wed Jul 05 18:03:08 2017 +0200
@@ -434,6 +434,8 @@
// Empty out the renderer pane, allowing renderers to be gc'ed.
rendererPane.removeAll();
+
+ paintContext = null;
}
private void configureRenderer(SynthContext context) {
--- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java Wed Jul 05 18:03:08 2017 +0200
@@ -156,7 +156,7 @@
protected Color borderSelectionColor;
private boolean isDropCell;
- private boolean fillBackground = true;
+ private boolean fillBackground;
/**
* Set to true after the constructor has run.
--- a/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2012, 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
@@ -185,6 +185,7 @@
theConsumer.setDimensions(image.getWidth(), image.getHeight());
theConsumer.setProperties(properties);
sendPixels();
+ theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
theConsumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
} catch (NullPointerException e) {
if (theConsumer != null) {
--- a/jdk/src/share/classes/sun/beans/infos/ComponentBeanInfo.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/beans/infos/ComponentBeanInfo.java Wed Jul 05 18:03:08 2017 +0200
@@ -32,7 +32,7 @@
*/
public class ComponentBeanInfo extends SimpleBeanInfo {
- private static final Class beanClass = java.awt.Component.class;
+ private static final Class<java.awt.Component> beanClass = java.awt.Component.class;
public PropertyDescriptor[] getPropertyDescriptors() {
try {
--- a/jdk/src/share/classes/sun/font/FileFont.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/font/FileFont.java Wed Jul 05 18:03:08 2017 +0200
@@ -163,7 +163,9 @@
}
}
}
- scaler.dispose();
+ if (scaler != null) {
+ scaler.dispose();
+ }
scaler = FontScaler.getNullScaler();
}
--- a/jdk/src/share/classes/sun/font/StandardGlyphVector.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/font/StandardGlyphVector.java Wed Jul 05 18:03:08 2017 +0200
@@ -1740,8 +1740,9 @@
tx,
sgv.font.getStyle(),
aa, fm);
-
- FontStrike strike = sgv.font2D.getStrike(desc); // !!! getStrike(desc, false)
+ // Get the strike via the handle. Shouldn't matter
+ // if we've invalidated the font but its an extra precaution.
+ FontStrike strike = sgv.font2D.handle.font2D.getStrike(desc); // !!! getStrike(desc, false)
return new GlyphStrike(sgv, strike, dx, dy);
}
--- a/jdk/src/share/classes/sun/font/SunFontManager.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/font/SunFontManager.java Wed Jul 05 18:03:08 2017 +0200
@@ -2619,6 +2619,9 @@
physicalFonts.remove(oldFont.fullName);
fullNameToFont.remove(oldFont.fullName.toLowerCase(Locale.ENGLISH));
FontFamily.remove(oldFont);
+ if (oldFont instanceof FileFont) {
+ ((FileFont)oldFont).deregisterFontAndClearStrikeCache();
+ }
if (localeFullNamesToFont != null) {
Map.Entry[] mapEntries =
--- a/jdk/src/share/classes/sun/font/TrueTypeFont.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/font/TrueTypeFont.java Wed Jul 05 18:03:08 2017 +0200
@@ -1037,6 +1037,9 @@
if (head_Table != null && head_Table.capacity() >= 18) {
ShortBuffer sb = head_Table.asShortBuffer();
upem = sb.get(9) & 0xffff;
+ if (upem < 16 || upem > 16384) {
+ upem = 2048;
+ }
}
ByteBuffer os2_Table = getTableBuffer(os_2Tag);
--- a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,13 +27,9 @@
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import javax.management.ObjectName;
-import com.sun.management.DiagnosticCommandInfo;
-import com.sun.management.DiagnosticCommandArgumentInfo;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
@@ -120,54 +116,7 @@
}
}
- public List<String> getDiagnosticCommands() {
- String[] commands = getDiagnosticCommands0();
- return commands == null ? Collections.<String>emptyList() :
- Arrays.asList(commands);
- }
-
- public DiagnosticCommandInfo getDiagnosticCommandInfo(String command) {
- String[] array = new String[] { command };
- return getDiagnosticCommandInfo0(array)[0];
- }
-
- public List<DiagnosticCommandInfo> getDiagnosticCommandInfo() {
- String[] commands = getDiagnosticCommands0();
- return Arrays.asList(getDiagnosticCommandInfo0(commands));
- }
-
- public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(
- List<String> commands) {
- return Arrays.asList(getDiagnosticCommandInfo0(
- commands.toArray(new String[commands.size()])));
- }
-
- public String execute(String command) {
- Util.checkControlAccess();
- return executeDiagnosticCommand0(command);
- }
-
- public String execute(String cmd, String... arguments) {
- if(cmd == null) {
- throw new NullPointerException("Missing command name");
- }
- StringBuilder sb = new StringBuilder();
- sb.append(cmd);
- sb.append(" ");
- for(String arg : arguments) {
- sb.append(arg);
- sb.append(" ");
- }
- return execute(sb.toString());
- }
-
public ObjectName getObjectName() {
return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
}
-
- private native String[] getDiagnosticCommands0();
- private native DiagnosticCommandInfo[] getDiagnosticCommandInfo0(
- String[] commands) throws IllegalArgumentException;
- private native String executeDiagnosticCommand0(String command)
- throws IllegalArgumentException;
}
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 05 18:03:08 2017 +0200
@@ -270,7 +270,7 @@
protected Proxy instProxy;
private CookieHandler cookieHandler;
- private ResponseCache cacheHandler;
+ private final ResponseCache cacheHandler;
// the cached response, and cached response headers and body
protected CacheResponse cachedResponse;
@@ -1579,7 +1579,7 @@
if (respCode == 200 || respCode == 203 || respCode == 206 ||
respCode == 300 || respCode == 301 || respCode == 410) {
- if (cacheHandler != null) {
+ if (cacheHandler != null && getUseCaches()) {
// give cache a chance to save response in cache
URI uri = ParseUtil.toURI(url);
if (uri != null) {
--- a/jdk/src/share/classes/sun/nio/ch/AbstractPollArrayWrapper.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/AbstractPollArrayWrapper.java Wed Jul 05 18:03:08 2017 +0200
@@ -35,15 +35,15 @@
* @since 1.4
*/
-abstract class AbstractPollArrayWrapper {
+public abstract class AbstractPollArrayWrapper {
// Event masks
- static final short POLLIN = 0x0001;
- static final short POLLOUT = 0x0004;
- static final short POLLERR = 0x0008;
- static final short POLLHUP = 0x0010;
- static final short POLLNVAL = 0x0020;
- static final short POLLREMOVE = 0x0800;
+ public static final short POLLIN = 0x0001;
+ public static final short POLLOUT = 0x0004;
+ public static final short POLLERR = 0x0008;
+ public static final short POLLHUP = 0x0010;
+ public static final short POLLNVAL = 0x0020;
+ public static final short POLLREMOVE = 0x0800;
// Miscellaneous constants
static final short SIZE_POLLFD = 8;
--- a/jdk/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -67,7 +67,7 @@
this.channelOffset = offset;
}
- void putEventOps(SelectionKeyImpl sk, int ops) {
+ public void putEventOps(SelectionKeyImpl sk, int ops) {
synchronized (closeLock) {
if (closed)
throw new ClosedSelectorException();
--- a/jdk/src/share/classes/sun/nio/ch/IOStatus.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/IOStatus.java Wed Jul 05 18:03:08 2017 +0200
@@ -28,16 +28,16 @@
// Constants for reporting I/O status
-final class IOStatus {
+public final class IOStatus {
private IOStatus() { }
- static final int EOF = -1; // End of file
- static final int UNAVAILABLE = -2; // Nothing available (non-blocking)
- static final int INTERRUPTED = -3; // System call interrupted
- static final int UNSUPPORTED = -4; // Operation not supported
- static final int THROWN = -5; // Exception thrown in JNI code
- static final int UNSUPPORTED_CASE = -6; // This case not supported
+ public static final int EOF = -1; // End of file
+ public static final int UNAVAILABLE = -2; // Nothing available (non-blocking)
+ public static final int INTERRUPTED = -3; // System call interrupted
+ public static final int UNSUPPORTED = -4; // Operation not supported
+ public static final int THROWN = -5; // Exception thrown in JNI code
+ public static final int UNSUPPORTED_CASE = -6; // This case not supported
// The following two methods are for use in try/finally blocks where a
// status value needs to be normalized before being returned to the invoker
@@ -55,28 +55,28 @@
// }
//
- static int normalize(int n) {
+ public static int normalize(int n) {
if (n == UNAVAILABLE)
return 0;
return n;
}
- static boolean check(int n) {
+ public static boolean check(int n) {
return (n >= UNAVAILABLE);
}
- static long normalize(long n) {
+ public static long normalize(long n) {
if (n == UNAVAILABLE)
return 0;
return n;
}
- static boolean check(long n) {
+ public static boolean check(long n) {
return (n >= UNAVAILABLE);
}
// Return true iff n is not one of the IOStatus values
- static boolean checkAll(long n) {
+ public static boolean checkAll(long n) {
return ((n > EOF) || (n < UNSUPPORTED_CASE));
}
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java Wed Jul 05 18:03:08 2017 +0200
@@ -34,7 +34,7 @@
* File-descriptor based I/O utilities that are shared by NIO classes.
*/
-class IOUtil {
+public class IOUtil {
private IOUtil() { } // No instantiation
@@ -309,7 +309,7 @@
}
}
- static FileDescriptor newFD(int i) {
+ public static FileDescriptor newFD(int i) {
FileDescriptor fd = new FileDescriptor();
setfdVal(fd, i);
return fd;
@@ -326,10 +326,11 @@
static native boolean drain(int fd) throws IOException;
- static native void configureBlocking(FileDescriptor fd, boolean blocking)
+ public static native void configureBlocking(FileDescriptor fd,
+ boolean blocking)
throws IOException;
- static native int fdVal(FileDescriptor fd);
+ public static native int fdVal(FileDescriptor fd);
static native void setfdVal(FileDescriptor fd, int value);
--- a/jdk/src/share/classes/sun/nio/ch/Net.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java Wed Jul 05 18:03:08 2017 +0200
@@ -33,7 +33,7 @@
import java.security.PrivilegedAction;
-class Net { // package-private
+public class Net {
private Net() { }
@@ -75,7 +75,7 @@
return canJoin6WithIPv4Group0();
}
- static InetSocketAddress checkAddress(SocketAddress sa) {
+ public static InetSocketAddress checkAddress(SocketAddress sa) {
if (sa == null)
throw new NullPointerException();
if (!(sa instanceof InetSocketAddress))
@@ -330,7 +330,7 @@
// Due to oddities SO_REUSEADDR on windows reuse is ignored
private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse);
- static void bind(FileDescriptor fd, InetAddress addr, int port)
+ public static void bind(FileDescriptor fd, InetAddress addr, int port)
throws IOException
{
bind(UNSPEC, fd, addr, port);
@@ -383,7 +383,7 @@
private static native InetAddress localInetAddress(FileDescriptor fd)
throws IOException;
- static InetSocketAddress localAddress(FileDescriptor fd)
+ public static InetSocketAddress localAddress(FileDescriptor fd)
throws IOException
{
return new InetSocketAddress(localInetAddress(fd), localPort(fd));
--- a/jdk/src/share/classes/sun/nio/ch/SctpMessageInfoImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.SocketAddress;
-import com.sun.nio.sctp.MessageInfo;
-import com.sun.nio.sctp.Association;
-
-/**
- * An implementation of a MessageInfo.
- */
-public class SctpMessageInfoImpl extends MessageInfo {
- private final SocketAddress address;
- private final int bytes; /* 0 */
-
- private Association association;
- private int assocId;
- private int streamNumber;
- private boolean complete = true;
- private boolean unordered; /* false */
- private long timeToLive; /* 0L */
- private int ppid; /* 0 */
-
- public SctpMessageInfoImpl(Association association,
- SocketAddress address,
- int streamNumber) {
- this.association = association;
- this.address = address;
- this.streamNumber = streamNumber;
- bytes = 0;
- }
-
- /* Invoked from native */
- private SctpMessageInfoImpl(int assocId,
- SocketAddress address,
- int bytes,
- int streamNumber,
- boolean complete,
- boolean unordered,
- int ppid) {
- this.assocId = assocId;
- this.address = address;
- this.bytes = bytes;
- this.streamNumber = streamNumber;
- this.complete = complete;
- this.unordered = unordered;
- this.ppid = ppid;
- }
-
- @Override
- public Association association() {
- return association;
- }
-
- /**
- * SctpMessageInfoImpl instances created from native will need to have their
- * association set from the channel.
- */
- void setAssociation(Association association) {
- this.association = association;
- }
-
- int associationID() {
- return assocId;
- }
-
- @Override
- public SocketAddress address() {
- return address;
- }
-
- @Override
- public int bytes() {
- return bytes;
- }
-
- @Override
- public int streamNumber() {
- return streamNumber;
- }
-
- @Override
- public MessageInfo streamNumber(int streamNumber) {
- if (streamNumber < 0 || streamNumber > 65536)
- throw new IllegalArgumentException("Invalid stream number");
-
- this.streamNumber = streamNumber;
- return this;
- }
-
- @Override
- public int payloadProtocolID() {
- return ppid;
- }
-
- @Override
- public MessageInfo payloadProtocolID(int ppid) {
- this.ppid = ppid;
- return this;
- }
-
- @Override
- public boolean isComplete() {
- return complete;
- }
-
- @Override
- public MessageInfo complete(boolean complete) {
- this.complete = complete;
- return this;
- }
-
- @Override
- public boolean isUnordered() {
- return unordered;
- }
-
- @Override
- public MessageInfo unordered(boolean unordered) {
- this.unordered = unordered;
- return this;
- }
-
- @Override
- public long timeToLive() {
- return timeToLive;
- }
-
- @Override
- public MessageInfo timeToLive(long millis) {
- timeToLive = millis;
- return this;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(super.toString());
- sb.append( "[Address: ").append(address)
- .append(", Association: ").append(association)
- .append(", Assoc ID: ").append(assocId)
- .append(", Bytes: ").append(bytes)
- .append(", Stream Number: ").append(streamNumber)
- .append(", Complete: ").append(complete)
- .append(", isUnordered: ").append(unordered)
- .append("]");
- return sb.toString();
- }
-}
--- a/jdk/src/share/classes/sun/nio/ch/SctpStdSocketOption.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import com.sun.nio.sctp.SctpSocketOption;
-
-public class SctpStdSocketOption<T>
- implements SctpSocketOption<T>
-{
- /* for native mapping of int options */
- public static final int SCTP_DISABLE_FRAGMENTS = 1;
- public static final int SCTP_EXPLICIT_COMPLETE = 2;
- public static final int SCTP_FRAGMENT_INTERLEAVE = 3;
- public static final int SCTP_NODELAY = 4;
- public static final int SO_SNDBUF = 5;
- public static final int SO_RCVBUF = 6;
- public static final int SO_LINGER = 7;
-
- private final String name;
- private final Class<T> type;
-
- /* for native mapping of int options */
- private int constValue;
-
- public SctpStdSocketOption(String name, Class<T> type) {
- this.name = name;
- this.type = type;
- }
-
- public SctpStdSocketOption(String name, Class<T> type, int constValue) {
- this.name = name;
- this.type = type;
- this.constValue = constValue;
- }
-
- @Override
- public String name() {
- return name;
- }
-
- @Override
- public Class<T> type() {
- return type;
- }
-
- @Override
- public String toString() {
- return name;
- }
-
- int constValue() {
- return constValue;
- }
-}
--- a/jdk/src/share/classes/sun/nio/ch/SelChImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/SelChImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -36,7 +36,7 @@
* @since 1.4
*/
-interface SelChImpl extends Channel {
+public interface SelChImpl extends Channel {
FileDescriptor getFD();
--- a/jdk/src/share/classes/sun/nio/ch/SelectionKeyImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/SelectionKeyImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -34,12 +34,12 @@
* An implementation of SelectionKey for Solaris.
*/
-class SelectionKeyImpl
+public class SelectionKeyImpl
extends AbstractSelectionKey
{
final SelChImpl channel; // package-private
- final SelectorImpl selector; // package-private
+ public final SelectorImpl selector;
// Index for a pollfd array in Selector that this key is registered with
private int index;
@@ -91,15 +91,15 @@
// The nio versions of these operations do not care if a key
// has been invalidated. They are for internal use by nio code.
- void nioReadyOps(int ops) { // package-private
+ public void nioReadyOps(int ops) {
readyOps = ops;
}
- int nioReadyOps() { // package-private
+ public int nioReadyOps() {
return readyOps;
}
- SelectionKey nioInterestOps(int ops) { // package-private
+ public SelectionKey nioInterestOps(int ops) {
if ((ops & ~channel().validOps()) != 0)
throw new IllegalArgumentException();
channel.translateAndSetInterestOps(ops, this);
@@ -107,7 +107,7 @@
return this;
}
- int nioInterestOps() { // package-private
+ public int nioInterestOps() {
return interestOps;
}
--- a/jdk/src/share/classes/sun/nio/ch/SelectorImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/SelectorImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -36,7 +36,7 @@
* Base Selector implementation class.
*/
-abstract class SelectorImpl
+public abstract class SelectorImpl
extends AbstractSelector
{
@@ -118,7 +118,7 @@
protected abstract void implClose() throws IOException;
- void putEventOps(SelectionKeyImpl sk, int ops) { }
+ public void putEventOps(SelectionKeyImpl sk, int ops) { }
protected final SelectionKey register(AbstractSelectableChannel ch,
int ops,
--- a/jdk/src/share/classes/sun/nio/ch/Util.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java Wed Jul 05 18:03:08 2017 +0200
@@ -40,7 +40,7 @@
import sun.security.action.GetPropertyAction;
-class Util {
+public class Util {
// -- Caches --
@@ -158,7 +158,7 @@
/**
* Returns a temporary buffer of at least the given size
*/
- static ByteBuffer getTemporaryDirectBuffer(int size) {
+ public static ByteBuffer getTemporaryDirectBuffer(int size) {
BufferCache cache = bufferCache.get();
ByteBuffer buf = cache.get(size);
if (buf != null) {
@@ -178,7 +178,7 @@
/**
* Releases a temporary buffer by returning to the cache or freeing it.
*/
- static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
+ public static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
offerFirstTemporaryDirectBuffer(buf);
}
@@ -467,7 +467,7 @@
private static boolean loaded = false;
- static void load() {
+ public static void load() {
synchronized (Util.class) {
if (loaded)
return;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/nio/ch/sctp/MessageInfoImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.Association;
+
+/**
+ * An implementation of a MessageInfo.
+ */
+public class MessageInfoImpl extends MessageInfo {
+ private final SocketAddress address;
+ private final int bytes; /* 0 */
+
+ private Association association;
+ private int assocId;
+ private int streamNumber;
+ private boolean complete = true;
+ private boolean unordered; /* false */
+ private long timeToLive; /* 0L */
+ private int ppid; /* 0 */
+
+ public MessageInfoImpl(Association association,
+ SocketAddress address,
+ int streamNumber) {
+ this.association = association;
+ this.address = address;
+ this.streamNumber = streamNumber;
+ bytes = 0;
+ }
+
+ /* Invoked from native */
+ private MessageInfoImpl(int assocId,
+ SocketAddress address,
+ int bytes,
+ int streamNumber,
+ boolean complete,
+ boolean unordered,
+ int ppid) {
+ this.assocId = assocId;
+ this.address = address;
+ this.bytes = bytes;
+ this.streamNumber = streamNumber;
+ this.complete = complete;
+ this.unordered = unordered;
+ this.ppid = ppid;
+ }
+
+ @Override
+ public Association association() {
+ return association;
+ }
+
+ /**
+ * MessageInfoImpl instances created from native will need to have their
+ * association set from the channel.
+ */
+ void setAssociation(Association association) {
+ this.association = association;
+ }
+
+ int associationID() {
+ return assocId;
+ }
+
+ @Override
+ public SocketAddress address() {
+ return address;
+ }
+
+ @Override
+ public int bytes() {
+ return bytes;
+ }
+
+ @Override
+ public int streamNumber() {
+ return streamNumber;
+ }
+
+ @Override
+ public MessageInfo streamNumber(int streamNumber) {
+ if (streamNumber < 0 || streamNumber > 65536)
+ throw new IllegalArgumentException("Invalid stream number");
+
+ this.streamNumber = streamNumber;
+ return this;
+ }
+
+ @Override
+ public int payloadProtocolID() {
+ return ppid;
+ }
+
+ @Override
+ public MessageInfo payloadProtocolID(int ppid) {
+ this.ppid = ppid;
+ return this;
+ }
+
+ @Override
+ public boolean isComplete() {
+ return complete;
+ }
+
+ @Override
+ public MessageInfo complete(boolean complete) {
+ this.complete = complete;
+ return this;
+ }
+
+ @Override
+ public boolean isUnordered() {
+ return unordered;
+ }
+
+ @Override
+ public MessageInfo unordered(boolean unordered) {
+ this.unordered = unordered;
+ return this;
+ }
+
+ @Override
+ public long timeToLive() {
+ return timeToLive;
+ }
+
+ @Override
+ public MessageInfo timeToLive(long millis) {
+ timeToLive = millis;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString());
+ sb.append( "[Address: ").append(address)
+ .append(", Association: ").append(association)
+ .append(", Assoc ID: ").append(assocId)
+ .append(", Bytes: ").append(bytes)
+ .append(", Stream Number: ").append(streamNumber)
+ .append(", Complete: ").append(complete)
+ .append(", isUnordered: ").append(unordered)
+ .append("]");
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/nio/ch/sctp/SctpStdSocketOption.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import com.sun.nio.sctp.SctpSocketOption;
+
+public class SctpStdSocketOption<T>
+ implements SctpSocketOption<T>
+{
+ /* for native mapping of int options */
+ public static final int SCTP_DISABLE_FRAGMENTS = 1;
+ public static final int SCTP_EXPLICIT_COMPLETE = 2;
+ public static final int SCTP_FRAGMENT_INTERLEAVE = 3;
+ public static final int SCTP_NODELAY = 4;
+ public static final int SO_SNDBUF = 5;
+ public static final int SO_RCVBUF = 6;
+ public static final int SO_LINGER = 7;
+
+ private final String name;
+ private final Class<T> type;
+
+ /* for native mapping of int options */
+ private int constValue;
+
+ public SctpStdSocketOption(String name, Class<T> type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public SctpStdSocketOption(String name, Class<T> type, int constValue) {
+ this.name = name;
+ this.type = type;
+ this.constValue = constValue;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public Class<T> type() {
+ return type;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ int constValue() {
+ return constValue;
+ }
+}
--- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -72,16 +72,19 @@
/*
* Random number generator for creating nonce values
+ * (Lazy initialization)
*/
- private static final SecureRandom RANDOM;
- static {
- SecureRandom tmp = null;
- try {
- tmp = SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- // should not happen
+ private static class SecureRandomHolder {
+ static final SecureRandom RANDOM;
+ static {
+ SecureRandom tmp = null;
+ try {
+ tmp = SecureRandom.getInstance("SHA1PRNG");
+ } catch (NoSuchAlgorithmException e) {
+ // should not happen
+ }
+ RANDOM = tmp;
}
- RANDOM = tmp;
}
/*
@@ -862,8 +865,8 @@
// Generate a nonce
BigInteger nonce = null;
- if (RANDOM != null) {
- nonce = new BigInteger(64, RANDOM);
+ if (SecureRandomHolder.RANDOM != null) {
+ nonce = new BigInteger(64, SecureRandomHolder.RANDOM);
tsQuery.setNonce(nonce);
}
tsQuery.requestCertificate(true);
--- a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Wed Jul 05 18:03:08 2017 +0200
@@ -253,11 +253,25 @@
}
try {
- // Use JCE
- SecretKey skey = getPBEKey(password);
- Cipher cipher = Cipher.getInstance(algOid.toString());
- cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
- byte[] privateKeyInfo = cipher.doFinal(encryptedKey);
+ byte[] privateKeyInfo;
+ while (true) {
+ try {
+ // Use JCE
+ SecretKey skey = getPBEKey(password);
+ Cipher cipher = Cipher.getInstance(algOid.toString());
+ cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
+ privateKeyInfo = cipher.doFinal(encryptedKey);
+ break;
+ } catch (Exception e) {
+ if (password.length == 0) {
+ // Retry using an empty password
+ // without a NULL terminator.
+ password = new char[1];
+ continue;
+ }
+ throw e;
+ }
+ }
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(privateKeyInfo);
@@ -1251,16 +1265,24 @@
ObjectIdentifier algOid = in.getOID();
AlgorithmParameters algParams = parseAlgParameters(in);
- try {
- // Use JCE
- SecretKey skey = getPBEKey(password);
- Cipher cipher = Cipher.getInstance(algOid.toString());
- cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
- safeContentsData = cipher.doFinal(safeContentsData);
-
- } catch (Exception e) {
- throw new IOException("failed to decrypt safe"
- + " contents entry: " + e, e);
+ while (true) {
+ try {
+ // Use JCE
+ SecretKey skey = getPBEKey(password);
+ Cipher cipher = Cipher.getInstance(algOid.toString());
+ cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
+ safeContentsData = cipher.doFinal(safeContentsData);
+ break;
+ } catch (Exception e) {
+ if (password.length == 0) {
+ // Retry using an empty password
+ // without a NULL terminator.
+ password = new char[1];
+ continue;
+ }
+ throw new IOException(
+ "failed to decrypt safe contents entry: " + e, e);
+ }
}
} else {
throw new IOException("public key protected PKCS12" +
--- a/jdk/src/share/classes/sun/tools/jar/CommandLine.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/CommandLine.java Wed Jul 05 18:03:08 2017 +0200
@@ -55,7 +55,7 @@
public static String[] parse(String[] args)
throws IOException
{
- ArrayList newArgs = new ArrayList(args.length);
+ List<String> newArgs = new ArrayList<>(args.length);
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.length() > 1 && arg.charAt(0) == '@') {
@@ -69,10 +69,10 @@
newArgs.add(arg);
}
}
- return (String[])newArgs.toArray(new String[newArgs.size()]);
+ return newArgs.toArray(new String[newArgs.size()]);
}
- private static void loadCmdFile(String name, List args)
+ private static void loadCmdFile(String name, List<String> args)
throws IOException
{
Reader r = new BufferedReader(new FileReader(name));
@@ -83,7 +83,7 @@
st.commentChar('#');
st.quoteChar('"');
st.quoteChar('\'');
- while (st.nextToken() != st.TT_EOF) {
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
args.add(st.sval);
}
r.close();
--- a/jdk/src/share/classes/sun/tools/jar/Manifest.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/Manifest.java Wed Jul 05 18:03:08 2017 +0200
@@ -47,10 +47,10 @@
/* list of headers that all pertain to a particular
* file in the archive
*/
- private Vector entries = new Vector();
+ private Vector<MessageHeader> entries = new Vector<>();
private byte[] tmpbuf = new byte[512];
/* a hashtable of entries, for fast lookup */
- private Hashtable tableEntries = new Hashtable();
+ private Hashtable<String, MessageHeader> tableEntries = new Hashtable<>();
static final String[] hashes = {"SHA"};
static final byte[] EOL = {(byte)'\r', (byte)'\n'};
@@ -115,14 +115,14 @@
}
public MessageHeader getEntry(String name) {
- return (MessageHeader) tableEntries.get(name);
+ return tableEntries.get(name);
}
public MessageHeader entryAt(int i) {
- return (MessageHeader) entries.elementAt(i);
+ return entries.elementAt(i);
}
- public Enumeration entries() {
+ public Enumeration<MessageHeader> entries() {
return entries.elements();
}
@@ -214,7 +214,7 @@
/* the first header in the file should be the global one.
* It should say "Manifest-Version: x.x"; if not add it
*/
- MessageHeader globals = (MessageHeader) entries.elementAt(0);
+ MessageHeader globals = entries.elementAt(0);
if (globals.findValue("Manifest-Version") == null) {
/* Assume this is a user-defined manifest. If it has a Name: <..>
@@ -238,7 +238,7 @@
globals.print(ps);
for (int i = 1; i < entries.size(); ++i) {
- MessageHeader mh = (MessageHeader) entries.elementAt(i);
+ MessageHeader mh = entries.elementAt(i);
mh.print(ps);
}
}
--- a/jdk/src/share/classes/sun/tools/jar/SignatureFile.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/SignatureFile.java Wed Jul 05 18:03:08 2017 +0200
@@ -47,7 +47,7 @@
*
* <p>Each entry section contains the name of an entry (which must
* have a counterpart in the manifest). Like the manifest it contains
- * a hash, the hash of the manifest section correspondind to the
+ * a hash, the hash of the manifest section corresponding to the
* name. Since the manifest entry contains the hash of the data, this
* is equivalent to a signature of the data, plus the attributes of
* the manifest entry.
@@ -66,7 +66,7 @@
/* list of headers that all pertain to a particular file in the
* archive */
- private Vector entries = new Vector();
+ private Vector<MessageHeader> entries = new Vector<>();
/* Right now we only support SHA hashes */
static final String[] hashes = {"SHA"};
@@ -98,7 +98,7 @@
* character in length. */
private SignatureFile(String name) throws JarException {
- entries = new Vector();
+ entries = new Vector<>();
if (name != null) {
if (name.length() > 8 || name.indexOf('.') != -1) {
@@ -142,9 +142,9 @@
this(name, true);
this.manifest = manifest;
- Enumeration enum_ = manifest.entries();
+ Enumeration<MessageHeader> enum_ = manifest.entries();
while (enum_.hasMoreElements()) {
- MessageHeader mh = (MessageHeader)enum_.nextElement();
+ MessageHeader mh = enum_.nextElement();
String entryName = mh.findValue("Name");
if (entryName != null) {
add(entryName);
@@ -269,9 +269,9 @@
*the entry does not exist.
*/
public MessageHeader getEntry(String name) {
- Enumeration enum_ = entries();
+ Enumeration<MessageHeader> enum_ = entries();
while(enum_.hasMoreElements()) {
- MessageHeader mh = (MessageHeader)enum_.nextElement();
+ MessageHeader mh = enum_.nextElement();
if (name.equals(mh.findValue("Name"))) {
return mh;
}
@@ -282,13 +282,13 @@
/**
* Returns the n-th entry. The global header is a entry 0. */
public MessageHeader entryAt(int n) {
- return (MessageHeader) entries.elementAt(n);
+ return entries.elementAt(n);
}
/**
* Returns an enumeration of the entries.
*/
- public Enumeration entries() {
+ public Enumeration<MessageHeader> entries() {
return entries.elements();
}
@@ -322,11 +322,11 @@
}
}
- private Hashtable digests = new Hashtable();
+ private Hashtable<String, MessageDigest> digests = new Hashtable<>();
private MessageDigest getDigest(String algorithm)
throws NoSuchAlgorithmException {
- MessageDigest dig = (MessageDigest)digests.get(algorithm);
+ MessageDigest dig = digests.get(algorithm);
if (dig == null) {
dig = MessageDigest.getInstance(algorithm);
digests.put(algorithm, dig);
@@ -344,7 +344,7 @@
/* the first header in the file should be the global one.
* It should say "SignatureFile-Version: x.x"; barf if not
*/
- MessageHeader globals = (MessageHeader) entries.elementAt(0);
+ MessageHeader globals = entries.elementAt(0);
if (globals.findValue("Signature-Version") == null) {
throw new JarException("Signature file requires " +
"Signature-Version: 1.0 in 1st header");
@@ -354,7 +354,7 @@
globals.print(ps);
for (int i = 1; i < entries.size(); ++i) {
- MessageHeader mh = (MessageHeader) entries.elementAt(i);
+ MessageHeader mh = entries.elementAt(i);
mh.print(ps);
}
}
--- a/jdk/src/share/demo/management/MemoryMonitor/MemoryMonitor.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/demo/management/MemoryMonitor/MemoryMonitor.java Wed Jul 05 18:03:08 2017 +0200
@@ -213,10 +213,10 @@
// Calculate remaining size
float ssH = ascent + descent;
- float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);
+ float remainingHeight = y2 - (ssH*2) - 0.5f;
float blockHeight = remainingHeight/10;
float blockWidth = 20.0f;
- float remainingWidth = (float) (x2 - blockWidth - 10);
+ float remainingWidth = x2 - blockWidth - 10;
// .. Memory Free ..
big.setColor(mfColor);
@@ -224,7 +224,7 @@
int i = 0;
for ( ; i < MemUsage ; i++) {
mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,
- blockWidth,(float) blockHeight-1);
+ blockWidth, blockHeight-1);
big.fill(mfRect);
}
@@ -232,13 +232,13 @@
big.setColor(Color.green);
for ( ; i < 10; i++) {
muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,
- blockWidth,(float) blockHeight-1);
+ blockWidth, blockHeight-1);
big.fill(muRect);
}
// .. Draw History Graph ..
if (remainingWidth <= 30) remainingWidth = (float)30;
- if (remainingHeight <= ssH) remainingHeight = (float)ssH;
+ if (remainingHeight <= ssH) remainingHeight = ssH;
big.setColor(graphColor);
int graphX = x1+30;
int graphY = y1 + (int) ssH;
@@ -347,8 +347,8 @@
big = bimg.createGraphics();
big.setFont(font);
FontMetrics fm = big.getFontMetrics(font);
- ascent = (int) fm.getAscent();
- descent = (int) fm.getDescent();
+ ascent = fm.getAscent();
+ descent = fm.getDescent();
}
repaint();
try {
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java Wed Jul 05 18:03:08 2017 +0200
@@ -185,11 +185,11 @@
*/
///////////////////////////////////////////////////////
static final int CH(byte[] b, int n) {
- return b[n] & 0xff;
+ return Byte.toUnsignedInt(b[n]);
}
static final int SH(byte[] b, int n) {
- return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
+ return Byte.toUnsignedInt(b[n]) | (Byte.toUnsignedInt(b[n + 1]) << 8);
}
static final long LG(byte[] b, int n) {
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Wed Jul 05 18:03:08 2017 +0200
@@ -61,7 +61,7 @@
private final ZipFileSystem zfs;
ZipFileStore(ZipPath zpath) {
- this.zfs = (ZipFileSystem)zpath.getFileSystem();
+ this.zfs = zpath.getFileSystem();
}
@Override
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Wed Jul 05 18:03:08 2017 +0200
@@ -1609,7 +1609,7 @@
synchronized (inflaters) {
int size = inflaters.size();
if (size > 0) {
- Inflater inf = (Inflater)inflaters.remove(size - 1);
+ Inflater inf = inflaters.remove(size - 1);
return inf;
} else {
return new Inflater(true);
@@ -1638,7 +1638,7 @@
synchronized (deflaters) {
int size = deflaters.size();
if (size > 0) {
- Deflater def = (Deflater)deflaters.remove(size - 1);
+ Deflater def = deflaters.remove(size - 1);
return def;
} else {
return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Wed Jul 05 18:03:08 2017 +0200
@@ -211,7 +211,7 @@
public <V extends FileAttributeView> V
getFileAttributeView(Path path, Class<V> type, LinkOption... options)
{
- return (V)ZipFileAttributeView.get(toZipPath(path), type);
+ return ZipFileAttributeView.get(toZipPath(path), type);
}
@Override
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipInfo.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipInfo.java Wed Jul 05 18:03:08 2017 +0200
@@ -78,12 +78,12 @@
// twice
long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
- zfs.zerror("read loc header failed");
+ ZipFileSystem.zerror("read loc header failed");
if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
// have to read the second time;
len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
- zfs.zerror("read loc header failed");
+ ZipFileSystem.zerror("read loc header failed");
}
printLOC(buf);
pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
--- a/jdk/src/share/native/sun/management/HotSpotDiagnostic.c Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/share/native/sun/management/HotSpotDiagnostic.c Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,141 +34,3 @@
{
jmm_interface->DumpHeap0(env, outputfile, live);
}
-
-JNIEXPORT jobjectArray JNICALL
-Java_sun_management_HotSpotDiagnostic_getDiagnosticCommands0
- (JNIEnv *env, jobject dummy)
-{
- if ((jmm_version > JMM_VERSION_1_2_1)
- || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=2))) {
- return jmm_interface->GetDiagnosticCommands(env);
- }
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "Diagnostic commands are not supported by this VM");
-}
-
-jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
- int num_arg) {
- int i;
- jobject obj;
- jobjectArray result;
- dcmdArgInfo* dcmd_arg_info_array;
- jclass dcmdArgInfoCls;
- jclass arraysCls;
- jmethodID mid;
- jobject resultList;
-
- dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
- if (dcmd_arg_info_array == NULL) {
- return NULL;
- }
- jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
- dcmd_arg_info_array);
- dcmdArgInfoCls = (*env)->FindClass(env,
- "com/sun/management/DiagnosticCommandArgumentInfo");
- result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
- if (result == NULL) {
- free(dcmd_arg_info_array);
- return NULL;
- }
- for (i=0; i<num_arg; i++) {
- obj = JNU_NewObjectByName(env,
- "com/sun/management/DiagnosticCommandArgumentInfo",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZI)V",
- (*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
- (*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
- (*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
- dcmd_arg_info_array[i].default_string == NULL ? NULL:
- (*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
- dcmd_arg_info_array[i].mandatory,
- dcmd_arg_info_array[i].option,
- dcmd_arg_info_array[i].position);
- if (obj == NULL) {
- free(dcmd_arg_info_array);
- return NULL;
- }
- (*env)->SetObjectArrayElement(env, result, i, obj);
- }
- free(dcmd_arg_info_array);
- arraysCls = (*env)->FindClass(env, "java/util/Arrays");
- mid = (*env)->GetStaticMethodID(env, arraysCls,
- "asList", "([Ljava/lang/Object;)Ljava/util/List;");
- resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
- return resultList;
-}
-
-/* Throws IllegalArgumentException if at least one the diagnostic command
- * passed in argument is not supported by the JVM
- */
-JNIEXPORT jobjectArray JNICALL
-Java_sun_management_HotSpotDiagnostic_getDiagnosticCommandInfo0
-(JNIEnv *env, jobject dummy, jobjectArray commands)
-{
- int i;
- jclass dcmdInfoCls;
- jobject result;
- jobjectArray args;
- jobject obj;
-
- if (commands == NULL) {
- JNU_ThrowNullPointerException(env, "Invalid String Array");
- return NULL;
- }
- if ((jmm_version > JMM_VERSION_1_2_1)
- || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=2))) {
- jsize num_commands = (*env)->GetArrayLength(env, commands);
- dcmdInfo* dcmd_info_array = (dcmdInfo*) malloc(num_commands *
- sizeof(dcmdInfo));
- if (dcmd_info_array == NULL) {
- JNU_ThrowOutOfMemoryError(env, NULL);
- }
- jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
- dcmdInfoCls = (*env)->FindClass(env,
- "com/sun/management/DiagnosticCommandInfo");
- result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
- if (result == NULL) {
- free(dcmd_info_array);
- JNU_ThrowOutOfMemoryError(env, 0);
- }
- for (i=0; i<num_commands; i++) {
- args = getDiagnosticCommandArgumentInfoArray(env,
- (*env)->GetObjectArrayElement(env,commands,i),
- dcmd_info_array[i].num_arguments);
- if (args == NULL) {
- free(dcmd_info_array);
- JNU_ThrowOutOfMemoryError(env, 0);
- }
- obj = JNU_NewObjectByName(env,
- "com/sun/management/DiagnosticCommandInfo",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
- (*env)->NewStringUTF(env,dcmd_info_array[i].name),
- (*env)->NewStringUTF(env,dcmd_info_array[i].description),
- (*env)->NewStringUTF(env,dcmd_info_array[i].impact),
- dcmd_info_array[i].enabled,
- args);
- if (obj == NULL) {
- free(dcmd_info_array);
- JNU_ThrowOutOfMemoryError(env, 0);
- }
- (*env)->SetObjectArrayElement(env, result, i, obj);
- }
- free(dcmd_info_array);
- return result;
- }
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "Diagnostic commands are not supported by this VM");
-}
-
-/* Throws IllegalArgumentException if the diagnostic command
- * passed in argument is not supported by the JVM
- */
-JNIEXPORT jstring JNICALL
-Java_sun_management_HotSpotDiagnostic_executeDiagnosticCommand0
-(JNIEnv *env, jobject dummy, jstring command) {
- if((jmm_version > JMM_VERSION_1_2_1 )
- || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=2))) {
- return jmm_interface->ExecuteDiagnosticCommand(env, command);
- }
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "Diagnostic commands are not supported by this VM");
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -180,7 +180,7 @@
((SelChImpl)selch).kill();
}
- void putEventOps(SelectionKeyImpl sk, int ops) {
+ public void putEventOps(SelectionKeyImpl sk, int ops) {
if (closed)
throw new ClosedSelectorException();
int fd = IOUtil.fdVal(sk.channel.getFD());
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -181,7 +181,7 @@
((SelChImpl)selch).kill();
}
- void putEventOps(SelectionKeyImpl sk, int ops) {
+ public void putEventOps(SelectionKeyImpl sk, int ops) {
if (closed)
throw new ClosedSelectorException();
pollWrapper.setInterest(sk.channel, ops);
--- a/jdk/src/solaris/classes/sun/nio/ch/NativeThread.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/solaris/classes/sun/nio/ch/NativeThread.java Wed Jul 05 18:03:08 2017 +0200
@@ -37,21 +37,21 @@
// always returns -1 and the signal(long) method has no effect.
-class NativeThread {
+public class NativeThread {
// Returns an opaque token representing the native thread underlying the
// invoking Java thread. On systems that do not require signalling, this
// method always returns -1.
//
- static native long current();
+ public static native long current();
// Signals the given native thread so as to release it from a blocking I/O
// operation. On systems that do not require signalling, this method has
// no effect.
//
- static native void signal(long nt);
+ public static native void signal(long nt);
- static native void init();
+ private static native void init();
static {
Util.load();
--- a/jdk/src/solaris/classes/sun/nio/ch/PollArrayWrapper.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/solaris/classes/sun/nio/ch/PollArrayWrapper.java Wed Jul 05 18:03:08 2017 +0200
@@ -41,9 +41,9 @@
* @since 1.4
*/
-class PollArrayWrapper extends AbstractPollArrayWrapper {
+public class PollArrayWrapper extends AbstractPollArrayWrapper {
- static final short POLLCONN = POLLOUT;
+ public static final short POLLCONN = POLLOUT;
// File descriptor to write for interrupt
int interruptFD;
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpAssocChange.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.AssociationChangeNotification;
-
-/**
- * An implementation of AssociationChangeNotification
- */
-public class SctpAssocChange extends AssociationChangeNotification
- implements SctpNotification
-{
- /* static final ints so that they can be referenced from native */
- private final static int SCTP_COMM_UP = 1;
- private final static int SCTP_COMM_LOST = 2;
- private final static int SCTP_RESTART = 3;
- private final static int SCTP_SHUTDOWN = 4;
- private final static int SCTP_CANT_START = 5;
-
- private Association association;
-
- /* assocId is used to lookup the association before the notification is
- * returned to user code */
- private int assocId;
- private AssocChangeEvent event;
- private int maxOutStreams;
- private int maxInStreams;
-
- /* Invoked from native */
- private SctpAssocChange(int assocId,
- int intEvent,
- int maxOutStreams,
- int maxInStreams) {
- switch (intEvent) {
- case SCTP_COMM_UP :
- this.event = AssocChangeEvent.COMM_UP;
- break;
- case SCTP_COMM_LOST :
- this.event = AssocChangeEvent.COMM_LOST;
- break;
- case SCTP_RESTART :
- this.event = AssocChangeEvent.RESTART;
- break;
- case SCTP_SHUTDOWN :
- this.event = AssocChangeEvent.SHUTDOWN;
- break;
- case SCTP_CANT_START :
- this.event = AssocChangeEvent.CANT_START;
- break;
- default :
- throw new AssertionError(
- "Unknown Association Change Event type: " + intEvent);
- }
-
- this.assocId = assocId;
- this.maxOutStreams = maxOutStreams;
- this.maxInStreams = maxInStreams;
- }
-
- @Override
- public int assocId() {
- return assocId;
- }
-
- @Override
- public void setAssociation(Association association) {
- this.association = association;
- }
-
- @Override
- public Association association() {
- assert association != null;
- return association;
- }
-
- @Override
- public AssocChangeEvent event() {
- return event;
- }
-
- int maxOutStreams() {
- return maxOutStreams;
- }
-
- int maxInStreams() {
- return maxInStreams;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(super.toString()).append(" [");
- sb.append("Association:").append(association);
- sb.append(", Event: ").append(event).append("]");
- return sb.toString();
- }
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpAssociationImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import com.sun.nio.sctp.Association;
-
-/**
- * An implementation of Association
- */
-public class SctpAssociationImpl extends Association {
- public SctpAssociationImpl(int associationID,
- int maxInStreams,
- int maxOutStreams) {
- super(associationID, maxInStreams, maxOutStreams);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer(super.toString());
- return sb.append("[associationID:")
- .append(associationID())
- .append(", maxIn:")
- .append(maxInboundStreams())
- .append(", maxOut:")
- .append(maxOutboundStreams())
- .append("]")
- .toString();
- }
-}
-
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1097 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.InetSocketAddress;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Set;
-import java.util.HashSet;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.ConnectionPendingException;
-import java.nio.channels.NoConnectionPendingException;
-import java.nio.channels.AlreadyConnectedException;
-import java.nio.channels.NotYetBoundException;
-import java.nio.channels.NotYetConnectedException;
-import java.nio.channels.spi.SelectorProvider;
-import com.sun.nio.sctp.AbstractNotificationHandler;
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.AssociationChangeNotification;
-import com.sun.nio.sctp.HandlerResult;
-import com.sun.nio.sctp.IllegalReceiveException;
-import com.sun.nio.sctp.InvalidStreamException;
-import com.sun.nio.sctp.IllegalUnbindException;
-import com.sun.nio.sctp.MessageInfo;
-import com.sun.nio.sctp.NotificationHandler;
-import com.sun.nio.sctp.SctpChannel;
-import com.sun.nio.sctp.SctpSocketOption;
-import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
-import static sun.nio.ch.SctpResultContainer.SEND_FAILED;
-import static sun.nio.ch.SctpResultContainer.ASSOCIATION_CHANGED;
-import static sun.nio.ch.SctpResultContainer.PEER_ADDRESS_CHANGED;
-import static sun.nio.ch.SctpResultContainer.SHUTDOWN;
-
-/**
- * An implementation of an SctpChannel
- */
-public class SctpChannelImpl extends SctpChannel
- implements SelChImpl
-{
- private final FileDescriptor fd;
-
- private final int fdVal;
-
- /* IDs of native threads doing send and receivess, for signalling */
- private volatile long receiverThread = 0;
- private volatile long senderThread = 0;
-
- /* Lock held by current receiving or connecting thread */
- private final Object receiveLock = new Object();
-
- /* Lock held by current sending or connecting thread */
- private final Object sendLock = new Object();
-
- private final ThreadLocal<Boolean> receiveInvoked =
- new ThreadLocal<Boolean>() {
- @Override protected Boolean initialValue() {
- return Boolean.FALSE;
- }
- };
-
- /* Lock held by any thread that modifies the state fields declared below
- DO NOT invoke a blocking I/O operation while holding this lock! */
- private final Object stateLock = new Object();
-
- private enum ChannelState {
- UNINITIALIZED,
- UNCONNECTED,
- PENDING,
- CONNECTED,
- KILLPENDING,
- KILLED,
- }
- /* -- The following fields are protected by stateLock -- */
- private ChannelState state = ChannelState.UNINITIALIZED;
-
- /* Binding; Once bound the port will remain constant. */
- int port = -1;
- private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
- /* Has the channel been bound to the wildcard address */
- private boolean wildcard; /* false */
- //private InetSocketAddress remoteAddress = null;
-
- /* Input/Output open */
- private boolean readyToConnect;
-
- /* Shutdown */
- private boolean isShutdown;
-
- private Association association;
-
- private Set<SocketAddress> remoteAddresses = Collections.emptySet();
-
- /* -- End of fields protected by stateLock -- */
-
- /**
- * Constructor for normal connecting sockets
- */
- public SctpChannelImpl(SelectorProvider provider) throws IOException {
- //TODO: update provider remove public modifier
- super(provider);
- this.fd = SctpNet.socket(true);
- this.fdVal = IOUtil.fdVal(fd);
- this.state = ChannelState.UNCONNECTED;
- }
-
- /**
- * Constructor for sockets obtained from server sockets
- */
- public SctpChannelImpl(SelectorProvider provider, FileDescriptor fd)
- throws IOException {
- this(provider, fd, null);
- }
-
- /**
- * Constructor for sockets obtained from branching
- */
- public SctpChannelImpl(SelectorProvider provider,
- FileDescriptor fd,
- Association association)
- throws IOException {
- super(provider);
- this.fd = fd;
- this.fdVal = IOUtil.fdVal(fd);
- this.state = ChannelState.CONNECTED;
- port = (Net.localAddress(fd)).getPort();
-
- if (association != null) { /* branched */
- this.association = association;
- } else { /* obtained from server channel */
- /* Receive COMM_UP */
- ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
- try {
- receive(buf, null, null, true);
- } finally {
- Util.releaseTemporaryDirectBuffer(buf);
- }
- }
- }
-
- /**
- * Binds the channel's socket to a local address.
- */
- @Override
- public SctpChannel bind(SocketAddress local) throws IOException {
- synchronized (receiveLock) {
- synchronized (sendLock) {
- synchronized (stateLock) {
- ensureOpenAndUnconnected();
- if (isBound())
- SctpNet.throwAlreadyBoundException();
- InetSocketAddress isa = (local == null) ?
- new InetSocketAddress(0) : Net.checkAddress(local);
- Net.bind(fd, isa.getAddress(), isa.getPort());
- InetSocketAddress boundIsa = Net.localAddress(fd);
- port = boundIsa.getPort();
- localAddresses.add(isa);
- if (isa.getAddress().isAnyLocalAddress())
- wildcard = true;
- }
- }
- }
- return this;
- }
-
- @Override
- public SctpChannel bindAddress(InetAddress address)
- throws IOException {
- bindUnbindAddress(address, true);
- localAddresses.add(new InetSocketAddress(address, port));
- return this;
- }
-
- @Override
- public SctpChannel unbindAddress(InetAddress address)
- throws IOException {
- bindUnbindAddress(address, false);
- localAddresses.remove(new InetSocketAddress(address, port));
- return this;
- }
-
- private SctpChannel bindUnbindAddress(InetAddress address, boolean add)
- throws IOException {
- if (address == null)
- throw new IllegalArgumentException();
-
- synchronized (receiveLock) {
- synchronized (sendLock) {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- throw new NotYetBoundException();
- if (wildcard)
- throw new IllegalStateException(
- "Cannot add or remove addresses from a channel that is bound to the wildcard address");
- if (address.isAnyLocalAddress())
- throw new IllegalArgumentException(
- "Cannot add or remove the wildcard address");
- if (add) {
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- SctpNet.throwAlreadyBoundException();
- }
- }
- } else { /*removing */
- /* Verify that there is more than one address
- * and that address is already bound */
- if (localAddresses.size() <= 1)
- throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
- boolean foundAddress = false;
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- foundAddress = true;
- break;
- }
- }
- if (!foundAddress )
- throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
- }
-
- SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
-
- /* Update our internal Set to reflect the addition/removal */
- if (add)
- localAddresses.add(new InetSocketAddress(address, port));
- else {
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- localAddresses.remove(addr);
- break;
- }
- }
- }
- }
- }
- }
- return this;
- }
-
- private boolean isBound() {
- synchronized (stateLock) {
- return port == -1 ? false : true;
- }
- }
-
- private boolean isConnected() {
- synchronized (stateLock) {
- return (state == ChannelState.CONNECTED);
- }
- }
-
- private void ensureOpenAndUnconnected() throws IOException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (isConnected())
- throw new AlreadyConnectedException();
- if (state == ChannelState.PENDING)
- throw new ConnectionPendingException();
- }
- }
-
- private boolean ensureReceiveOpen() throws ClosedChannelException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isConnected())
- throw new NotYetConnectedException();
- else
- return true;
- }
- }
-
- private void ensureSendOpen() throws ClosedChannelException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (isShutdown)
- throw new ClosedChannelException();
- if (!isConnected())
- throw new NotYetConnectedException();
- }
- }
-
- private void receiverCleanup() throws IOException {
- synchronized (stateLock) {
- receiverThread = 0;
- if (state == ChannelState.KILLPENDING)
- kill();
- }
- }
-
- private void senderCleanup() throws IOException {
- synchronized (stateLock) {
- senderThread = 0;
- if (state == ChannelState.KILLPENDING)
- kill();
- }
- }
-
- @Override
- public Association association() throws ClosedChannelException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isConnected())
- return null;
-
- return association;
- }
- }
-
- @Override
- public boolean connect(SocketAddress endpoint) throws IOException {
- synchronized (receiveLock) {
- synchronized (sendLock) {
- ensureOpenAndUnconnected();
- InetSocketAddress isa = Net.checkAddress(endpoint);
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkConnect(isa.getAddress().getHostAddress(),
- isa.getPort());
- synchronized (blockingLock()) {
- int n = 0;
- try {
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen()) {
- return false;
- }
- receiverThread = NativeThread.current();
- }
- for (;;) {
- InetAddress ia = isa.getAddress();
- if (ia.isAnyLocalAddress())
- ia = InetAddress.getLocalHost();
- n = SctpNet.connect(fdVal, ia, isa.getPort());
- if ( (n == IOStatus.INTERRUPTED)
- && isOpen())
- continue;
- break;
- }
- } finally {
- receiverCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- } catch (IOException x) {
- /* If an exception was thrown, close the channel after
- * invoking end() so as to avoid bogus
- * AsynchronousCloseExceptions */
- close();
- throw x;
- }
-
- if (n > 0) {
- synchronized (stateLock) {
- /* Connection succeeded */
- state = ChannelState.CONNECTED;
- if (!isBound()) {
- InetSocketAddress boundIsa =
- Net.localAddress(fd);
- port = boundIsa.getPort();
- }
-
- /* Receive COMM_UP */
- ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
- try {
- receive(buf, null, null, true);
- } finally {
- Util.releaseTemporaryDirectBuffer(buf);
- }
-
- /* cache remote addresses */
- try {
- remoteAddresses = getRemoteAddresses();
- } catch (IOException unused) { /* swallow exception */ }
-
- return true;
- }
- } else {
- synchronized (stateLock) {
- /* If nonblocking and no exception then connection
- * pending; disallow another invocation */
- if (!isBlocking())
- state = ChannelState.PENDING;
- else
- assert false;
- }
- }
- }
- return false;
- }
- }
- }
-
- @Override
- public boolean connect(SocketAddress endpoint,
- int maxOutStreams,
- int maxInStreams)
- throws IOException {
- ensureOpenAndUnconnected();
- return setOption(SCTP_INIT_MAXSTREAMS, InitMaxStreams.
- create(maxInStreams, maxOutStreams)).connect(endpoint);
-
- }
-
- @Override
- public boolean isConnectionPending() {
- synchronized (stateLock) {
- return (state == ChannelState.PENDING);
- }
- }
-
- @Override
- public boolean finishConnect() throws IOException {
- synchronized (receiveLock) {
- synchronized (sendLock) {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (isConnected())
- return true;
- if (state != ChannelState.PENDING)
- throw new NoConnectionPendingException();
- }
- int n = 0;
- try {
- try {
- begin();
- synchronized (blockingLock()) {
- synchronized (stateLock) {
- if (!isOpen()) {
- return false;
- }
- receiverThread = NativeThread.current();
- }
- if (!isBlocking()) {
- for (;;) {
- n = checkConnect(fd, false, readyToConnect);
- if ( (n == IOStatus.INTERRUPTED)
- && isOpen())
- continue;
- break;
- }
- } else {
- for (;;) {
- n = checkConnect(fd, true, readyToConnect);
- if (n == 0) {
- // Loop in case of
- // spurious notifications
- continue;
- }
- if ( (n == IOStatus.INTERRUPTED)
- && isOpen())
- continue;
- break;
- }
- }
- }
- } finally {
- synchronized (stateLock) {
- receiverThread = 0;
- if (state == ChannelState.KILLPENDING) {
- kill();
- /* poll()/getsockopt() does not report
- * error (throws exception, with n = 0)
- * on Linux platform after dup2 and
- * signal-wakeup. Force n to 0 so the
- * end() can throw appropriate exception */
- n = 0;
- }
- }
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- } catch (IOException x) {
- /* If an exception was thrown, close the channel after
- * invoking end() so as to avoid bogus
- * AsynchronousCloseExceptions */
- close();
- throw x;
- }
-
- if (n > 0) {
- synchronized (stateLock) {
- state = ChannelState.CONNECTED;
- if (!isBound()) {
- InetSocketAddress boundIsa =
- Net.localAddress(fd);
- port = boundIsa.getPort();
- }
-
- /* Receive COMM_UP */
- ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
- try {
- receive(buf, null, null, true);
- } finally {
- Util.releaseTemporaryDirectBuffer(buf);
- }
-
- /* cache remote addresses */
- try {
- remoteAddresses = getRemoteAddresses();
- } catch (IOException unused) { /* swallow exception */ }
-
- return true;
- }
- }
- }
- }
- return false;
- }
-
- @Override
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
- @Override
- public void implCloseSelectableChannel() throws IOException {
- synchronized (stateLock) {
- SctpNet.preClose(fdVal);
-
- if (receiverThread != 0)
- NativeThread.signal(receiverThread);
-
- if (senderThread != 0)
- NativeThread.signal(senderThread);
-
- if (!isRegistered())
- kill();
- }
- }
-
- @Override
- public FileDescriptor getFD() {
- return fd;
- }
-
- @Override
- public int getFDVal() {
- return fdVal;
- }
-
- /**
- * Translates native poll revent ops into a ready operation ops
- */
- private boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps();
- int oldOps = sk.nioReadyOps();
- int newOps = initialOps;
-
- if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
- /* This should only happen if this channel is pre-closed while a
- * selection operation is in progress
- * ## Throw an error if this channel has not been pre-closed */
- return false;
- }
-
- if ((ops & (PollArrayWrapper.POLLERR
- | PollArrayWrapper.POLLHUP)) != 0) {
- newOps = intOps;
- sk.nioReadyOps(newOps);
- /* No need to poll again in checkConnect,
- * the error will be detected there */
- readyToConnect = true;
- return (newOps & ~oldOps) != 0;
- }
-
- if (((ops & PollArrayWrapper.POLLIN) != 0) &&
- ((intOps & SelectionKey.OP_READ) != 0) &&
- isConnected())
- newOps |= SelectionKey.OP_READ;
-
- if (((ops & PollArrayWrapper.POLLCONN) != 0) &&
- ((intOps & SelectionKey.OP_CONNECT) != 0) &&
- ((state == ChannelState.UNCONNECTED) || (state == ChannelState.PENDING))) {
- newOps |= SelectionKey.OP_CONNECT;
- readyToConnect = true;
- }
-
- if (((ops & PollArrayWrapper.POLLOUT) != 0) &&
- ((intOps & SelectionKey.OP_WRITE) != 0) &&
- isConnected())
- newOps |= SelectionKey.OP_WRITE;
-
- sk.nioReadyOps(newOps);
- return (newOps & ~oldOps) != 0;
- }
-
- @Override
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
- }
-
- @Override
- @SuppressWarnings("all")
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
- }
-
- @Override
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
- int newOps = 0;
- if ((ops & SelectionKey.OP_READ) != 0)
- newOps |= PollArrayWrapper.POLLIN;
- if ((ops & SelectionKey.OP_WRITE) != 0)
- newOps |= PollArrayWrapper.POLLOUT;
- if ((ops & SelectionKey.OP_CONNECT) != 0)
- newOps |= PollArrayWrapper.POLLCONN;
- sk.selector.putEventOps(sk, newOps);
- }
-
- @Override
- public void kill() throws IOException {
- synchronized (stateLock) {
- if (state == ChannelState.KILLED)
- return;
- if (state == ChannelState.UNINITIALIZED) {
- state = ChannelState.KILLED;
- return;
- }
- assert !isOpen() && !isRegistered();
-
- /* Postpone the kill if there is a waiting reader
- * or writer thread. */
- if (receiverThread == 0 && senderThread == 0) {
- SctpNet.close(fdVal);
- state = ChannelState.KILLED;
- } else {
- state = ChannelState.KILLPENDING;
- }
- }
- }
-
- @Override
- public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
- throws IOException {
- if (name == null)
- throw new NullPointerException();
- if (!supportedOptions().contains(name))
- throw new UnsupportedOperationException("'" + name + "' not supported");
-
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
-
- SctpNet.setSocketOption(fdVal, name, value, 0 /*oneToOne*/);
- }
- return this;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T> T getOption(SctpSocketOption<T> name) throws IOException {
- if (name == null)
- throw new NullPointerException();
- if (!supportedOptions().contains(name))
- throw new UnsupportedOperationException("'" + name + "' not supported");
-
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
-
- return (T)SctpNet.getSocketOption(fdVal, name, 0 /*oneToOne*/);
- }
- }
-
- private static class DefaultOptionsHolder {
- static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
-
- private static Set<SctpSocketOption<?>> defaultOptions() {
- HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(10);
- set.add(SCTP_DISABLE_FRAGMENTS);
- set.add(SCTP_EXPLICIT_COMPLETE);
- set.add(SCTP_FRAGMENT_INTERLEAVE);
- set.add(SCTP_INIT_MAXSTREAMS);
- set.add(SCTP_NODELAY);
- set.add(SCTP_PRIMARY_ADDR);
- set.add(SCTP_SET_PEER_PRIMARY_ADDR);
- set.add(SO_SNDBUF);
- set.add(SO_RCVBUF);
- set.add(SO_LINGER);
- return Collections.unmodifiableSet(set);
- }
- }
-
- @Override
- public final Set<SctpSocketOption<?>> supportedOptions() {
- return DefaultOptionsHolder.defaultOptions;
- }
-
- @Override
- public <T> MessageInfo receive(ByteBuffer buffer,
- T attachment,
- NotificationHandler<T> handler)
- throws IOException {
- return receive(buffer, attachment, handler, false);
- }
-
- private <T> MessageInfo receive(ByteBuffer buffer,
- T attachment,
- NotificationHandler<T> handler,
- boolean fromConnect)
- throws IOException {
- if (buffer == null)
- throw new IllegalArgumentException("buffer cannot be null");
-
- if (buffer.isReadOnly())
- throw new IllegalArgumentException("Read-only buffer");
-
- if (receiveInvoked.get())
- throw new IllegalReceiveException(
- "cannot invoke receive from handler");
- receiveInvoked.set(Boolean.TRUE);
-
- try {
- SctpResultContainer resultContainer = new SctpResultContainer();
- do {
- resultContainer.clear();
- synchronized (receiveLock) {
- if (!ensureReceiveOpen())
- return null;
-
- int n = 0;
- try {
- begin();
-
- synchronized (stateLock) {
- if(!isOpen())
- return null;
- receiverThread = NativeThread.current();
- }
-
- do {
- n = receive(fdVal, buffer, resultContainer, fromConnect);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
- } finally {
- receiverCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
-
- if (!resultContainer.isNotification()) {
- /* message or nothing */
- if (resultContainer.hasSomething()) {
- /* Set the association before returning */
- SctpMessageInfoImpl info =
- resultContainer.getMessageInfo();
- synchronized (stateLock) {
- assert association != null;
- info.setAssociation(association);
- }
- return info;
- } else
- /* Non-blocking may return null if nothing available*/
- return null;
- } else { /* notification */
- synchronized (stateLock) {
- handleNotificationInternal(
- resultContainer);
- }
- }
-
- if (fromConnect) {
- /* If we reach here, then it was connect that invoked
- * receive and received the COMM_UP. We have already
- * handled the COMM_UP with the internal notification
- * handler. Simply return. */
- return null;
- }
- } /* receiveLock */
- } while (handler == null ? true :
- (invokeNotificationHandler(resultContainer, handler, attachment)
- == HandlerResult.CONTINUE));
-
- return null;
- } finally {
- receiveInvoked.set(Boolean.FALSE);
- }
- }
-
- private int receive(int fd,
- ByteBuffer dst,
- SctpResultContainer resultContainer,
- boolean peek)
- throws IOException {
- int pos = dst.position();
- int lim = dst.limit();
- assert (pos <= lim);
- int rem = (pos <= lim ? lim - pos : 0);
- if (dst instanceof DirectBuffer && rem > 0)
- return receiveIntoNativeBuffer(fd, resultContainer, dst, rem, pos, peek);
-
- /* Substitute a native buffer */
- int newSize = Math.max(rem, 1);
- ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
- try {
- int n = receiveIntoNativeBuffer(fd, resultContainer, bb, newSize, 0, peek);
- bb.flip();
- if (n > 0 && rem > 0)
- dst.put(bb);
- return n;
- } finally {
- Util.releaseTemporaryDirectBuffer(bb);
- }
- }
-
- private int receiveIntoNativeBuffer(int fd,
- SctpResultContainer resultContainer,
- ByteBuffer bb,
- int rem,
- int pos,
- boolean peek)
- throws IOException
- {
- int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem, peek);
-
- if (n > 0)
- bb.position(pos + n);
- return n;
- }
-
- private InternalNotificationHandler internalNotificationHandler =
- new InternalNotificationHandler();
-
- private void handleNotificationInternal(SctpResultContainer resultContainer)
- {
- invokeNotificationHandler(resultContainer,
- internalNotificationHandler, null);
- }
-
- private class InternalNotificationHandler
- extends AbstractNotificationHandler<Object>
- {
- @Override
- public HandlerResult handleNotification(
- AssociationChangeNotification not, Object unused) {
- if (not.event().equals(
- AssociationChangeNotification.AssocChangeEvent.COMM_UP) &&
- association == null) {
- SctpAssocChange sac = (SctpAssocChange) not;
- association = new SctpAssociationImpl
- (sac.assocId(), sac.maxInStreams(), sac.maxOutStreams());
- }
- return HandlerResult.CONTINUE;
- }
- }
-
- private <T> HandlerResult invokeNotificationHandler
- (SctpResultContainer resultContainer,
- NotificationHandler<T> handler,
- T attachment) {
- SctpNotification notification = resultContainer.notification();
- synchronized (stateLock) {
- notification.setAssociation(association);
- }
-
- if (!(handler instanceof AbstractNotificationHandler)) {
- return handler.handleNotification(notification, attachment);
- }
-
- /* AbstractNotificationHandler */
- AbstractNotificationHandler<T> absHandler =
- (AbstractNotificationHandler<T>)handler;
- switch(resultContainer.type()) {
- case ASSOCIATION_CHANGED :
- return absHandler.handleNotification(
- resultContainer.getAssociationChanged(), attachment);
- case PEER_ADDRESS_CHANGED :
- return absHandler.handleNotification(
- resultContainer.getPeerAddressChanged(), attachment);
- case SEND_FAILED :
- return absHandler.handleNotification(
- resultContainer.getSendFailed(), attachment);
- case SHUTDOWN :
- return absHandler.handleNotification(
- resultContainer.getShutdown(), attachment);
- default :
- /* implementation specific handlers */
- return absHandler.handleNotification(
- resultContainer.notification(), attachment);
- }
- }
-
- private void checkAssociation(Association sendAssociation) {
- synchronized (stateLock) {
- if (sendAssociation != null && !sendAssociation.equals(association)) {
- throw new IllegalArgumentException(
- "Cannot send to another association");
- }
- }
- }
-
- private void checkStreamNumber(int streamNumber) {
- synchronized (stateLock) {
- if (association != null) {
- if (streamNumber < 0 ||
- streamNumber >= association.maxOutboundStreams())
- throw new InvalidStreamException();
- }
- }
- }
-
- /* TODO: Add support for ttl and isComplete to both 121 12M
- * SCTP_EOR not yet supported on reference platforms
- * TTL support limited...
- */
- @Override
- public int send(ByteBuffer buffer, MessageInfo messageInfo)
- throws IOException {
- if (buffer == null)
- throw new IllegalArgumentException("buffer cannot be null");
-
- if (messageInfo == null)
- throw new IllegalArgumentException("messageInfo cannot be null");
-
- checkAssociation(messageInfo.association());
- checkStreamNumber(messageInfo.streamNumber());
-
- synchronized (sendLock) {
- ensureSendOpen();
-
- int n = 0;
- try {
- begin();
-
- synchronized (stateLock) {
- if(!isOpen())
- return 0;
- senderThread = NativeThread.current();
- }
-
- do {
- n = send(fdVal, buffer, messageInfo);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
-
- return IOStatus.normalize(n);
- } finally {
- senderCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- }
- }
-
- private int send(int fd, ByteBuffer src, MessageInfo messageInfo)
- throws IOException {
- int streamNumber = messageInfo.streamNumber();
- SocketAddress target = messageInfo.address();
- boolean unordered = messageInfo.isUnordered();
- int ppid = messageInfo.payloadProtocolID();
-
- if (src instanceof DirectBuffer)
- return sendFromNativeBuffer(fd, src, target, streamNumber,
- unordered, ppid);
-
- /* Substitute a native buffer */
- int pos = src.position();
- int lim = src.limit();
- assert (pos <= lim && streamNumber >= 0);
-
- int rem = (pos <= lim ? lim - pos : 0);
- ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
- try {
- bb.put(src);
- bb.flip();
- /* Do not update src until we see how many bytes were written */
- src.position(pos);
-
- int n = sendFromNativeBuffer(fd, bb, target, streamNumber,
- unordered, ppid);
- if (n > 0) {
- /* now update src */
- src.position(pos + n);
- }
- return n;
- } finally {
- Util.releaseTemporaryDirectBuffer(bb);
- }
- }
-
- private int sendFromNativeBuffer(int fd,
- ByteBuffer bb,
- SocketAddress target,
- int streamNumber,
- boolean unordered,
- int ppid)
- throws IOException {
- int pos = bb.position();
- int lim = bb.limit();
- assert (pos <= lim);
- int rem = (pos <= lim ? lim - pos : 0);
-
- int written = send0(fd, ((DirectBuffer)bb).address() + pos,
- rem, target, -1 /*121*/, streamNumber, unordered, ppid);
- if (written > 0)
- bb.position(pos + written);
- return written;
- }
-
- @Override
- public SctpChannel shutdown() throws IOException {
- synchronized(stateLock) {
- if (isShutdown)
- return this;
-
- ensureSendOpen();
- SctpNet.shutdown(fdVal, -1);
- if (senderThread != 0)
- NativeThread.signal(senderThread);
- isShutdown = true;
- }
- return this;
- }
-
- @Override
- public Set<SocketAddress> getAllLocalAddresses()
- throws IOException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- return Collections.emptySet();
-
- return SctpNet.getLocalAddresses(fdVal);
- }
- }
-
- @Override
- public Set<SocketAddress> getRemoteAddresses()
- throws IOException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isConnected() || isShutdown)
- return Collections.emptySet();
-
- try {
- return SctpNet.getRemoteAddresses(fdVal, 0/*unused*/);
- } catch (SocketException unused) {
- /* an open connected channel should always have remote addresses */
- return remoteAddresses;
- }
- }
- }
-
- /* Native */
- private static native void initIDs();
-
- static native int receive0(int fd, SctpResultContainer resultContainer,
- long address, int length, boolean peek) throws IOException;
-
- static native int send0(int fd, long address, int length,
- SocketAddress target, int assocId, int streamNumber,
- boolean unordered, int ppid) throws IOException;
-
- private static native int checkConnect(FileDescriptor fd, boolean block,
- boolean ready) throws IOException;
-
- static {
- Util.load(); /* loads nio & net native libraries */
- java.security.AccessController.doPrivileged(
- new sun.security.action.LoadLibraryAction("sctp"));
- initIDs();
- }
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,985 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.InetSocketAddress;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map.Entry;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.NotYetBoundException;
-import java.nio.channels.spi.SelectorProvider;
-import com.sun.nio.sctp.AbstractNotificationHandler;
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.AssociationChangeNotification;
-import com.sun.nio.sctp.HandlerResult;
-import com.sun.nio.sctp.IllegalReceiveException;
-import com.sun.nio.sctp.InvalidStreamException;
-import com.sun.nio.sctp.IllegalUnbindException;
-import com.sun.nio.sctp.NotificationHandler;
-import com.sun.nio.sctp.MessageInfo;
-import com.sun.nio.sctp.SctpChannel;
-import com.sun.nio.sctp.SctpMultiChannel;
-import com.sun.nio.sctp.SctpSocketOption;
-import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
-import static sun.nio.ch.SctpResultContainer.*;
-
-/**
- * An implementation of SctpMultiChannel
- */
-public class SctpMultiChannelImpl extends SctpMultiChannel
- implements SelChImpl
-{
- private final FileDescriptor fd;
-
- private final int fdVal;
-
- /* IDs of native threads doing send and receives, for signalling */
- private volatile long receiverThread = 0;
- private volatile long senderThread = 0;
-
- /* Lock held by current receiving thread */
- private final Object receiveLock = new Object();
-
- /* Lock held by current sending thread */
- private final Object sendLock = new Object();
-
- /* Lock held by any thread that modifies the state fields declared below
- * DO NOT invoke a blocking I/O operation while holding this lock! */
- private final Object stateLock = new Object();
-
- private enum ChannelState {
- UNINITIALIZED,
- KILLPENDING,
- KILLED,
- }
-
- /* -- The following fields are protected by stateLock -- */
- private ChannelState state = ChannelState.UNINITIALIZED;
-
- /* Binding: Once bound the port will remain constant. */
- int port = -1;
- private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
- /* Has the channel been bound to the wildcard address */
- private boolean wildcard; /* false */
-
- /* Keeps a map of addresses to association, and visa versa */
- private HashMap<SocketAddress, Association> addressMap =
- new HashMap<SocketAddress, Association>();
- private HashMap<Association, Set<SocketAddress>> associationMap =
- new HashMap<Association, Set<SocketAddress>>();
-
- /* -- End of fields protected by stateLock -- */
-
- /* If an association has been shutdown mark it for removal after
- * the user handler has been invoked */
- private final ThreadLocal<Association> associationToRemove =
- new ThreadLocal<Association>() {
- @Override protected Association initialValue() {
- return null;
- }
- };
-
- /* A notification handler cannot invoke receive */
- private final ThreadLocal<Boolean> receiveInvoked =
- new ThreadLocal<Boolean>() {
- @Override protected Boolean initialValue() {
- return Boolean.FALSE;
- }
- };
-
- public SctpMultiChannelImpl(SelectorProvider provider)
- throws IOException {
- //TODO: update provider, remove public modifier
- super(provider);
- this.fd = SctpNet.socket(false /*one-to-many*/);
- this.fdVal = IOUtil.fdVal(fd);
- }
-
- @Override
- public SctpMultiChannel bind(SocketAddress local, int backlog)
- throws IOException {
- synchronized (receiveLock) {
- synchronized (sendLock) {
- synchronized (stateLock) {
- ensureOpen();
- if (isBound())
- SctpNet.throwAlreadyBoundException();
- InetSocketAddress isa = (local == null) ?
- new InetSocketAddress(0) : Net.checkAddress(local);
-
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkListen(isa.getPort());
- Net.bind(fd, isa.getAddress(), isa.getPort());
-
- InetSocketAddress boundIsa = Net.localAddress(fd);
- port = boundIsa.getPort();
- localAddresses.add(isa);
- if (isa.getAddress().isAnyLocalAddress())
- wildcard = true;
-
- SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog);
- }
- }
- }
- return this;
- }
-
- @Override
- public SctpMultiChannel bindAddress(InetAddress address)
- throws IOException {
- return bindUnbindAddress(address, true);
- }
-
- @Override
- public SctpMultiChannel unbindAddress(InetAddress address)
- throws IOException {
- return bindUnbindAddress(address, false);
- }
-
- private SctpMultiChannel bindUnbindAddress(InetAddress address,
- boolean add)
- throws IOException {
- if (address == null)
- throw new IllegalArgumentException();
-
- synchronized (receiveLock) {
- synchronized (sendLock) {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- throw new NotYetBoundException();
- if (wildcard)
- throw new IllegalStateException(
- "Cannot add or remove addresses from a channel that is bound to the wildcard address");
- if (address.isAnyLocalAddress())
- throw new IllegalArgumentException(
- "Cannot add or remove the wildcard address");
- if (add) {
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- SctpNet.throwAlreadyBoundException();
- }
- }
- } else { /*removing */
- /* Verify that there is more than one address
- * and that address is already bound */
- if (localAddresses.size() <= 1)
- throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
- boolean foundAddress = false;
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- foundAddress = true;
- break;
- }
- }
- if (!foundAddress )
- throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
- }
-
- SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
-
- /* Update our internal Set to reflect the addition/removal */
- if (add)
- localAddresses.add(new InetSocketAddress(address, port));
- else {
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- localAddresses.remove(addr);
- break;
- }
- }
- }
- }
- }
- }
- return this;
- }
-
- @Override
- public Set<Association> associations()
- throws ClosedChannelException, NotYetBoundException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- throw new NotYetBoundException();
-
- return Collections.unmodifiableSet(associationMap.keySet());
- }
- }
-
- private boolean isBound() {
- synchronized (stateLock) {
- return port == -1 ? false : true;
- }
- }
-
- private void ensureOpen() throws IOException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- }
- }
-
- private void receiverCleanup() throws IOException {
- synchronized (stateLock) {
- receiverThread = 0;
- if (state == ChannelState.KILLPENDING)
- kill();
- }
- }
-
- private void senderCleanup() throws IOException {
- synchronized (stateLock) {
- senderThread = 0;
- if (state == ChannelState.KILLPENDING)
- kill();
- }
- }
-
- @Override
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
- @Override
- public void implCloseSelectableChannel() throws IOException {
- synchronized (stateLock) {
- SctpNet.preClose(fdVal);
-
- if (receiverThread != 0)
- NativeThread.signal(receiverThread);
-
- if (senderThread != 0)
- NativeThread.signal(senderThread);
-
- if (!isRegistered())
- kill();
- }
- }
-
- @Override
- public FileDescriptor getFD() {
- return fd;
- }
-
- @Override
- public int getFDVal() {
- return fdVal;
- }
-
- /**
- * Translates native poll revent ops into a ready operation ops
- */
- private boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps();
- int oldOps = sk.nioReadyOps();
- int newOps = initialOps;
-
- if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
- /* This should only happen if this channel is pre-closed while a
- * selection operation is in progress
- * ## Throw an error if this channel has not been pre-closed */
- return false;
- }
-
- if ((ops & (PollArrayWrapper.POLLERR
- | PollArrayWrapper.POLLHUP)) != 0) {
- newOps = intOps;
- sk.nioReadyOps(newOps);
- return (newOps & ~oldOps) != 0;
- }
-
- if (((ops & PollArrayWrapper.POLLIN) != 0) &&
- ((intOps & SelectionKey.OP_READ) != 0))
- newOps |= SelectionKey.OP_READ;
-
- if (((ops & PollArrayWrapper.POLLOUT) != 0) &&
- ((intOps & SelectionKey.OP_WRITE) != 0))
- newOps |= SelectionKey.OP_WRITE;
-
- sk.nioReadyOps(newOps);
- return (newOps & ~oldOps) != 0;
- }
-
- @Override
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
- }
-
- @Override
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
- }
-
- @Override
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
- int newOps = 0;
- if ((ops & SelectionKey.OP_READ) != 0)
- newOps |= PollArrayWrapper.POLLIN;
- if ((ops & SelectionKey.OP_WRITE) != 0)
- newOps |= PollArrayWrapper.POLLOUT;
- sk.selector.putEventOps(sk, newOps);
- }
-
- @Override
- public void kill() throws IOException {
- synchronized (stateLock) {
- if (state == ChannelState.KILLED)
- return;
- if (state == ChannelState.UNINITIALIZED) {
- state = ChannelState.KILLED;
- return;
- }
- assert !isOpen() && !isRegistered();
-
- /* Postpone the kill if there is a thread sending or receiving. */
- if (receiverThread == 0 && senderThread == 0) {
- SctpNet.close(fdVal);
- state = ChannelState.KILLED;
- } else {
- state = ChannelState.KILLPENDING;
- }
- }
- }
-
- @Override
- public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
- T value,
- Association association)
- throws IOException {
- if (name == null)
- throw new NullPointerException();
- if (!(supportedOptions().contains(name)))
- throw new UnsupportedOperationException("'" + name + "' not supported");
-
- synchronized (stateLock) {
- if (association != null && (name.equals(SCTP_PRIMARY_ADDR) ||
- name.equals(SCTP_SET_PEER_PRIMARY_ADDR))) {
- checkAssociation(association);
- }
- if (!isOpen())
- throw new ClosedChannelException();
-
- int assocId = association == null ? 0 : association.associationID();
- SctpNet.setSocketOption(fdVal, name, value, assocId);
- }
- return this;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T> T getOption(SctpSocketOption<T> name, Association association)
- throws IOException {
- if (name == null)
- throw new NullPointerException();
- if (!supportedOptions().contains(name))
- throw new UnsupportedOperationException("'" + name + "' not supported");
-
- synchronized (stateLock) {
- if (association != null && (name.equals(SCTP_PRIMARY_ADDR) ||
- name.equals(SCTP_SET_PEER_PRIMARY_ADDR))) {
- checkAssociation(association);
- }
- if (!isOpen())
- throw new ClosedChannelException();
-
- int assocId = association == null ? 0 : association.associationID();
- return (T)SctpNet.getSocketOption(fdVal, name, assocId);
- }
- }
-
- private static class DefaultOptionsHolder {
- static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
-
- private static Set<SctpSocketOption<?>> defaultOptions() {
- HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(10);
- set.add(SCTP_DISABLE_FRAGMENTS);
- set.add(SCTP_EXPLICIT_COMPLETE);
- set.add(SCTP_FRAGMENT_INTERLEAVE);
- set.add(SCTP_INIT_MAXSTREAMS);
- set.add(SCTP_NODELAY);
- set.add(SCTP_PRIMARY_ADDR);
- set.add(SCTP_SET_PEER_PRIMARY_ADDR);
- set.add(SO_SNDBUF);
- set.add(SO_RCVBUF);
- set.add(SO_LINGER);
- return Collections.unmodifiableSet(set);
- }
- }
-
- @Override
- public final Set<SctpSocketOption<?>> supportedOptions() {
- return DefaultOptionsHolder.defaultOptions;
- }
-
- @Override
- public <T> MessageInfo receive(ByteBuffer buffer,
- T attachment,
- NotificationHandler<T> handler)
- throws IOException {
- if (buffer == null)
- throw new IllegalArgumentException("buffer cannot be null");
-
- if (buffer.isReadOnly())
- throw new IllegalArgumentException("Read-only buffer");
-
- if (receiveInvoked.get())
- throw new IllegalReceiveException(
- "cannot invoke receive from handler");
- receiveInvoked.set(Boolean.TRUE);
-
- try {
- SctpResultContainer resultContainer = new SctpResultContainer();
- do {
- resultContainer.clear();
- synchronized (receiveLock) {
- ensureOpen();
- if (!isBound())
- throw new NotYetBoundException();
-
- int n = 0;
- try {
- begin();
-
- synchronized (stateLock) {
- if(!isOpen())
- return null;
- receiverThread = NativeThread.current();
- }
-
- do {
- n = receive(fdVal, buffer, resultContainer);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
-
- } finally {
- receiverCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
-
- if (!resultContainer.isNotification()) {
- /* message or nothing */
- if (resultContainer.hasSomething()) {
- /* Set the association before returning */
- SctpMessageInfoImpl info =
- resultContainer.getMessageInfo();
- info.setAssociation(lookupAssociation(info.
- associationID()));
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- InetSocketAddress isa = (InetSocketAddress)info.address();
- if (!addressMap.containsKey(isa)) {
- /* must be a new association */
- try {
- sm.checkAccept(isa.getAddress().getHostAddress(),
- isa.getPort());
- } catch (SecurityException se) {
- buffer.clear();
- throw se;
- }
- }
- }
-
- assert info.association() != null;
- return info;
- } else {
- /* Non-blocking may return null if nothing available*/
- return null;
- }
- } else { /* notification */
- synchronized (stateLock) {
- handleNotificationInternal(
- resultContainer);
- }
- }
- } /* receiveLock */
- } while (handler == null ? true :
- (invokeNotificationHandler(resultContainer, handler, attachment)
- == HandlerResult.CONTINUE));
- } finally {
- receiveInvoked.set(Boolean.FALSE);
- }
-
- return null;
- }
-
- private int receive(int fd,
- ByteBuffer dst,
- SctpResultContainer resultContainer)
- throws IOException {
- int pos = dst.position();
- int lim = dst.limit();
- assert (pos <= lim);
- int rem = (pos <= lim ? lim - pos : 0);
- if (dst instanceof DirectBuffer && rem > 0)
- return receiveIntoNativeBuffer(fd, resultContainer, dst, rem, pos);
-
- /* Substitute a native buffer. */
- int newSize = Math.max(rem, 1);
- ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
- try {
- int n = receiveIntoNativeBuffer(fd, resultContainer, bb, newSize, 0);
- bb.flip();
- if (n > 0 && rem > 0)
- dst.put(bb);
- return n;
- } finally {
- Util.releaseTemporaryDirectBuffer(bb);
- }
- }
-
- private int receiveIntoNativeBuffer(int fd,
- SctpResultContainer resultContainer,
- ByteBuffer bb,
- int rem,
- int pos)
- throws IOException {
- int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
- if (n > 0)
- bb.position(pos + n);
- return n;
- }
-
- private InternalNotificationHandler internalNotificationHandler =
- new InternalNotificationHandler();
-
- private void handleNotificationInternal(SctpResultContainer resultContainer)
- {
- invokeNotificationHandler(resultContainer,
- internalNotificationHandler, null);
- }
-
- private class InternalNotificationHandler
- extends AbstractNotificationHandler<Object>
- {
- @Override
- public HandlerResult handleNotification(
- AssociationChangeNotification not, Object unused) {
- SctpAssocChange sac = (SctpAssocChange) not;
-
- /* Update map to reflect change in association */
- switch (not.event()) {
- case COMM_UP :
- Association newAssociation = new SctpAssociationImpl
- (sac.assocId(), sac.maxInStreams(), sac.maxOutStreams());
- addAssociation(newAssociation);
- break;
- case SHUTDOWN :
- case COMM_LOST :
- //case RESTART: ???
- /* mark association for removal after user handler invoked*/
- associationToRemove.set(lookupAssociation(sac.assocId()));
- }
- return HandlerResult.CONTINUE;
- }
- }
-
- private <T> HandlerResult invokeNotificationHandler(
- SctpResultContainer resultContainer,
- NotificationHandler<T> handler,
- T attachment) {
- HandlerResult result;
- SctpNotification notification = resultContainer.notification();
- notification.setAssociation(lookupAssociation(notification.assocId()));
-
- if (!(handler instanceof AbstractNotificationHandler)) {
- result = handler.handleNotification(notification, attachment);
- } else { /* AbstractNotificationHandler */
- AbstractNotificationHandler<T> absHandler =
- (AbstractNotificationHandler<T>)handler;
- switch(resultContainer.type()) {
- case ASSOCIATION_CHANGED :
- result = absHandler.handleNotification(
- resultContainer.getAssociationChanged(), attachment);
- break;
- case PEER_ADDRESS_CHANGED :
- result = absHandler.handleNotification(
- resultContainer.getPeerAddressChanged(), attachment);
- break;
- case SEND_FAILED :
- result = absHandler.handleNotification(
- resultContainer.getSendFailed(), attachment);
- break;
- case SHUTDOWN :
- result = absHandler.handleNotification(
- resultContainer.getShutdown(), attachment);
- break;
- default :
- /* implementation specific handlers */
- result = absHandler.handleNotification(
- resultContainer.notification(), attachment);
- }
- }
-
- if (!(handler instanceof InternalNotificationHandler)) {
- /* Only remove associations after user handler
- * has finished with them */
- Association assoc = associationToRemove.get();
- if (assoc != null) {
- removeAssociation(assoc);
- associationToRemove.set(null);
- }
-
- }
-
- return result;
- }
-
- private Association lookupAssociation(int assocId) {
- /* Lookup the association in our internal map */
- synchronized (stateLock) {
- Set<Association> assocs = associationMap.keySet();
- for (Association a : assocs) {
- if (a.associationID() == assocId) {
- return a;
- }
- }
- }
- return null;
- }
-
- private void addAssociation(Association association) {
- synchronized (stateLock) {
- int assocId = association.associationID();
- Set<SocketAddress> addresses = null;
-
- try {
- addresses = SctpNet.getRemoteAddresses(fdVal, assocId);
- } catch (IOException unused) {
- /* OK, determining connected addresses may not be possible
- * shutdown, connection lost, etc */
- }
-
- associationMap.put(association, addresses);
- if (addresses != null) {
- for (SocketAddress addr : addresses)
- addressMap.put(addr, association);
- }
- }
- }
-
- private void removeAssociation(Association association) {
- synchronized (stateLock) {
- int assocId = association.associationID();
- Set<SocketAddress> addresses = null;
-
- try {
- addresses = SctpNet.getRemoteAddresses(fdVal, assocId);
- } catch (IOException unused) {
- /* OK, determining connected addresses may not be possible
- * shutdown, connection lost, etc */
- }
-
- Set<Association> assocs = associationMap.keySet();
- for (Association a : assocs) {
- if (a.associationID() == assocId) {
- associationMap.remove(a);
- break;
- }
- }
- if (addresses != null) {
- for (SocketAddress addr : addresses)
- addressMap.remove(addr);
- } else {
- /* We cannot determine the connected addresses */
- Set<java.util.Map.Entry<SocketAddress, Association>> addrAssocs =
- addressMap.entrySet();
- Iterator<Entry<SocketAddress, Association>> iterator = addrAssocs.iterator();
- while (iterator.hasNext()) {
- Entry<SocketAddress, Association> entry = iterator.next();
- if (entry.getValue().equals(association)) {
- iterator.remove();
- }
- }
- }
- }
- }
-
- /**
- * @throws IllegalArgumentException
- * If the given association is not controlled by this channel
- *
- * @return {@code true} if, and only if, the given association is one
- * of the current associations controlled by this channel
- */
- private boolean checkAssociation(Association messageAssoc) {
- synchronized (stateLock) {
- for (Association association : associationMap.keySet()) {
- if (messageAssoc.equals(association)) {
- return true;
- }
- }
- }
- throw new IllegalArgumentException(
- "Given Association is not controlled by this channel");
- }
-
- private void checkStreamNumber(Association assoc, int streamNumber) {
- synchronized (stateLock) {
- if (streamNumber < 0 || streamNumber >= assoc.maxOutboundStreams())
- throw new InvalidStreamException();
- }
- }
-
- /* TODO: Add support for ttl and isComplete to both 121 12M
- * SCTP_EOR not yet supported on reference platforms
- * TTL support limited...
- */
- @Override
- public int send(ByteBuffer buffer, MessageInfo messageInfo)
- throws IOException {
- if (buffer == null)
- throw new IllegalArgumentException("buffer cannot be null");
-
- if (messageInfo == null)
- throw new IllegalArgumentException("messageInfo cannot be null");
-
- synchronized (sendLock) {
- ensureOpen();
-
- if (!isBound())
- bind(null, 0);
-
- int n = 0;
- try {
- int assocId = -1;
- SocketAddress address = null;
- begin();
-
- synchronized (stateLock) {
- if(!isOpen())
- return 0;
- senderThread = NativeThread.current();
-
- /* Determine what address or association to send to */
- Association assoc = messageInfo.association();
- InetSocketAddress addr = (InetSocketAddress)messageInfo.address();
- if (assoc != null) {
- checkAssociation(assoc);
- checkStreamNumber(assoc, messageInfo.streamNumber());
- assocId = assoc.associationID();
- /* have we also got a preferred address */
- if (addr != null) {
- if (!assoc.equals(addressMap.get(addr)))
- throw new IllegalArgumentException("given preferred address is not part of this association");
- address = addr;
- }
- } else if (addr != null) {
- address = addr;
- Association association = addressMap.get(addr);
- if (association != null) {
- checkStreamNumber(association, messageInfo.streamNumber());
- assocId = association.associationID();
-
- } else { /* must be new association */
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkConnect(addr.getAddress().getHostAddress(),
- addr.getPort());
- }
- } else {
- throw new AssertionError(
- "Both association and address cannot be null");
- }
- }
-
- do {
- n = send(fdVal, buffer, assocId, address, messageInfo);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
-
- return IOStatus.normalize(n);
- } finally {
- senderCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- }
- }
-
- private int send(int fd,
- ByteBuffer src,
- int assocId,
- SocketAddress target,
- MessageInfo messageInfo)
- throws IOException {
- int streamNumber = messageInfo.streamNumber();
- boolean unordered = messageInfo.isUnordered();
- int ppid = messageInfo.payloadProtocolID();
-
- if (src instanceof DirectBuffer)
- return sendFromNativeBuffer(fd, src, target, assocId,
- streamNumber, unordered, ppid);
-
- /* Substitute a native buffer */
- int pos = src.position();
- int lim = src.limit();
- assert (pos <= lim && streamNumber >= 0);
-
- int rem = (pos <= lim ? lim - pos : 0);
- ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
- try {
- bb.put(src);
- bb.flip();
- /* Do not update src until we see how many bytes were written */
- src.position(pos);
-
- int n = sendFromNativeBuffer(fd, bb, target, assocId,
- streamNumber, unordered, ppid);
- if (n > 0) {
- /* now update src */
- src.position(pos + n);
- }
- return n;
- } finally {
- Util.releaseTemporaryDirectBuffer(bb);
- }
- }
-
- private int sendFromNativeBuffer(int fd,
- ByteBuffer bb,
- SocketAddress target,
- int assocId,
- int streamNumber,
- boolean unordered,
- int ppid)
- throws IOException {
- int pos = bb.position();
- int lim = bb.limit();
- assert (pos <= lim);
- int rem = (pos <= lim ? lim - pos : 0);
-
- int written = send0(fd, ((DirectBuffer)bb).address() + pos,
- rem, target, assocId, streamNumber, unordered, ppid);
- if (written > 0)
- bb.position(pos + written);
- return written;
- }
-
- @Override
- public SctpMultiChannel shutdown(Association association)
- throws IOException {
- synchronized (stateLock) {
- checkAssociation(association);
- if (!isOpen())
- throw new ClosedChannelException();
-
- SctpNet.shutdown(fdVal, association.associationID());
- }
- return this;
- }
-
- @Override
- public Set<SocketAddress> getAllLocalAddresses()
- throws IOException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- return Collections.emptySet();
-
- return SctpNet.getLocalAddresses(fdVal);
- }
- }
-
- @Override
- public Set<SocketAddress> getRemoteAddresses(Association association)
- throws IOException {
- synchronized (stateLock) {
- checkAssociation(association);
- if (!isOpen())
- throw new ClosedChannelException();
-
- try {
- return SctpNet.getRemoteAddresses(fdVal, association.associationID());
- } catch (SocketException se) {
- /* a valid association should always have remote addresses */
- Set<SocketAddress> addrs = associationMap.get(association);
- return addrs != null ? addrs : Collections.<SocketAddress>emptySet();
- }
- }
- }
-
- @Override
- public SctpChannel branch(Association association)
- throws IOException {
- synchronized (stateLock) {
- checkAssociation(association);
- if (!isOpen())
- throw new ClosedChannelException();
-
- FileDescriptor bFd = SctpNet.branch(fdVal,
- association.associationID());
- /* successfully branched, we can now remove it from assoc list */
- removeAssociation(association);
-
- return new SctpChannelImpl(provider(), bFd, association);
- }
- }
-
- /* Use common native implementation shared between
- * one-to-one and one-to-many */
- private static int receive0(int fd,
- SctpResultContainer resultContainer,
- long address,
- int length)
- throws IOException{
- return SctpChannelImpl.receive0(fd, resultContainer, address,
- length, false /*peek */);
- }
-
- private static int send0(int fd,
- long address,
- int length,
- SocketAddress target,
- int assocId,
- int streamNumber,
- boolean unordered,
- int ppid)
- throws IOException {
- return SctpChannelImpl.send0(fd, address, length, target, assocId,
- streamNumber, unordered, ppid);
- }
-
- static {
- Util.load(); /* loads nio & net native libraries */
- java.security.AccessController.doPrivileged(
- new sun.security.action.LoadLibraryAction("sctp"));
- }
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.channels.AlreadyBoundException;
-import java.util.Set;
-import java.util.HashSet;
-import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
-import com.sun.nio.sctp.SctpSocketOption;
-import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
-
-public class SctpNet {
- static final String osName = AccessController.doPrivileged(
- new GetPropertyAction("os.name"));
-
- /* -- Miscellaneous SCTP utilities -- */
-
- private static boolean IPv4MappedAddresses() {
- if ("SunOS".equals(osName)) {
- /* Solaris supports IPv4Mapped Addresses with bindx */
- return true;
- } /* else { //other OS/implementations */
-
- /* lksctp/linux requires Ipv4 addresses */
- return false;
- }
-
- static boolean throwAlreadyBoundException() throws IOException {
- throw new AlreadyBoundException();
- }
-
- static void listen(int fd, int backlog) throws IOException {
- listen0(fd, backlog);
- }
-
- static int connect(int fd, InetAddress remote, int remotePort)
- throws IOException {
- return connect0(fd, remote, remotePort);
- }
-
- static void close(int fd) throws IOException {
- close0(fd);
- }
-
- static void preClose(int fd) throws IOException {
- preClose0(fd);
- }
-
- /**
- * @param oneToOne
- * if {@code true} returns a one-to-one sctp socket, otherwise
- * returns a one-to-many sctp socket
- */
- static FileDescriptor socket(boolean oneToOne) throws IOException {
- int nativefd = socket0(oneToOne);
- return IOUtil.newFD(nativefd);
- }
-
- static void bindx(int fd, InetAddress[] addrs, int port, boolean add)
- throws IOException {
- bindx(fd, addrs, port, addrs.length, add,
- IPv4MappedAddresses());
- }
-
- static Set<SocketAddress> getLocalAddresses(int fd)
- throws IOException {
- HashSet<SocketAddress> set = null;
- SocketAddress[] saa = getLocalAddresses0(fd);
-
- if (saa != null) {
- set = new HashSet<SocketAddress>(saa.length);
- for (SocketAddress sa : saa)
- set.add(sa);
- }
-
- return set;
- }
-
- static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)
- throws IOException {
- HashSet<SocketAddress> set = null;
- SocketAddress[] saa = getRemoteAddresses0(fd, assocId);
-
- if (saa != null) {
- set = new HashSet<SocketAddress>(saa.length);
- for (SocketAddress sa : saa)
- set.add(sa);
- }
-
- return set;
- }
-
- static <T> void setSocketOption(int fd,
- SctpSocketOption<T> name,
- T value,
- int assocId)
- throws IOException {
- if (value == null)
- throw new IllegalArgumentException("Invalid option value");
-
- if (name.equals(SCTP_INIT_MAXSTREAMS)) {
- InitMaxStreams maxStreamValue = (InitMaxStreams)value;
- SctpNet.setInitMsgOption0(fd,
- maxStreamValue.maxInStreams(), maxStreamValue.maxOutStreams());
- } else if (name.equals(SCTP_PRIMARY_ADDR) ||
- name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {
-
- SocketAddress addr = (SocketAddress) value;
- if (addr == null)
- throw new IllegalArgumentException("Invalid option value");
-
- Net.checkAddress(addr);
- InetSocketAddress netAddr = (InetSocketAddress)addr;
-
- if (name.equals(SCTP_PRIMARY_ADDR)) {
- setPrimAddrOption0(fd,
- assocId,
- netAddr.getAddress(),
- netAddr.getPort());
- } else {
- setPeerPrimAddrOption0(fd,
- assocId,
- netAddr.getAddress(),
- netAddr.getPort(),
- IPv4MappedAddresses());
- }
- } else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||
- name.equals(SCTP_EXPLICIT_COMPLETE) ||
- name.equals(SCTP_FRAGMENT_INTERLEAVE) ||
- name.equals(SCTP_NODELAY) ||
- name.equals(SO_SNDBUF) ||
- name.equals(SO_RCVBUF) ||
- name.equals(SO_LINGER)) {
- setIntOption(fd, name, value);
- } else {
- throw new AssertionError("Unknown socket option");
- }
- }
-
- static Object getSocketOption(int fd, SctpSocketOption<?> name, int assocId)
- throws IOException {
- if (name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {
- throw new IllegalArgumentException(
- "SCTP_SET_PEER_PRIMARY_ADDR cannot be retrieved");
- } else if (name.equals(SCTP_INIT_MAXSTREAMS)) {
- /* container for holding maxIn/Out streams */
- int[] values = new int[2];
- SctpNet.getInitMsgOption0(fd, values);
- return InitMaxStreams.create(values[0], values[1]);
- } else if (name.equals(SCTP_PRIMARY_ADDR)) {
- return getPrimAddrOption0(fd, assocId);
- } else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||
- name.equals(SCTP_EXPLICIT_COMPLETE) ||
- name.equals(SCTP_FRAGMENT_INTERLEAVE) ||
- name.equals(SCTP_NODELAY) ||
- name.equals(SO_SNDBUF) ||
- name.equals(SO_RCVBUF) ||
- name.equals(SO_LINGER)) {
- return getIntOption(fd, name);
- } else {
- throw new AssertionError("Unknown socket option");
- }
- }
-
- static void setIntOption(int fd, SctpSocketOption<?> name, Object value)
- throws IOException {
- if (value == null)
- throw new IllegalArgumentException("Invalid option value");
-
- Class<?> type = name.type();
- if (type != Integer.class && type != Boolean.class)
- throw new AssertionError("Should not reach here");
-
- if (name == SO_RCVBUF ||
- name == SO_SNDBUF)
- {
- int i = ((Integer)value).intValue();
- if (i < 0)
- throw new IllegalArgumentException(
- "Invalid send/receive buffer size");
- } else if (name == SO_LINGER) {
- int i = ((Integer)value).intValue();
- if (i < 0)
- value = Integer.valueOf(-1);
- if (i > 65535)
- value = Integer.valueOf(65535);
- } else if (name.equals(SCTP_FRAGMENT_INTERLEAVE)) {
- int i = ((Integer)value).intValue();
- if (i < 0 || i > 2)
- throw new IllegalArgumentException(
- "Invalid value for SCTP_FRAGMENT_INTERLEAVE");
- }
-
- int arg;
- if (type == Integer.class) {
- arg = ((Integer)value).intValue();
- } else {
- boolean b = ((Boolean)value).booleanValue();
- arg = (b) ? 1 : 0;
- }
-
- setIntOption0(fd, ((SctpStdSocketOption)name).constValue(), arg);
- }
-
- static Object getIntOption(int fd, SctpSocketOption<?> name)
- throws IOException {
- Class<?> type = name.type();
-
- if (type != Integer.class && type != Boolean.class)
- throw new AssertionError("Should not reach here");
-
- if (!(name instanceof SctpStdSocketOption))
- throw new AssertionError("Should not reach here");
-
- int value = getIntOption0(fd,
- ((SctpStdSocketOption)name).constValue());
-
- if (type == Integer.class) {
- return Integer.valueOf(value);
- } else {
- return (value == 0) ? Boolean.FALSE : Boolean.TRUE;
- }
- }
-
- static void shutdown(int fd, int assocId)
- throws IOException {
- shutdown0(fd, assocId);
- }
-
- static FileDescriptor branch(int fd, int assocId) throws IOException {
- int nativefd = branch0(fd, assocId);
- return IOUtil.newFD(nativefd);
- }
-
- /* Native Methods */
- static native int socket0(boolean oneToOne) throws IOException;
-
- static native void listen0(int fd, int backlog) throws IOException;
-
- static native int connect0(int fd, InetAddress remote, int remotePort)
- throws IOException;
-
- static native void close0(int fd) throws IOException;
-
- static native void preClose0(int fd) throws IOException;
-
- static native void bindx(int fd, InetAddress[] addrs, int port, int length,
- boolean add, boolean preferIPv6) throws IOException;
-
- static native int getIntOption0(int fd, int opt) throws IOException;
-
- static native void setIntOption0(int fd, int opt, int arg)
- throws IOException;
-
- static native SocketAddress[] getLocalAddresses0(int fd) throws IOException;
-
- static native SocketAddress[] getRemoteAddresses0(int fd, int assocId)
- throws IOException;
-
- static native int branch0(int fd, int assocId) throws IOException;
-
- static native void setPrimAddrOption0(int fd, int assocId, InetAddress ia,
- int port) throws IOException;
-
- static native void setPeerPrimAddrOption0(int fd, int assocId,
- InetAddress ia, int port, boolean preferIPv6) throws IOException;
-
- static native SocketAddress getPrimAddrOption0(int fd, int assocId)
- throws IOException;
-
- /* retVals [0] maxInStreams, [1] maxOutStreams */
- static native void getInitMsgOption0(int fd, int[] retVals) throws IOException;
-
- static native void setInitMsgOption0(int fd, int arg1, int arg2)
- throws IOException;
-
- static native void shutdown0(int fd, int assocId);
-
- static native void init();
-
- static {
- init();
- }
-}
-
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpNotification.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.Notification;
-
-/**
- * All Notification implemenations MUST implement this interface to provide
- * access to the native association identidier.
- */
-interface SctpNotification extends Notification {
- int assocId();
- void setAssociation(Association association);
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpPeerAddrChange.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.SocketAddress;
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.PeerAddressChangeNotification;
-
-/**
- * An implementation of PeerAddressChangeNotification
- */
-public class SctpPeerAddrChange extends PeerAddressChangeNotification
- implements SctpNotification
-{
- /* static final ints so that they can be referenced from native */
- private final static int SCTP_ADDR_AVAILABLE = 1;
- private final static int SCTP_ADDR_UNREACHABLE = 2;
- private final static int SCTP_ADDR_REMOVED = 3;
- private final static int SCTP_ADDR_ADDED = 4;
- private final static int SCTP_ADDR_MADE_PRIM = 5;
- private final static int SCTP_ADDR_CONFIRMED =6;
-
- private Association association;
-
- /* assocId is used to lookup the association before the notification is
- * returned to user code */
- private int assocId;
- private SocketAddress address;
- private AddressChangeEvent event;
-
- /* Invoked from native */
- private SctpPeerAddrChange(int assocId, SocketAddress address, int intEvent) {
- switch (intEvent) {
- case SCTP_ADDR_AVAILABLE :
- this.event = AddressChangeEvent.ADDR_AVAILABLE;
- break;
- case SCTP_ADDR_UNREACHABLE :
- this.event = AddressChangeEvent.ADDR_UNREACHABLE;
- break;
- case SCTP_ADDR_REMOVED :
- this.event = AddressChangeEvent.ADDR_REMOVED;
- break;
- case SCTP_ADDR_ADDED :
- this.event = AddressChangeEvent.ADDR_ADDED;
- break;
- case SCTP_ADDR_MADE_PRIM :
- this.event = AddressChangeEvent.ADDR_MADE_PRIMARY;
- break;
- case SCTP_ADDR_CONFIRMED :
- this.event = AddressChangeEvent.ADDR_CONFIRMED;
- break;
- default:
- throw new AssertionError("Unknown event type");
- }
- this.assocId = assocId;
- this.address = address;
- }
-
- @Override
- public int assocId() {
- return assocId;
- }
-
- @Override
- public void setAssociation(Association association) {
- this.association = association;
- }
-
- @Override
- public SocketAddress address() {
- assert address != null;
- return address;
- }
-
- @Override
- public Association association() {
- assert association != null;
- return association;
- }
-
- @Override
- public AddressChangeEvent event() {
- assert event != null;
- return event;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(super.toString()).append(" [");
- sb.append("Address: ").append(address);
- sb.append(", Association:").append(association);
- sb.append(", Event: ").append(event).append("]");
- return sb.toString();
- }
-}
-
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpResultContainer.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-/**
- * Wraps the actual message or notification so that it can be
- * set and returned from the native receive implementation.
- */
-public class SctpResultContainer {
- /* static final ints so that they can be referenced from native */
- static final int NOTHING = 0;
- static final int MESSAGE = 1;
- static final int SEND_FAILED = 2;
- static final int ASSOCIATION_CHANGED = 3;
- static final int PEER_ADDRESS_CHANGED = 4;
- static final int SHUTDOWN = 5;
-
- private Object value;
- private int type;
-
- int type() {
- return type;
- }
-
- boolean hasSomething() {
- return type() != NOTHING;
- }
-
- boolean isNotification() {
- return type() != MESSAGE && type() != NOTHING ? true : false;
- }
-
- void clear() {
- type = NOTHING;
- value = null;
- }
-
- SctpNotification notification() {
- assert type() != MESSAGE && type() != NOTHING;
-
- return (SctpNotification) value;
- }
-
- SctpMessageInfoImpl getMessageInfo() {
- assert type() == MESSAGE;
-
- if (value instanceof SctpMessageInfoImpl)
- return (SctpMessageInfoImpl) value;
-
- return null;
- }
-
- SctpSendFailed getSendFailed() {
- assert type() == SEND_FAILED;
-
- if (value instanceof SctpSendFailed)
- return (SctpSendFailed) value;
-
- return null;
- }
-
- SctpAssocChange getAssociationChanged() {
- assert type() == ASSOCIATION_CHANGED;
-
- if (value instanceof SctpAssocChange)
- return (SctpAssocChange) value;
-
- return null;
- }
-
- SctpPeerAddrChange getPeerAddressChanged() {
- assert type() == PEER_ADDRESS_CHANGED;
-
- if (value instanceof SctpPeerAddrChange)
- return (SctpPeerAddrChange) value;
-
- return null;
- }
-
- SctpShutdown getShutdown() {
- assert type() == SHUTDOWN;
-
- if (value instanceof SctpShutdown)
- return (SctpShutdown) value;
-
- return null;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("Type: ");
- switch (type) {
- case NOTHING: sb.append("NOTHING"); break;
- case MESSAGE: sb.append("MESSAGE"); break;
- case SEND_FAILED: sb.append("SEND FAILED"); break;
- case ASSOCIATION_CHANGED: sb.append("ASSOCIATION CHANGE"); break;
- case PEER_ADDRESS_CHANGED: sb.append("PEER ADDRESS CHANGE"); break;
- case SHUTDOWN: sb.append("SHUTDOWN"); break;
- default : sb.append("Unknown result type");
- }
- sb.append(", Value: ");
- sb.append((value == null) ? "null" : value.toString());
- return sb.toString();
- }
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpSendFailed.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.nio.ByteBuffer;
-import java.net.SocketAddress;
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.SendFailedNotification;
-
-/**
- * An implementation of SendFailedNotification
- */
-public class SctpSendFailed extends SendFailedNotification
- implements SctpNotification
-{
- private Association association;
- /* assocId is used to lookup the association before the notification is
- * returned to user code */
- private int assocId;
- private SocketAddress address;
- private ByteBuffer buffer;
- private int errorCode;
- private int streamNumber;
-
- /* Invoked from native */
- private SctpSendFailed(int assocId,
- SocketAddress address,
- ByteBuffer buffer,
- int errorCode,
- int streamNumber) {
- this.assocId = assocId;
- this.errorCode = errorCode;
- this.streamNumber = streamNumber;
- this.address = address;
- this.buffer = buffer;
- }
-
- @Override
- public int assocId() {
- return assocId;
- }
-
- @Override
- public void setAssociation(Association association) {
- this.association = association;
- }
-
- @Override
- public Association association() {
- /* may be null */
- return association;
- }
-
- @Override
- public SocketAddress address() {
- assert address != null;
- return address;
- }
-
- @Override
- public ByteBuffer buffer() {
- assert buffer != null;
- return buffer;
- }
-
- @Override
- public int errorCode() {
- return errorCode;
- }
-
- @Override
- public int streamNumber() {
- return streamNumber;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(super.toString()).append(" [");
- sb.append("Association:").append(association);
- sb.append(", Address: ").append(address);
- sb.append(", buffer: ").append(buffer);
- sb.append(", errorCode: ").append(errorCode);
- sb.append(", streamNumber: ").append(streamNumber);
- sb.append("]");
- return sb.toString();
- }
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.SocketAddress;
-import java.net.InetSocketAddress;
-import java.net.InetAddress;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Set;
-import java.util.HashSet;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.NotYetBoundException;
-import java.nio.channels.spi.SelectorProvider;
-import com.sun.nio.sctp.IllegalUnbindException;
-import com.sun.nio.sctp.SctpChannel;
-import com.sun.nio.sctp.SctpServerChannel;
-import com.sun.nio.sctp.SctpSocketOption;
-import com.sun.nio.sctp.SctpStandardSocketOptions;
-
-/**
- * An implementation of SctpServerChannel
- */
-public class SctpServerChannelImpl extends SctpServerChannel
- implements SelChImpl
-{
- private final FileDescriptor fd;
-
- private final int fdVal;
-
- /* IDs of native thread doing accept, for signalling */
- private volatile long thread = 0;
-
- /* Lock held by thread currently blocked in this channel */
- private final Object lock = new Object();
-
- /* Lock held by any thread that modifies the state fields declared below
- * DO NOT invoke a blocking I/O operation while holding this lock! */
- private final Object stateLock = new Object();
-
- private enum ChannelState {
- UNINITIALIZED,
- INUSE,
- KILLPENDING,
- KILLED,
- }
- /* -- The following fields are protected by stateLock -- */
- private ChannelState state = ChannelState.UNINITIALIZED;
-
- /* Binding: Once bound the port will remain constant. */
- int port = -1;
- private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
- /* Has the channel been bound to the wildcard address */
- private boolean wildcard; /* false */
-
- /* -- End of fields protected by stateLock -- */
-
- /**
- * Initializes a new instance of this class.
- */
- public SctpServerChannelImpl(SelectorProvider provider)
- throws IOException {
- //TODO: update provider remove public modifier
- super(provider);
- this.fd = SctpNet.socket(true);
- this.fdVal = IOUtil.fdVal(fd);
- this.state = ChannelState.INUSE;
- }
-
- @Override
- public SctpServerChannel bind(SocketAddress local, int backlog)
- throws IOException {
- synchronized (lock) {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (isBound())
- SctpNet.throwAlreadyBoundException();
-
- InetSocketAddress isa = (local == null) ?
- new InetSocketAddress(0) : Net.checkAddress(local);
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkListen(isa.getPort());
- Net.bind(fd, isa.getAddress(), isa.getPort());
-
- InetSocketAddress boundIsa = Net.localAddress(fd);
- port = boundIsa.getPort();
- localAddresses.add(isa);
- if (isa.getAddress().isAnyLocalAddress())
- wildcard = true;
-
- SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog);
- }
- }
- return this;
- }
-
- @Override
- public SctpServerChannel bindAddress(InetAddress address)
- throws IOException {
- return bindUnbindAddress(address, true);
- }
-
- @Override
- public SctpServerChannel unbindAddress(InetAddress address)
- throws IOException {
- return bindUnbindAddress(address, false);
- }
-
- private SctpServerChannel bindUnbindAddress(InetAddress address, boolean add)
- throws IOException {
- if (address == null)
- throw new IllegalArgumentException();
-
- synchronized (lock) {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- throw new NotYetBoundException();
- if (wildcard)
- throw new IllegalStateException(
- "Cannot add or remove addresses from a channel that is bound to the wildcard address");
- if (address.isAnyLocalAddress())
- throw new IllegalArgumentException(
- "Cannot add or remove the wildcard address");
- if (add) {
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- SctpNet.throwAlreadyBoundException();
- }
- }
- } else { /*removing */
- /* Verify that there is more than one address
- * and that address is already bound */
- if (localAddresses.size() <= 1)
- throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
- boolean foundAddress = false;
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- foundAddress = true;
- break;
- }
- }
- if (!foundAddress )
- throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
- }
-
- SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
-
- /* Update our internal Set to reflect the addition/removal */
- if (add)
- localAddresses.add(new InetSocketAddress(address, port));
- else {
- for (InetSocketAddress addr : localAddresses) {
- if (addr.getAddress().equals(address)) {
- localAddresses.remove(addr);
- break;
- }
- }
- }
- }
- }
- return this;
- }
-
- private boolean isBound() {
- synchronized (stateLock) {
- return port == -1 ? false : true;
- }
- }
-
- private void acceptCleanup() throws IOException {
- synchronized (stateLock) {
- thread = 0;
- if (state == ChannelState.KILLPENDING)
- kill();
- }
- }
-
- @Override
- public SctpChannel accept() throws IOException {
- synchronized (lock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- throw new NotYetBoundException();
- SctpChannel sc = null;
-
- int n = 0;
- FileDescriptor newfd = new FileDescriptor();
- InetSocketAddress[] isaa = new InetSocketAddress[1];
-
- try {
- begin();
- if (!isOpen())
- return null;
- thread = NativeThread.current();
- for (;;) {
- n = accept0(fd, newfd, isaa);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- break;
- }
- } finally {
- acceptCleanup();
- end(n > 0);
- assert IOStatus.check(n);
- }
-
- if (n < 1)
- return null;
-
- IOUtil.configureBlocking(newfd, true);
- InetSocketAddress isa = isaa[0];
- sc = new SctpChannelImpl(provider(), newfd);
-
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkAccept(isa.getAddress().getHostAddress(),
- isa.getPort());
-
- return sc;
- }
- }
-
- @Override
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
- @Override
- public void implCloseSelectableChannel() throws IOException {
- synchronized (stateLock) {
- SctpNet.preClose(fdVal);
- if (thread != 0)
- NativeThread.signal(thread);
- if (!isRegistered())
- kill();
- }
- }
-
- @Override
- public void kill() throws IOException {
- synchronized (stateLock) {
- if (state == ChannelState.KILLED)
- return;
- if (state == ChannelState.UNINITIALIZED) {
- state = ChannelState.KILLED;
- return;
- }
- assert !isOpen() && !isRegistered();
-
- // Postpone the kill if there is a thread in accept
- if (thread == 0) {
- SctpNet.close(fdVal);
- state = ChannelState.KILLED;
- } else {
- state = ChannelState.KILLPENDING;
- }
- }
- }
-
- @Override
- public FileDescriptor getFD() {
- return fd;
- }
-
- @Override
- public int getFDVal() {
- return fdVal;
- }
-
- /**
- * Translates native poll revent ops into a ready operation ops
- */
- private boolean translateReadyOps(int ops, int initialOps,
- SelectionKeyImpl sk) {
- int intOps = sk.nioInterestOps();
- int oldOps = sk.nioReadyOps();
- int newOps = initialOps;
-
- if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
- /* This should only happen if this channel is pre-closed while a
- * selection operation is in progress
- * ## Throw an error if this channel has not been pre-closed */
- return false;
- }
-
- if ((ops & (PollArrayWrapper.POLLERR
- | PollArrayWrapper.POLLHUP)) != 0) {
- newOps = intOps;
- sk.nioReadyOps(newOps);
- return (newOps & ~oldOps) != 0;
- }
-
- if (((ops & PollArrayWrapper.POLLIN) != 0) &&
- ((intOps & SelectionKey.OP_ACCEPT) != 0))
- newOps |= SelectionKey.OP_ACCEPT;
-
- sk.nioReadyOps(newOps);
- return (newOps & ~oldOps) != 0;
- }
-
- @Override
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, sk.nioReadyOps(), sk);
- }
-
- @Override
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
- return translateReadyOps(ops, 0, sk);
- }
-
- @Override
- public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
- int newOps = 0;
-
- /* Translate ops */
- if ((ops & SelectionKey.OP_ACCEPT) != 0)
- newOps |= PollArrayWrapper.POLLIN;
- /* Place ops into pollfd array */
- sk.selector.putEventOps(sk, newOps);
-
- }
-
- @Override
- public <T> SctpServerChannel setOption(SctpSocketOption<T> name, T value)
- throws IOException {
- if (name == null)
- throw new NullPointerException();
- if (!supportedOptions().contains(name))
- throw new UnsupportedOperationException("'" + name + "' not supported");
-
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
-
- SctpNet.setSocketOption(fdVal, name, value, 0 /*oneToOne*/);
- return this;
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T> T getOption(SctpSocketOption<T> name) throws IOException {
- if (name == null)
- throw new NullPointerException();
- if (!supportedOptions().contains(name))
- throw new UnsupportedOperationException("'" + name + "' not supported");
-
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
-
- return (T) SctpNet.getSocketOption(fdVal, name, 0 /*oneToOne*/);
- }
- }
-
- private static class DefaultOptionsHolder {
- static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
-
- private static Set<SctpSocketOption<?>> defaultOptions() {
- HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(1);
- set.add(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS);
- return Collections.unmodifiableSet(set);
- }
- }
-
- @Override
- public final Set<SctpSocketOption<?>> supportedOptions() {
- return DefaultOptionsHolder.defaultOptions;
- }
-
- @Override
- public Set<SocketAddress> getAllLocalAddresses()
- throws IOException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- return Collections.emptySet();
-
- return SctpNet.getLocalAddresses(fdVal);
- }
- }
-
- /* Native */
- private static native void initIDs();
-
- private static native int accept0(FileDescriptor ssfd,
- FileDescriptor newfd, InetSocketAddress[] isaa) throws IOException;
-
- static {
- Util.load(); // loads nio & net native libraries
- java.security.AccessController.doPrivileged(
- new sun.security.action.LoadLibraryAction("sctp"));
- initIDs();
- }
-}
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpShutdown.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.ShutdownNotification;
-
-/**
- * An implementation of ShutdownNotification
- */
-public class SctpShutdown extends ShutdownNotification
- implements SctpNotification
-{
- private Association association;
- /* assocId is used to lookup the association before the notification is
- * returned to user code */
- private int assocId;
-
- /* Invoked from native */
- private SctpShutdown(int assocId) {
- this.assocId = assocId;
- }
-
- @Override
- public int assocId() {
- return assocId;
- }
-
- @Override
- public void setAssociation(Association association) {
- this.association = association;
- }
-
- @Override
- public Association association() {
- assert association != null;
- return association;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(super.toString()).append(" [");
- sb.append("Association:").append(association).append("]");
- return sb.toString();
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/AssociationChange.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.AssociationChangeNotification;
+
+/**
+ * An implementation of AssociationChangeNotification
+ */
+public class AssociationChange extends AssociationChangeNotification
+ implements SctpNotification
+{
+ /* static final ints so that they can be referenced from native */
+ private final static int SCTP_COMM_UP = 1;
+ private final static int SCTP_COMM_LOST = 2;
+ private final static int SCTP_RESTART = 3;
+ private final static int SCTP_SHUTDOWN = 4;
+ private final static int SCTP_CANT_START = 5;
+
+ private Association association;
+
+ /* assocId is used to lookup the association before the notification is
+ * returned to user code */
+ private int assocId;
+ private AssocChangeEvent event;
+ private int maxOutStreams;
+ private int maxInStreams;
+
+ /* Invoked from native */
+ private AssociationChange(int assocId,
+ int intEvent,
+ int maxOutStreams,
+ int maxInStreams) {
+ switch (intEvent) {
+ case SCTP_COMM_UP :
+ this.event = AssocChangeEvent.COMM_UP;
+ break;
+ case SCTP_COMM_LOST :
+ this.event = AssocChangeEvent.COMM_LOST;
+ break;
+ case SCTP_RESTART :
+ this.event = AssocChangeEvent.RESTART;
+ break;
+ case SCTP_SHUTDOWN :
+ this.event = AssocChangeEvent.SHUTDOWN;
+ break;
+ case SCTP_CANT_START :
+ this.event = AssocChangeEvent.CANT_START;
+ break;
+ default :
+ throw new AssertionError(
+ "Unknown Association Change Event type: " + intEvent);
+ }
+
+ this.assocId = assocId;
+ this.maxOutStreams = maxOutStreams;
+ this.maxInStreams = maxInStreams;
+ }
+
+ @Override
+ public int assocId() {
+ return assocId;
+ }
+
+ @Override
+ public void setAssociation(Association association) {
+ this.association = association;
+ }
+
+ @Override
+ public Association association() {
+ assert association != null;
+ return association;
+ }
+
+ @Override
+ public AssocChangeEvent event() {
+ return event;
+ }
+
+ int maxOutStreams() {
+ return maxOutStreams;
+ }
+
+ int maxInStreams() {
+ return maxInStreams;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString()).append(" [");
+ sb.append("Association:").append(association);
+ sb.append(", Event: ").append(event).append("]");
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/AssociationImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import com.sun.nio.sctp.Association;
+
+/**
+ * An implementation of Association
+ */
+public class AssociationImpl extends Association {
+ public AssociationImpl(int associationID,
+ int maxInStreams,
+ int maxOutStreams) {
+ super(associationID, maxInStreams, maxOutStreams);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer(super.toString());
+ return sb.append("[associationID:")
+ .append(associationID())
+ .append(", maxIn:")
+ .append(maxInboundStreams())
+ .append(", maxOut:")
+ .append(maxOutboundStreams())
+ .append("]")
+ .toString();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/PeerAddrChange.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.PeerAddressChangeNotification;
+
+/**
+ * An implementation of PeerAddressChangeNotification
+ */
+public class PeerAddrChange extends PeerAddressChangeNotification
+ implements SctpNotification
+{
+ /* static final ints so that they can be referenced from native */
+ private final static int SCTP_ADDR_AVAILABLE = 1;
+ private final static int SCTP_ADDR_UNREACHABLE = 2;
+ private final static int SCTP_ADDR_REMOVED = 3;
+ private final static int SCTP_ADDR_ADDED = 4;
+ private final static int SCTP_ADDR_MADE_PRIM = 5;
+ private final static int SCTP_ADDR_CONFIRMED =6;
+
+ private Association association;
+
+ /* assocId is used to lookup the association before the notification is
+ * returned to user code */
+ private int assocId;
+ private SocketAddress address;
+ private AddressChangeEvent event;
+
+ /* Invoked from native */
+ private PeerAddrChange(int assocId, SocketAddress address, int intEvent) {
+ switch (intEvent) {
+ case SCTP_ADDR_AVAILABLE :
+ this.event = AddressChangeEvent.ADDR_AVAILABLE;
+ break;
+ case SCTP_ADDR_UNREACHABLE :
+ this.event = AddressChangeEvent.ADDR_UNREACHABLE;
+ break;
+ case SCTP_ADDR_REMOVED :
+ this.event = AddressChangeEvent.ADDR_REMOVED;
+ break;
+ case SCTP_ADDR_ADDED :
+ this.event = AddressChangeEvent.ADDR_ADDED;
+ break;
+ case SCTP_ADDR_MADE_PRIM :
+ this.event = AddressChangeEvent.ADDR_MADE_PRIMARY;
+ break;
+ case SCTP_ADDR_CONFIRMED :
+ this.event = AddressChangeEvent.ADDR_CONFIRMED;
+ break;
+ default:
+ throw new AssertionError("Unknown event type");
+ }
+ this.assocId = assocId;
+ this.address = address;
+ }
+
+ @Override
+ public int assocId() {
+ return assocId;
+ }
+
+ @Override
+ public void setAssociation(Association association) {
+ this.association = association;
+ }
+
+ @Override
+ public SocketAddress address() {
+ assert address != null;
+ return address;
+ }
+
+ @Override
+ public Association association() {
+ assert association != null;
+ return association;
+ }
+
+ @Override
+ public AddressChangeEvent event() {
+ assert event != null;
+ return event;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString()).append(" [");
+ sb.append("Address: ").append(address);
+ sb.append(", Association:").append(association);
+ sb.append(", Event: ").append(event).append("]");
+ return sb.toString();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/ResultContainer.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+/**
+ * Wraps the actual message or notification so that it can be
+ * set and returned from the native receive implementation.
+ */
+public class ResultContainer {
+ /* static final ints so that they can be referenced from native */
+ static final int NOTHING = 0;
+ static final int MESSAGE = 1;
+ static final int SEND_FAILED = 2;
+ static final int ASSOCIATION_CHANGED = 3;
+ static final int PEER_ADDRESS_CHANGED = 4;
+ static final int SHUTDOWN = 5;
+
+ private Object value;
+ private int type;
+
+ int type() {
+ return type;
+ }
+
+ boolean hasSomething() {
+ return type() != NOTHING;
+ }
+
+ boolean isNotification() {
+ return type() != MESSAGE && type() != NOTHING ? true : false;
+ }
+
+ void clear() {
+ type = NOTHING;
+ value = null;
+ }
+
+ SctpNotification notification() {
+ assert type() != MESSAGE && type() != NOTHING;
+
+ return (SctpNotification) value;
+ }
+
+ MessageInfoImpl getMessageInfo() {
+ assert type() == MESSAGE;
+
+ if (value instanceof MessageInfoImpl)
+ return (MessageInfoImpl) value;
+
+ return null;
+ }
+
+ SendFailed getSendFailed() {
+ assert type() == SEND_FAILED;
+
+ if (value instanceof SendFailed)
+ return (SendFailed) value;
+
+ return null;
+ }
+
+ AssociationChange getAssociationChanged() {
+ assert type() == ASSOCIATION_CHANGED;
+
+ if (value instanceof AssociationChange)
+ return (AssociationChange) value;
+
+ return null;
+ }
+
+ PeerAddrChange getPeerAddressChanged() {
+ assert type() == PEER_ADDRESS_CHANGED;
+
+ if (value instanceof PeerAddrChange)
+ return (PeerAddrChange) value;
+
+ return null;
+ }
+
+ Shutdown getShutdown() {
+ assert type() == SHUTDOWN;
+
+ if (value instanceof Shutdown)
+ return (Shutdown) value;
+
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Type: ");
+ switch (type) {
+ case NOTHING: sb.append("NOTHING"); break;
+ case MESSAGE: sb.append("MESSAGE"); break;
+ case SEND_FAILED: sb.append("SEND FAILED"); break;
+ case ASSOCIATION_CHANGED: sb.append("ASSOCIATION CHANGE"); break;
+ case PEER_ADDRESS_CHANGED: sb.append("PEER ADDRESS CHANGE"); break;
+ case SHUTDOWN: sb.append("SHUTDOWN"); break;
+ default : sb.append("Unknown result type");
+ }
+ sb.append(", Value: ");
+ sb.append((value == null) ? "null" : value.toString());
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,1106 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.InetSocketAddress;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.HashSet;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ConnectionPendingException;
+import java.nio.channels.NoConnectionPendingException;
+import java.nio.channels.AlreadyConnectedException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.NotYetConnectedException;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.AbstractNotificationHandler;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.AssociationChangeNotification;
+import com.sun.nio.sctp.HandlerResult;
+import com.sun.nio.sctp.IllegalReceiveException;
+import com.sun.nio.sctp.InvalidStreamException;
+import com.sun.nio.sctp.IllegalUnbindException;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.NotificationHandler;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+import sun.nio.ch.DirectBuffer;
+import sun.nio.ch.IOStatus;
+import sun.nio.ch.IOUtil;
+import sun.nio.ch.NativeThread;
+import sun.nio.ch.Net;
+import sun.nio.ch.PollArrayWrapper;
+import sun.nio.ch.SelChImpl;
+import sun.nio.ch.SelectionKeyImpl;
+import sun.nio.ch.Util;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
+import static sun.nio.ch.sctp.ResultContainer.SEND_FAILED;
+import static sun.nio.ch.sctp.ResultContainer.ASSOCIATION_CHANGED;
+import static sun.nio.ch.sctp.ResultContainer.PEER_ADDRESS_CHANGED;
+import static sun.nio.ch.sctp.ResultContainer.SHUTDOWN;
+
+/**
+ * An implementation of an SctpChannel
+ */
+public class SctpChannelImpl extends SctpChannel
+ implements SelChImpl
+{
+ private final FileDescriptor fd;
+
+ private final int fdVal;
+
+ /* IDs of native threads doing send and receivess, for signalling */
+ private volatile long receiverThread = 0;
+ private volatile long senderThread = 0;
+
+ /* Lock held by current receiving or connecting thread */
+ private final Object receiveLock = new Object();
+
+ /* Lock held by current sending or connecting thread */
+ private final Object sendLock = new Object();
+
+ private final ThreadLocal<Boolean> receiveInvoked =
+ new ThreadLocal<Boolean>() {
+ @Override protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ /* Lock held by any thread that modifies the state fields declared below
+ DO NOT invoke a blocking I/O operation while holding this lock! */
+ private final Object stateLock = new Object();
+
+ private enum ChannelState {
+ UNINITIALIZED,
+ UNCONNECTED,
+ PENDING,
+ CONNECTED,
+ KILLPENDING,
+ KILLED,
+ }
+ /* -- The following fields are protected by stateLock -- */
+ private ChannelState state = ChannelState.UNINITIALIZED;
+
+ /* Binding; Once bound the port will remain constant. */
+ int port = -1;
+ private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
+ /* Has the channel been bound to the wildcard address */
+ private boolean wildcard; /* false */
+ //private InetSocketAddress remoteAddress = null;
+
+ /* Input/Output open */
+ private boolean readyToConnect;
+
+ /* Shutdown */
+ private boolean isShutdown;
+
+ private Association association;
+
+ private Set<SocketAddress> remoteAddresses = Collections.emptySet();
+
+ /* -- End of fields protected by stateLock -- */
+
+ /**
+ * Constructor for normal connecting sockets
+ */
+ public SctpChannelImpl(SelectorProvider provider) throws IOException {
+ //TODO: update provider remove public modifier
+ super(provider);
+ this.fd = SctpNet.socket(true);
+ this.fdVal = IOUtil.fdVal(fd);
+ this.state = ChannelState.UNCONNECTED;
+ }
+
+ /**
+ * Constructor for sockets obtained from server sockets
+ */
+ public SctpChannelImpl(SelectorProvider provider, FileDescriptor fd)
+ throws IOException {
+ this(provider, fd, null);
+ }
+
+ /**
+ * Constructor for sockets obtained from branching
+ */
+ public SctpChannelImpl(SelectorProvider provider,
+ FileDescriptor fd,
+ Association association)
+ throws IOException {
+ super(provider);
+ this.fd = fd;
+ this.fdVal = IOUtil.fdVal(fd);
+ this.state = ChannelState.CONNECTED;
+ port = (Net.localAddress(fd)).getPort();
+
+ if (association != null) { /* branched */
+ this.association = association;
+ } else { /* obtained from server channel */
+ /* Receive COMM_UP */
+ ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
+ try {
+ receive(buf, null, null, true);
+ } finally {
+ Util.releaseTemporaryDirectBuffer(buf);
+ }
+ }
+ }
+
+ /**
+ * Binds the channel's socket to a local address.
+ */
+ @Override
+ public SctpChannel bind(SocketAddress local) throws IOException {
+ synchronized (receiveLock) {
+ synchronized (sendLock) {
+ synchronized (stateLock) {
+ ensureOpenAndUnconnected();
+ if (isBound())
+ SctpNet.throwAlreadyBoundException();
+ InetSocketAddress isa = (local == null) ?
+ new InetSocketAddress(0) : Net.checkAddress(local);
+ Net.bind(fd, isa.getAddress(), isa.getPort());
+ InetSocketAddress boundIsa = Net.localAddress(fd);
+ port = boundIsa.getPort();
+ localAddresses.add(isa);
+ if (isa.getAddress().isAnyLocalAddress())
+ wildcard = true;
+ }
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public SctpChannel bindAddress(InetAddress address)
+ throws IOException {
+ bindUnbindAddress(address, true);
+ localAddresses.add(new InetSocketAddress(address, port));
+ return this;
+ }
+
+ @Override
+ public SctpChannel unbindAddress(InetAddress address)
+ throws IOException {
+ bindUnbindAddress(address, false);
+ localAddresses.remove(new InetSocketAddress(address, port));
+ return this;
+ }
+
+ private SctpChannel bindUnbindAddress(InetAddress address, boolean add)
+ throws IOException {
+ if (address == null)
+ throw new IllegalArgumentException();
+
+ synchronized (receiveLock) {
+ synchronized (sendLock) {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ throw new NotYetBoundException();
+ if (wildcard)
+ throw new IllegalStateException(
+ "Cannot add or remove addresses from a channel that is bound to the wildcard address");
+ if (address.isAnyLocalAddress())
+ throw new IllegalArgumentException(
+ "Cannot add or remove the wildcard address");
+ if (add) {
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ SctpNet.throwAlreadyBoundException();
+ }
+ }
+ } else { /*removing */
+ /* Verify that there is more than one address
+ * and that address is already bound */
+ if (localAddresses.size() <= 1)
+ throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
+ boolean foundAddress = false;
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ foundAddress = true;
+ break;
+ }
+ }
+ if (!foundAddress )
+ throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
+ }
+
+ SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
+
+ /* Update our internal Set to reflect the addition/removal */
+ if (add)
+ localAddresses.add(new InetSocketAddress(address, port));
+ else {
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ localAddresses.remove(addr);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return this;
+ }
+
+ private boolean isBound() {
+ synchronized (stateLock) {
+ return port == -1 ? false : true;
+ }
+ }
+
+ private boolean isConnected() {
+ synchronized (stateLock) {
+ return (state == ChannelState.CONNECTED);
+ }
+ }
+
+ private void ensureOpenAndUnconnected() throws IOException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (isConnected())
+ throw new AlreadyConnectedException();
+ if (state == ChannelState.PENDING)
+ throw new ConnectionPendingException();
+ }
+ }
+
+ private boolean ensureReceiveOpen() throws ClosedChannelException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isConnected())
+ throw new NotYetConnectedException();
+ else
+ return true;
+ }
+ }
+
+ private void ensureSendOpen() throws ClosedChannelException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (isShutdown)
+ throw new ClosedChannelException();
+ if (!isConnected())
+ throw new NotYetConnectedException();
+ }
+ }
+
+ private void receiverCleanup() throws IOException {
+ synchronized (stateLock) {
+ receiverThread = 0;
+ if (state == ChannelState.KILLPENDING)
+ kill();
+ }
+ }
+
+ private void senderCleanup() throws IOException {
+ synchronized (stateLock) {
+ senderThread = 0;
+ if (state == ChannelState.KILLPENDING)
+ kill();
+ }
+ }
+
+ @Override
+ public Association association() throws ClosedChannelException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isConnected())
+ return null;
+
+ return association;
+ }
+ }
+
+ @Override
+ public boolean connect(SocketAddress endpoint) throws IOException {
+ synchronized (receiveLock) {
+ synchronized (sendLock) {
+ ensureOpenAndUnconnected();
+ InetSocketAddress isa = Net.checkAddress(endpoint);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(isa.getAddress().getHostAddress(),
+ isa.getPort());
+ synchronized (blockingLock()) {
+ int n = 0;
+ try {
+ try {
+ begin();
+ synchronized (stateLock) {
+ if (!isOpen()) {
+ return false;
+ }
+ receiverThread = NativeThread.current();
+ }
+ for (;;) {
+ InetAddress ia = isa.getAddress();
+ if (ia.isAnyLocalAddress())
+ ia = InetAddress.getLocalHost();
+ n = SctpNet.connect(fdVal, ia, isa.getPort());
+ if ( (n == IOStatus.INTERRUPTED)
+ && isOpen())
+ continue;
+ break;
+ }
+ } finally {
+ receiverCleanup();
+ end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ assert IOStatus.check(n);
+ }
+ } catch (IOException x) {
+ /* If an exception was thrown, close the channel after
+ * invoking end() so as to avoid bogus
+ * AsynchronousCloseExceptions */
+ close();
+ throw x;
+ }
+
+ if (n > 0) {
+ synchronized (stateLock) {
+ /* Connection succeeded */
+ state = ChannelState.CONNECTED;
+ if (!isBound()) {
+ InetSocketAddress boundIsa =
+ Net.localAddress(fd);
+ port = boundIsa.getPort();
+ }
+
+ /* Receive COMM_UP */
+ ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
+ try {
+ receive(buf, null, null, true);
+ } finally {
+ Util.releaseTemporaryDirectBuffer(buf);
+ }
+
+ /* cache remote addresses */
+ try {
+ remoteAddresses = getRemoteAddresses();
+ } catch (IOException unused) { /* swallow exception */ }
+
+ return true;
+ }
+ } else {
+ synchronized (stateLock) {
+ /* If nonblocking and no exception then connection
+ * pending; disallow another invocation */
+ if (!isBlocking())
+ state = ChannelState.PENDING;
+ else
+ assert false;
+ }
+ }
+ }
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean connect(SocketAddress endpoint,
+ int maxOutStreams,
+ int maxInStreams)
+ throws IOException {
+ ensureOpenAndUnconnected();
+ return setOption(SCTP_INIT_MAXSTREAMS, InitMaxStreams.
+ create(maxInStreams, maxOutStreams)).connect(endpoint);
+
+ }
+
+ @Override
+ public boolean isConnectionPending() {
+ synchronized (stateLock) {
+ return (state == ChannelState.PENDING);
+ }
+ }
+
+ @Override
+ public boolean finishConnect() throws IOException {
+ synchronized (receiveLock) {
+ synchronized (sendLock) {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (isConnected())
+ return true;
+ if (state != ChannelState.PENDING)
+ throw new NoConnectionPendingException();
+ }
+ int n = 0;
+ try {
+ try {
+ begin();
+ synchronized (blockingLock()) {
+ synchronized (stateLock) {
+ if (!isOpen()) {
+ return false;
+ }
+ receiverThread = NativeThread.current();
+ }
+ if (!isBlocking()) {
+ for (;;) {
+ n = checkConnect(fd, false, readyToConnect);
+ if ( (n == IOStatus.INTERRUPTED)
+ && isOpen())
+ continue;
+ break;
+ }
+ } else {
+ for (;;) {
+ n = checkConnect(fd, true, readyToConnect);
+ if (n == 0) {
+ // Loop in case of
+ // spurious notifications
+ continue;
+ }
+ if ( (n == IOStatus.INTERRUPTED)
+ && isOpen())
+ continue;
+ break;
+ }
+ }
+ }
+ } finally {
+ synchronized (stateLock) {
+ receiverThread = 0;
+ if (state == ChannelState.KILLPENDING) {
+ kill();
+ /* poll()/getsockopt() does not report
+ * error (throws exception, with n = 0)
+ * on Linux platform after dup2 and
+ * signal-wakeup. Force n to 0 so the
+ * end() can throw appropriate exception */
+ n = 0;
+ }
+ }
+ end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ assert IOStatus.check(n);
+ }
+ } catch (IOException x) {
+ /* If an exception was thrown, close the channel after
+ * invoking end() so as to avoid bogus
+ * AsynchronousCloseExceptions */
+ close();
+ throw x;
+ }
+
+ if (n > 0) {
+ synchronized (stateLock) {
+ state = ChannelState.CONNECTED;
+ if (!isBound()) {
+ InetSocketAddress boundIsa =
+ Net.localAddress(fd);
+ port = boundIsa.getPort();
+ }
+
+ /* Receive COMM_UP */
+ ByteBuffer buf = Util.getTemporaryDirectBuffer(50);
+ try {
+ receive(buf, null, null, true);
+ } finally {
+ Util.releaseTemporaryDirectBuffer(buf);
+ }
+
+ /* cache remote addresses */
+ try {
+ remoteAddresses = getRemoteAddresses();
+ } catch (IOException unused) { /* swallow exception */ }
+
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ IOUtil.configureBlocking(fd, block);
+ }
+
+ @Override
+ public void implCloseSelectableChannel() throws IOException {
+ synchronized (stateLock) {
+ SctpNet.preClose(fdVal);
+
+ if (receiverThread != 0)
+ NativeThread.signal(receiverThread);
+
+ if (senderThread != 0)
+ NativeThread.signal(senderThread);
+
+ if (!isRegistered())
+ kill();
+ }
+ }
+
+ @Override
+ public FileDescriptor getFD() {
+ return fd;
+ }
+
+ @Override
+ public int getFDVal() {
+ return fdVal;
+ }
+
+ /**
+ * Translates native poll revent ops into a ready operation ops
+ */
+ private boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl sk) {
+ int intOps = sk.nioInterestOps();
+ int oldOps = sk.nioReadyOps();
+ int newOps = initialOps;
+
+ if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
+ /* This should only happen if this channel is pre-closed while a
+ * selection operation is in progress
+ * ## Throw an error if this channel has not been pre-closed */
+ return false;
+ }
+
+ if ((ops & (PollArrayWrapper.POLLERR
+ | PollArrayWrapper.POLLHUP)) != 0) {
+ newOps = intOps;
+ sk.nioReadyOps(newOps);
+ /* No need to poll again in checkConnect,
+ * the error will be detected there */
+ readyToConnect = true;
+ return (newOps & ~oldOps) != 0;
+ }
+
+ if (((ops & PollArrayWrapper.POLLIN) != 0) &&
+ ((intOps & SelectionKey.OP_READ) != 0) &&
+ isConnected())
+ newOps |= SelectionKey.OP_READ;
+
+ if (((ops & PollArrayWrapper.POLLCONN) != 0) &&
+ ((intOps & SelectionKey.OP_CONNECT) != 0) &&
+ ((state == ChannelState.UNCONNECTED) || (state == ChannelState.PENDING))) {
+ newOps |= SelectionKey.OP_CONNECT;
+ readyToConnect = true;
+ }
+
+ if (((ops & PollArrayWrapper.POLLOUT) != 0) &&
+ ((intOps & SelectionKey.OP_WRITE) != 0) &&
+ isConnected())
+ newOps |= SelectionKey.OP_WRITE;
+
+ sk.nioReadyOps(newOps);
+ return (newOps & ~oldOps) != 0;
+ }
+
+ @Override
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
+ return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ }
+
+ @Override
+ @SuppressWarnings("all")
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
+ return translateReadyOps(ops, 0, sk);
+ }
+
+ @Override
+ public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ int newOps = 0;
+ if ((ops & SelectionKey.OP_READ) != 0)
+ newOps |= PollArrayWrapper.POLLIN;
+ if ((ops & SelectionKey.OP_WRITE) != 0)
+ newOps |= PollArrayWrapper.POLLOUT;
+ if ((ops & SelectionKey.OP_CONNECT) != 0)
+ newOps |= PollArrayWrapper.POLLCONN;
+ sk.selector.putEventOps(sk, newOps);
+ }
+
+ @Override
+ public void kill() throws IOException {
+ synchronized (stateLock) {
+ if (state == ChannelState.KILLED)
+ return;
+ if (state == ChannelState.UNINITIALIZED) {
+ state = ChannelState.KILLED;
+ return;
+ }
+ assert !isOpen() && !isRegistered();
+
+ /* Postpone the kill if there is a waiting reader
+ * or writer thread. */
+ if (receiverThread == 0 && senderThread == 0) {
+ SctpNet.close(fdVal);
+ state = ChannelState.KILLED;
+ } else {
+ state = ChannelState.KILLPENDING;
+ }
+ }
+ }
+
+ @Override
+ public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
+ throws IOException {
+ if (name == null)
+ throw new NullPointerException();
+ if (!supportedOptions().contains(name))
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ SctpNet.setSocketOption(fdVal, name, value, 0 /*oneToOne*/);
+ }
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T> T getOption(SctpSocketOption<T> name) throws IOException {
+ if (name == null)
+ throw new NullPointerException();
+ if (!supportedOptions().contains(name))
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ return (T)SctpNet.getSocketOption(fdVal, name, 0 /*oneToOne*/);
+ }
+ }
+
+ private static class DefaultOptionsHolder {
+ static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
+
+ private static Set<SctpSocketOption<?>> defaultOptions() {
+ HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(10);
+ set.add(SCTP_DISABLE_FRAGMENTS);
+ set.add(SCTP_EXPLICIT_COMPLETE);
+ set.add(SCTP_FRAGMENT_INTERLEAVE);
+ set.add(SCTP_INIT_MAXSTREAMS);
+ set.add(SCTP_NODELAY);
+ set.add(SCTP_PRIMARY_ADDR);
+ set.add(SCTP_SET_PEER_PRIMARY_ADDR);
+ set.add(SO_SNDBUF);
+ set.add(SO_RCVBUF);
+ set.add(SO_LINGER);
+ return Collections.unmodifiableSet(set);
+ }
+ }
+
+ @Override
+ public final Set<SctpSocketOption<?>> supportedOptions() {
+ return DefaultOptionsHolder.defaultOptions;
+ }
+
+ @Override
+ public <T> MessageInfo receive(ByteBuffer buffer,
+ T attachment,
+ NotificationHandler<T> handler)
+ throws IOException {
+ return receive(buffer, attachment, handler, false);
+ }
+
+ private <T> MessageInfo receive(ByteBuffer buffer,
+ T attachment,
+ NotificationHandler<T> handler,
+ boolean fromConnect)
+ throws IOException {
+ if (buffer == null)
+ throw new IllegalArgumentException("buffer cannot be null");
+
+ if (buffer.isReadOnly())
+ throw new IllegalArgumentException("Read-only buffer");
+
+ if (receiveInvoked.get())
+ throw new IllegalReceiveException(
+ "cannot invoke receive from handler");
+ receiveInvoked.set(Boolean.TRUE);
+
+ try {
+ ResultContainer resultContainer = new ResultContainer();
+ do {
+ resultContainer.clear();
+ synchronized (receiveLock) {
+ if (!ensureReceiveOpen())
+ return null;
+
+ int n = 0;
+ try {
+ begin();
+
+ synchronized (stateLock) {
+ if(!isOpen())
+ return null;
+ receiverThread = NativeThread.current();
+ }
+
+ do {
+ n = receive(fdVal, buffer, resultContainer, fromConnect);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+ } finally {
+ receiverCleanup();
+ end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ assert IOStatus.check(n);
+ }
+
+ if (!resultContainer.isNotification()) {
+ /* message or nothing */
+ if (resultContainer.hasSomething()) {
+ /* Set the association before returning */
+ MessageInfoImpl info =
+ resultContainer.getMessageInfo();
+ synchronized (stateLock) {
+ assert association != null;
+ info.setAssociation(association);
+ }
+ return info;
+ } else
+ /* Non-blocking may return null if nothing available*/
+ return null;
+ } else { /* notification */
+ synchronized (stateLock) {
+ handleNotificationInternal(
+ resultContainer);
+ }
+ }
+
+ if (fromConnect) {
+ /* If we reach here, then it was connect that invoked
+ * receive and received the COMM_UP. We have already
+ * handled the COMM_UP with the internal notification
+ * handler. Simply return. */
+ return null;
+ }
+ } /* receiveLock */
+ } while (handler == null ? true :
+ (invokeNotificationHandler(resultContainer, handler, attachment)
+ == HandlerResult.CONTINUE));
+
+ return null;
+ } finally {
+ receiveInvoked.set(Boolean.FALSE);
+ }
+ }
+
+ private int receive(int fd,
+ ByteBuffer dst,
+ ResultContainer resultContainer,
+ boolean peek)
+ throws IOException {
+ int pos = dst.position();
+ int lim = dst.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (dst instanceof DirectBuffer && rem > 0)
+ return receiveIntoNativeBuffer(fd, resultContainer, dst, rem, pos, peek);
+
+ /* Substitute a native buffer */
+ int newSize = Math.max(rem, 1);
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
+ try {
+ int n = receiveIntoNativeBuffer(fd, resultContainer, bb, newSize, 0, peek);
+ bb.flip();
+ if (n > 0 && rem > 0)
+ dst.put(bb);
+ return n;
+ } finally {
+ Util.releaseTemporaryDirectBuffer(bb);
+ }
+ }
+
+ private int receiveIntoNativeBuffer(int fd,
+ ResultContainer resultContainer,
+ ByteBuffer bb,
+ int rem,
+ int pos,
+ boolean peek)
+ throws IOException
+ {
+ int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem, peek);
+
+ if (n > 0)
+ bb.position(pos + n);
+ return n;
+ }
+
+ private InternalNotificationHandler internalNotificationHandler =
+ new InternalNotificationHandler();
+
+ private void handleNotificationInternal(ResultContainer resultContainer)
+ {
+ invokeNotificationHandler(resultContainer,
+ internalNotificationHandler, null);
+ }
+
+ private class InternalNotificationHandler
+ extends AbstractNotificationHandler<Object>
+ {
+ @Override
+ public HandlerResult handleNotification(
+ AssociationChangeNotification not, Object unused) {
+ if (not.event().equals(
+ AssociationChangeNotification.AssocChangeEvent.COMM_UP) &&
+ association == null) {
+ AssociationChange sac = (AssociationChange) not;
+ association = new AssociationImpl
+ (sac.assocId(), sac.maxInStreams(), sac.maxOutStreams());
+ }
+ return HandlerResult.CONTINUE;
+ }
+ }
+
+ private <T> HandlerResult invokeNotificationHandler
+ (ResultContainer resultContainer,
+ NotificationHandler<T> handler,
+ T attachment) {
+ SctpNotification notification = resultContainer.notification();
+ synchronized (stateLock) {
+ notification.setAssociation(association);
+ }
+
+ if (!(handler instanceof AbstractNotificationHandler)) {
+ return handler.handleNotification(notification, attachment);
+ }
+
+ /* AbstractNotificationHandler */
+ AbstractNotificationHandler<T> absHandler =
+ (AbstractNotificationHandler<T>)handler;
+ switch(resultContainer.type()) {
+ case ASSOCIATION_CHANGED :
+ return absHandler.handleNotification(
+ resultContainer.getAssociationChanged(), attachment);
+ case PEER_ADDRESS_CHANGED :
+ return absHandler.handleNotification(
+ resultContainer.getPeerAddressChanged(), attachment);
+ case SEND_FAILED :
+ return absHandler.handleNotification(
+ resultContainer.getSendFailed(), attachment);
+ case SHUTDOWN :
+ return absHandler.handleNotification(
+ resultContainer.getShutdown(), attachment);
+ default :
+ /* implementation specific handlers */
+ return absHandler.handleNotification(
+ resultContainer.notification(), attachment);
+ }
+ }
+
+ private void checkAssociation(Association sendAssociation) {
+ synchronized (stateLock) {
+ if (sendAssociation != null && !sendAssociation.equals(association)) {
+ throw new IllegalArgumentException(
+ "Cannot send to another association");
+ }
+ }
+ }
+
+ private void checkStreamNumber(int streamNumber) {
+ synchronized (stateLock) {
+ if (association != null) {
+ if (streamNumber < 0 ||
+ streamNumber >= association.maxOutboundStreams())
+ throw new InvalidStreamException();
+ }
+ }
+ }
+
+ /* TODO: Add support for ttl and isComplete to both 121 12M
+ * SCTP_EOR not yet supported on reference platforms
+ * TTL support limited...
+ */
+ @Override
+ public int send(ByteBuffer buffer, MessageInfo messageInfo)
+ throws IOException {
+ if (buffer == null)
+ throw new IllegalArgumentException("buffer cannot be null");
+
+ if (messageInfo == null)
+ throw new IllegalArgumentException("messageInfo cannot be null");
+
+ checkAssociation(messageInfo.association());
+ checkStreamNumber(messageInfo.streamNumber());
+
+ synchronized (sendLock) {
+ ensureSendOpen();
+
+ int n = 0;
+ try {
+ begin();
+
+ synchronized (stateLock) {
+ if(!isOpen())
+ return 0;
+ senderThread = NativeThread.current();
+ }
+
+ do {
+ n = send(fdVal, buffer, messageInfo);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+
+ return IOStatus.normalize(n);
+ } finally {
+ senderCleanup();
+ end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ assert IOStatus.check(n);
+ }
+ }
+ }
+
+ private int send(int fd, ByteBuffer src, MessageInfo messageInfo)
+ throws IOException {
+ int streamNumber = messageInfo.streamNumber();
+ SocketAddress target = messageInfo.address();
+ boolean unordered = messageInfo.isUnordered();
+ int ppid = messageInfo.payloadProtocolID();
+
+ if (src instanceof DirectBuffer)
+ return sendFromNativeBuffer(fd, src, target, streamNumber,
+ unordered, ppid);
+
+ /* Substitute a native buffer */
+ int pos = src.position();
+ int lim = src.limit();
+ assert (pos <= lim && streamNumber >= 0);
+
+ int rem = (pos <= lim ? lim - pos : 0);
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
+ try {
+ bb.put(src);
+ bb.flip();
+ /* Do not update src until we see how many bytes were written */
+ src.position(pos);
+
+ int n = sendFromNativeBuffer(fd, bb, target, streamNumber,
+ unordered, ppid);
+ if (n > 0) {
+ /* now update src */
+ src.position(pos + n);
+ }
+ return n;
+ } finally {
+ Util.releaseTemporaryDirectBuffer(bb);
+ }
+ }
+
+ private int sendFromNativeBuffer(int fd,
+ ByteBuffer bb,
+ SocketAddress target,
+ int streamNumber,
+ boolean unordered,
+ int ppid)
+ throws IOException {
+ int pos = bb.position();
+ int lim = bb.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+
+ int written = send0(fd, ((DirectBuffer)bb).address() + pos,
+ rem, target, -1 /*121*/, streamNumber, unordered, ppid);
+ if (written > 0)
+ bb.position(pos + written);
+ return written;
+ }
+
+ @Override
+ public SctpChannel shutdown() throws IOException {
+ synchronized(stateLock) {
+ if (isShutdown)
+ return this;
+
+ ensureSendOpen();
+ SctpNet.shutdown(fdVal, -1);
+ if (senderThread != 0)
+ NativeThread.signal(senderThread);
+ isShutdown = true;
+ }
+ return this;
+ }
+
+ @Override
+ public Set<SocketAddress> getAllLocalAddresses()
+ throws IOException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ return Collections.emptySet();
+
+ return SctpNet.getLocalAddresses(fdVal);
+ }
+ }
+
+ @Override
+ public Set<SocketAddress> getRemoteAddresses()
+ throws IOException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isConnected() || isShutdown)
+ return Collections.emptySet();
+
+ try {
+ return SctpNet.getRemoteAddresses(fdVal, 0/*unused*/);
+ } catch (SocketException unused) {
+ /* an open connected channel should always have remote addresses */
+ return remoteAddresses;
+ }
+ }
+ }
+
+ /* Native */
+ private static native void initIDs();
+
+ static native int receive0(int fd, ResultContainer resultContainer,
+ long address, int length, boolean peek) throws IOException;
+
+ static native int send0(int fd, long address, int length,
+ SocketAddress target, int assocId, int streamNumber,
+ boolean unordered, int ppid) throws IOException;
+
+ private static native int checkConnect(FileDescriptor fd, boolean block,
+ boolean ready) throws IOException;
+
+ static {
+ Util.load(); /* loads nio & net native libraries */
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.LoadLibraryAction("sctp"));
+ initIDs();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,994 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.InetSocketAddress;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map.Entry;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.AbstractNotificationHandler;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.AssociationChangeNotification;
+import com.sun.nio.sctp.HandlerResult;
+import com.sun.nio.sctp.IllegalReceiveException;
+import com.sun.nio.sctp.InvalidStreamException;
+import com.sun.nio.sctp.IllegalUnbindException;
+import com.sun.nio.sctp.NotificationHandler;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpMultiChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+import sun.nio.ch.DirectBuffer;
+import sun.nio.ch.NativeThread;
+import sun.nio.ch.IOStatus;
+import sun.nio.ch.IOUtil;
+import sun.nio.ch.Net;
+import sun.nio.ch.PollArrayWrapper;
+import sun.nio.ch.SelChImpl;
+import sun.nio.ch.SelectionKeyImpl;
+import sun.nio.ch.Util;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
+import static sun.nio.ch.sctp.ResultContainer.*;
+
+/**
+ * An implementation of SctpMultiChannel
+ */
+public class SctpMultiChannelImpl extends SctpMultiChannel
+ implements SelChImpl
+{
+ private final FileDescriptor fd;
+
+ private final int fdVal;
+
+ /* IDs of native threads doing send and receives, for signalling */
+ private volatile long receiverThread = 0;
+ private volatile long senderThread = 0;
+
+ /* Lock held by current receiving thread */
+ private final Object receiveLock = new Object();
+
+ /* Lock held by current sending thread */
+ private final Object sendLock = new Object();
+
+ /* Lock held by any thread that modifies the state fields declared below
+ * DO NOT invoke a blocking I/O operation while holding this lock! */
+ private final Object stateLock = new Object();
+
+ private enum ChannelState {
+ UNINITIALIZED,
+ KILLPENDING,
+ KILLED,
+ }
+
+ /* -- The following fields are protected by stateLock -- */
+ private ChannelState state = ChannelState.UNINITIALIZED;
+
+ /* Binding: Once bound the port will remain constant. */
+ int port = -1;
+ private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
+ /* Has the channel been bound to the wildcard address */
+ private boolean wildcard; /* false */
+
+ /* Keeps a map of addresses to association, and visa versa */
+ private HashMap<SocketAddress, Association> addressMap =
+ new HashMap<SocketAddress, Association>();
+ private HashMap<Association, Set<SocketAddress>> associationMap =
+ new HashMap<Association, Set<SocketAddress>>();
+
+ /* -- End of fields protected by stateLock -- */
+
+ /* If an association has been shutdown mark it for removal after
+ * the user handler has been invoked */
+ private final ThreadLocal<Association> associationToRemove =
+ new ThreadLocal<Association>() {
+ @Override protected Association initialValue() {
+ return null;
+ }
+ };
+
+ /* A notification handler cannot invoke receive */
+ private final ThreadLocal<Boolean> receiveInvoked =
+ new ThreadLocal<Boolean>() {
+ @Override protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ public SctpMultiChannelImpl(SelectorProvider provider)
+ throws IOException {
+ //TODO: update provider, remove public modifier
+ super(provider);
+ this.fd = SctpNet.socket(false /*one-to-many*/);
+ this.fdVal = IOUtil.fdVal(fd);
+ }
+
+ @Override
+ public SctpMultiChannel bind(SocketAddress local, int backlog)
+ throws IOException {
+ synchronized (receiveLock) {
+ synchronized (sendLock) {
+ synchronized (stateLock) {
+ ensureOpen();
+ if (isBound())
+ SctpNet.throwAlreadyBoundException();
+ InetSocketAddress isa = (local == null) ?
+ new InetSocketAddress(0) : Net.checkAddress(local);
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkListen(isa.getPort());
+ Net.bind(fd, isa.getAddress(), isa.getPort());
+
+ InetSocketAddress boundIsa = Net.localAddress(fd);
+ port = boundIsa.getPort();
+ localAddresses.add(isa);
+ if (isa.getAddress().isAnyLocalAddress())
+ wildcard = true;
+
+ SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog);
+ }
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public SctpMultiChannel bindAddress(InetAddress address)
+ throws IOException {
+ return bindUnbindAddress(address, true);
+ }
+
+ @Override
+ public SctpMultiChannel unbindAddress(InetAddress address)
+ throws IOException {
+ return bindUnbindAddress(address, false);
+ }
+
+ private SctpMultiChannel bindUnbindAddress(InetAddress address,
+ boolean add)
+ throws IOException {
+ if (address == null)
+ throw new IllegalArgumentException();
+
+ synchronized (receiveLock) {
+ synchronized (sendLock) {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ throw new NotYetBoundException();
+ if (wildcard)
+ throw new IllegalStateException(
+ "Cannot add or remove addresses from a channel that is bound to the wildcard address");
+ if (address.isAnyLocalAddress())
+ throw new IllegalArgumentException(
+ "Cannot add or remove the wildcard address");
+ if (add) {
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ SctpNet.throwAlreadyBoundException();
+ }
+ }
+ } else { /*removing */
+ /* Verify that there is more than one address
+ * and that address is already bound */
+ if (localAddresses.size() <= 1)
+ throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
+ boolean foundAddress = false;
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ foundAddress = true;
+ break;
+ }
+ }
+ if (!foundAddress )
+ throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
+ }
+
+ SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
+
+ /* Update our internal Set to reflect the addition/removal */
+ if (add)
+ localAddresses.add(new InetSocketAddress(address, port));
+ else {
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ localAddresses.remove(addr);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public Set<Association> associations()
+ throws ClosedChannelException, NotYetBoundException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ throw new NotYetBoundException();
+
+ return Collections.unmodifiableSet(associationMap.keySet());
+ }
+ }
+
+ private boolean isBound() {
+ synchronized (stateLock) {
+ return port == -1 ? false : true;
+ }
+ }
+
+ private void ensureOpen() throws IOException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ }
+ }
+
+ private void receiverCleanup() throws IOException {
+ synchronized (stateLock) {
+ receiverThread = 0;
+ if (state == ChannelState.KILLPENDING)
+ kill();
+ }
+ }
+
+ private void senderCleanup() throws IOException {
+ synchronized (stateLock) {
+ senderThread = 0;
+ if (state == ChannelState.KILLPENDING)
+ kill();
+ }
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ IOUtil.configureBlocking(fd, block);
+ }
+
+ @Override
+ public void implCloseSelectableChannel() throws IOException {
+ synchronized (stateLock) {
+ SctpNet.preClose(fdVal);
+
+ if (receiverThread != 0)
+ NativeThread.signal(receiverThread);
+
+ if (senderThread != 0)
+ NativeThread.signal(senderThread);
+
+ if (!isRegistered())
+ kill();
+ }
+ }
+
+ @Override
+ public FileDescriptor getFD() {
+ return fd;
+ }
+
+ @Override
+ public int getFDVal() {
+ return fdVal;
+ }
+
+ /**
+ * Translates native poll revent ops into a ready operation ops
+ */
+ private boolean translateReadyOps(int ops, int initialOps,
+ SelectionKeyImpl sk) {
+ int intOps = sk.nioInterestOps();
+ int oldOps = sk.nioReadyOps();
+ int newOps = initialOps;
+
+ if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
+ /* This should only happen if this channel is pre-closed while a
+ * selection operation is in progress
+ * ## Throw an error if this channel has not been pre-closed */
+ return false;
+ }
+
+ if ((ops & (PollArrayWrapper.POLLERR
+ | PollArrayWrapper.POLLHUP)) != 0) {
+ newOps = intOps;
+ sk.nioReadyOps(newOps);
+ return (newOps & ~oldOps) != 0;
+ }
+
+ if (((ops & PollArrayWrapper.POLLIN) != 0) &&
+ ((intOps & SelectionKey.OP_READ) != 0))
+ newOps |= SelectionKey.OP_READ;
+
+ if (((ops & PollArrayWrapper.POLLOUT) != 0) &&
+ ((intOps & SelectionKey.OP_WRITE) != 0))
+ newOps |= SelectionKey.OP_WRITE;
+
+ sk.nioReadyOps(newOps);
+ return (newOps & ~oldOps) != 0;
+ }
+
+ @Override
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
+ return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ }
+
+ @Override
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
+ return translateReadyOps(ops, 0, sk);
+ }
+
+ @Override
+ public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ int newOps = 0;
+ if ((ops & SelectionKey.OP_READ) != 0)
+ newOps |= PollArrayWrapper.POLLIN;
+ if ((ops & SelectionKey.OP_WRITE) != 0)
+ newOps |= PollArrayWrapper.POLLOUT;
+ sk.selector.putEventOps(sk, newOps);
+ }
+
+ @Override
+ public void kill() throws IOException {
+ synchronized (stateLock) {
+ if (state == ChannelState.KILLED)
+ return;
+ if (state == ChannelState.UNINITIALIZED) {
+ state = ChannelState.KILLED;
+ return;
+ }
+ assert !isOpen() && !isRegistered();
+
+ /* Postpone the kill if there is a thread sending or receiving. */
+ if (receiverThread == 0 && senderThread == 0) {
+ SctpNet.close(fdVal);
+ state = ChannelState.KILLED;
+ } else {
+ state = ChannelState.KILLPENDING;
+ }
+ }
+ }
+
+ @Override
+ public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
+ T value,
+ Association association)
+ throws IOException {
+ if (name == null)
+ throw new NullPointerException();
+ if (!(supportedOptions().contains(name)))
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+
+ synchronized (stateLock) {
+ if (association != null && (name.equals(SCTP_PRIMARY_ADDR) ||
+ name.equals(SCTP_SET_PEER_PRIMARY_ADDR))) {
+ checkAssociation(association);
+ }
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ int assocId = association == null ? 0 : association.associationID();
+ SctpNet.setSocketOption(fdVal, name, value, assocId);
+ }
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T> T getOption(SctpSocketOption<T> name, Association association)
+ throws IOException {
+ if (name == null)
+ throw new NullPointerException();
+ if (!supportedOptions().contains(name))
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+
+ synchronized (stateLock) {
+ if (association != null && (name.equals(SCTP_PRIMARY_ADDR) ||
+ name.equals(SCTP_SET_PEER_PRIMARY_ADDR))) {
+ checkAssociation(association);
+ }
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ int assocId = association == null ? 0 : association.associationID();
+ return (T)SctpNet.getSocketOption(fdVal, name, assocId);
+ }
+ }
+
+ private static class DefaultOptionsHolder {
+ static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
+
+ private static Set<SctpSocketOption<?>> defaultOptions() {
+ HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(10);
+ set.add(SCTP_DISABLE_FRAGMENTS);
+ set.add(SCTP_EXPLICIT_COMPLETE);
+ set.add(SCTP_FRAGMENT_INTERLEAVE);
+ set.add(SCTP_INIT_MAXSTREAMS);
+ set.add(SCTP_NODELAY);
+ set.add(SCTP_PRIMARY_ADDR);
+ set.add(SCTP_SET_PEER_PRIMARY_ADDR);
+ set.add(SO_SNDBUF);
+ set.add(SO_RCVBUF);
+ set.add(SO_LINGER);
+ return Collections.unmodifiableSet(set);
+ }
+ }
+
+ @Override
+ public final Set<SctpSocketOption<?>> supportedOptions() {
+ return DefaultOptionsHolder.defaultOptions;
+ }
+
+ @Override
+ public <T> MessageInfo receive(ByteBuffer buffer,
+ T attachment,
+ NotificationHandler<T> handler)
+ throws IOException {
+ if (buffer == null)
+ throw new IllegalArgumentException("buffer cannot be null");
+
+ if (buffer.isReadOnly())
+ throw new IllegalArgumentException("Read-only buffer");
+
+ if (receiveInvoked.get())
+ throw new IllegalReceiveException(
+ "cannot invoke receive from handler");
+ receiveInvoked.set(Boolean.TRUE);
+
+ try {
+ ResultContainer resultContainer = new ResultContainer();
+ do {
+ resultContainer.clear();
+ synchronized (receiveLock) {
+ ensureOpen();
+ if (!isBound())
+ throw new NotYetBoundException();
+
+ int n = 0;
+ try {
+ begin();
+
+ synchronized (stateLock) {
+ if(!isOpen())
+ return null;
+ receiverThread = NativeThread.current();
+ }
+
+ do {
+ n = receive(fdVal, buffer, resultContainer);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+
+ } finally {
+ receiverCleanup();
+ end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ assert IOStatus.check(n);
+ }
+
+ if (!resultContainer.isNotification()) {
+ /* message or nothing */
+ if (resultContainer.hasSomething()) {
+ /* Set the association before returning */
+ MessageInfoImpl info =
+ resultContainer.getMessageInfo();
+ info.setAssociation(lookupAssociation(info.
+ associationID()));
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ InetSocketAddress isa = (InetSocketAddress)info.address();
+ if (!addressMap.containsKey(isa)) {
+ /* must be a new association */
+ try {
+ sm.checkAccept(isa.getAddress().getHostAddress(),
+ isa.getPort());
+ } catch (SecurityException se) {
+ buffer.clear();
+ throw se;
+ }
+ }
+ }
+
+ assert info.association() != null;
+ return info;
+ } else {
+ /* Non-blocking may return null if nothing available*/
+ return null;
+ }
+ } else { /* notification */
+ synchronized (stateLock) {
+ handleNotificationInternal(
+ resultContainer);
+ }
+ }
+ } /* receiveLock */
+ } while (handler == null ? true :
+ (invokeNotificationHandler(resultContainer, handler, attachment)
+ == HandlerResult.CONTINUE));
+ } finally {
+ receiveInvoked.set(Boolean.FALSE);
+ }
+
+ return null;
+ }
+
+ private int receive(int fd,
+ ByteBuffer dst,
+ ResultContainer resultContainer)
+ throws IOException {
+ int pos = dst.position();
+ int lim = dst.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (dst instanceof DirectBuffer && rem > 0)
+ return receiveIntoNativeBuffer(fd, resultContainer, dst, rem, pos);
+
+ /* Substitute a native buffer. */
+ int newSize = Math.max(rem, 1);
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
+ try {
+ int n = receiveIntoNativeBuffer(fd, resultContainer, bb, newSize, 0);
+ bb.flip();
+ if (n > 0 && rem > 0)
+ dst.put(bb);
+ return n;
+ } finally {
+ Util.releaseTemporaryDirectBuffer(bb);
+ }
+ }
+
+ private int receiveIntoNativeBuffer(int fd,
+ ResultContainer resultContainer,
+ ByteBuffer bb,
+ int rem,
+ int pos)
+ throws IOException {
+ int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
+ if (n > 0)
+ bb.position(pos + n);
+ return n;
+ }
+
+ private InternalNotificationHandler internalNotificationHandler =
+ new InternalNotificationHandler();
+
+ private void handleNotificationInternal(ResultContainer resultContainer)
+ {
+ invokeNotificationHandler(resultContainer,
+ internalNotificationHandler, null);
+ }
+
+ private class InternalNotificationHandler
+ extends AbstractNotificationHandler<Object>
+ {
+ @Override
+ public HandlerResult handleNotification(
+ AssociationChangeNotification not, Object unused) {
+ AssociationChange sac = (AssociationChange) not;
+
+ /* Update map to reflect change in association */
+ switch (not.event()) {
+ case COMM_UP :
+ Association newAssociation = new AssociationImpl
+ (sac.assocId(), sac.maxInStreams(), sac.maxOutStreams());
+ addAssociation(newAssociation);
+ break;
+ case SHUTDOWN :
+ case COMM_LOST :
+ //case RESTART: ???
+ /* mark association for removal after user handler invoked*/
+ associationToRemove.set(lookupAssociation(sac.assocId()));
+ }
+ return HandlerResult.CONTINUE;
+ }
+ }
+
+ private <T> HandlerResult invokeNotificationHandler(
+ ResultContainer resultContainer,
+ NotificationHandler<T> handler,
+ T attachment) {
+ HandlerResult result;
+ SctpNotification notification = resultContainer.notification();
+ notification.setAssociation(lookupAssociation(notification.assocId()));
+
+ if (!(handler instanceof AbstractNotificationHandler)) {
+ result = handler.handleNotification(notification, attachment);
+ } else { /* AbstractNotificationHandler */
+ AbstractNotificationHandler<T> absHandler =
+ (AbstractNotificationHandler<T>)handler;
+ switch(resultContainer.type()) {
+ case ASSOCIATION_CHANGED :
+ result = absHandler.handleNotification(
+ resultContainer.getAssociationChanged(), attachment);
+ break;
+ case PEER_ADDRESS_CHANGED :
+ result = absHandler.handleNotification(
+ resultContainer.getPeerAddressChanged(), attachment);
+ break;
+ case SEND_FAILED :
+ result = absHandler.handleNotification(
+ resultContainer.getSendFailed(), attachment);
+ break;
+ case SHUTDOWN :
+ result = absHandler.handleNotification(
+ resultContainer.getShutdown(), attachment);
+ break;
+ default :
+ /* implementation specific handlers */
+ result = absHandler.handleNotification(
+ resultContainer.notification(), attachment);
+ }
+ }
+
+ if (!(handler instanceof InternalNotificationHandler)) {
+ /* Only remove associations after user handler
+ * has finished with them */
+ Association assoc = associationToRemove.get();
+ if (assoc != null) {
+ removeAssociation(assoc);
+ associationToRemove.set(null);
+ }
+
+ }
+
+ return result;
+ }
+
+ private Association lookupAssociation(int assocId) {
+ /* Lookup the association in our internal map */
+ synchronized (stateLock) {
+ Set<Association> assocs = associationMap.keySet();
+ for (Association a : assocs) {
+ if (a.associationID() == assocId) {
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void addAssociation(Association association) {
+ synchronized (stateLock) {
+ int assocId = association.associationID();
+ Set<SocketAddress> addresses = null;
+
+ try {
+ addresses = SctpNet.getRemoteAddresses(fdVal, assocId);
+ } catch (IOException unused) {
+ /* OK, determining connected addresses may not be possible
+ * shutdown, connection lost, etc */
+ }
+
+ associationMap.put(association, addresses);
+ if (addresses != null) {
+ for (SocketAddress addr : addresses)
+ addressMap.put(addr, association);
+ }
+ }
+ }
+
+ private void removeAssociation(Association association) {
+ synchronized (stateLock) {
+ int assocId = association.associationID();
+ Set<SocketAddress> addresses = null;
+
+ try {
+ addresses = SctpNet.getRemoteAddresses(fdVal, assocId);
+ } catch (IOException unused) {
+ /* OK, determining connected addresses may not be possible
+ * shutdown, connection lost, etc */
+ }
+
+ Set<Association> assocs = associationMap.keySet();
+ for (Association a : assocs) {
+ if (a.associationID() == assocId) {
+ associationMap.remove(a);
+ break;
+ }
+ }
+ if (addresses != null) {
+ for (SocketAddress addr : addresses)
+ addressMap.remove(addr);
+ } else {
+ /* We cannot determine the connected addresses */
+ Set<java.util.Map.Entry<SocketAddress, Association>> addrAssocs =
+ addressMap.entrySet();
+ Iterator<Entry<SocketAddress, Association>> iterator = addrAssocs.iterator();
+ while (iterator.hasNext()) {
+ Entry<SocketAddress, Association> entry = iterator.next();
+ if (entry.getValue().equals(association)) {
+ iterator.remove();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @throws IllegalArgumentException
+ * If the given association is not controlled by this channel
+ *
+ * @return {@code true} if, and only if, the given association is one
+ * of the current associations controlled by this channel
+ */
+ private boolean checkAssociation(Association messageAssoc) {
+ synchronized (stateLock) {
+ for (Association association : associationMap.keySet()) {
+ if (messageAssoc.equals(association)) {
+ return true;
+ }
+ }
+ }
+ throw new IllegalArgumentException(
+ "Given Association is not controlled by this channel");
+ }
+
+ private void checkStreamNumber(Association assoc, int streamNumber) {
+ synchronized (stateLock) {
+ if (streamNumber < 0 || streamNumber >= assoc.maxOutboundStreams())
+ throw new InvalidStreamException();
+ }
+ }
+
+ /* TODO: Add support for ttl and isComplete to both 121 12M
+ * SCTP_EOR not yet supported on reference platforms
+ * TTL support limited...
+ */
+ @Override
+ public int send(ByteBuffer buffer, MessageInfo messageInfo)
+ throws IOException {
+ if (buffer == null)
+ throw new IllegalArgumentException("buffer cannot be null");
+
+ if (messageInfo == null)
+ throw new IllegalArgumentException("messageInfo cannot be null");
+
+ synchronized (sendLock) {
+ ensureOpen();
+
+ if (!isBound())
+ bind(null, 0);
+
+ int n = 0;
+ try {
+ int assocId = -1;
+ SocketAddress address = null;
+ begin();
+
+ synchronized (stateLock) {
+ if(!isOpen())
+ return 0;
+ senderThread = NativeThread.current();
+
+ /* Determine what address or association to send to */
+ Association assoc = messageInfo.association();
+ InetSocketAddress addr = (InetSocketAddress)messageInfo.address();
+ if (assoc != null) {
+ checkAssociation(assoc);
+ checkStreamNumber(assoc, messageInfo.streamNumber());
+ assocId = assoc.associationID();
+ /* have we also got a preferred address */
+ if (addr != null) {
+ if (!assoc.equals(addressMap.get(addr)))
+ throw new IllegalArgumentException("given preferred address is not part of this association");
+ address = addr;
+ }
+ } else if (addr != null) {
+ address = addr;
+ Association association = addressMap.get(addr);
+ if (association != null) {
+ checkStreamNumber(association, messageInfo.streamNumber());
+ assocId = association.associationID();
+
+ } else { /* must be new association */
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(addr.getAddress().getHostAddress(),
+ addr.getPort());
+ }
+ } else {
+ throw new AssertionError(
+ "Both association and address cannot be null");
+ }
+ }
+
+ do {
+ n = send(fdVal, buffer, assocId, address, messageInfo);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+
+ return IOStatus.normalize(n);
+ } finally {
+ senderCleanup();
+ end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ assert IOStatus.check(n);
+ }
+ }
+ }
+
+ private int send(int fd,
+ ByteBuffer src,
+ int assocId,
+ SocketAddress target,
+ MessageInfo messageInfo)
+ throws IOException {
+ int streamNumber = messageInfo.streamNumber();
+ boolean unordered = messageInfo.isUnordered();
+ int ppid = messageInfo.payloadProtocolID();
+
+ if (src instanceof DirectBuffer)
+ return sendFromNativeBuffer(fd, src, target, assocId,
+ streamNumber, unordered, ppid);
+
+ /* Substitute a native buffer */
+ int pos = src.position();
+ int lim = src.limit();
+ assert (pos <= lim && streamNumber >= 0);
+
+ int rem = (pos <= lim ? lim - pos : 0);
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
+ try {
+ bb.put(src);
+ bb.flip();
+ /* Do not update src until we see how many bytes were written */
+ src.position(pos);
+
+ int n = sendFromNativeBuffer(fd, bb, target, assocId,
+ streamNumber, unordered, ppid);
+ if (n > 0) {
+ /* now update src */
+ src.position(pos + n);
+ }
+ return n;
+ } finally {
+ Util.releaseTemporaryDirectBuffer(bb);
+ }
+ }
+
+ private int sendFromNativeBuffer(int fd,
+ ByteBuffer bb,
+ SocketAddress target,
+ int assocId,
+ int streamNumber,
+ boolean unordered,
+ int ppid)
+ throws IOException {
+ int pos = bb.position();
+ int lim = bb.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+
+ int written = send0(fd, ((DirectBuffer)bb).address() + pos,
+ rem, target, assocId, streamNumber, unordered, ppid);
+ if (written > 0)
+ bb.position(pos + written);
+ return written;
+ }
+
+ @Override
+ public SctpMultiChannel shutdown(Association association)
+ throws IOException {
+ synchronized (stateLock) {
+ checkAssociation(association);
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ SctpNet.shutdown(fdVal, association.associationID());
+ }
+ return this;
+ }
+
+ @Override
+ public Set<SocketAddress> getAllLocalAddresses()
+ throws IOException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ return Collections.emptySet();
+
+ return SctpNet.getLocalAddresses(fdVal);
+ }
+ }
+
+ @Override
+ public Set<SocketAddress> getRemoteAddresses(Association association)
+ throws IOException {
+ synchronized (stateLock) {
+ checkAssociation(association);
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ try {
+ return SctpNet.getRemoteAddresses(fdVal, association.associationID());
+ } catch (SocketException se) {
+ /* a valid association should always have remote addresses */
+ Set<SocketAddress> addrs = associationMap.get(association);
+ return addrs != null ? addrs : Collections.<SocketAddress>emptySet();
+ }
+ }
+ }
+
+ @Override
+ public SctpChannel branch(Association association)
+ throws IOException {
+ synchronized (stateLock) {
+ checkAssociation(association);
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ FileDescriptor bFd = SctpNet.branch(fdVal,
+ association.associationID());
+ /* successfully branched, we can now remove it from assoc list */
+ removeAssociation(association);
+
+ return new SctpChannelImpl(provider(), bFd, association);
+ }
+ }
+
+ /* Use common native implementation shared between
+ * one-to-one and one-to-many */
+ private static int receive0(int fd,
+ ResultContainer resultContainer,
+ long address,
+ int length)
+ throws IOException{
+ return SctpChannelImpl.receive0(fd, resultContainer, address,
+ length, false /*peek */);
+ }
+
+ private static int send0(int fd,
+ long address,
+ int length,
+ SocketAddress target,
+ int assocId,
+ int streamNumber,
+ boolean unordered,
+ int ppid)
+ throws IOException {
+ return SctpChannelImpl.send0(fd, address, length, target, assocId,
+ streamNumber, unordered, ppid);
+ }
+
+ static {
+ Util.load(); /* loads nio & net native libraries */
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.LoadLibraryAction("sctp"));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpNet.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.channels.AlreadyBoundException;
+import java.util.Set;
+import java.util.HashSet;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+import sun.nio.ch.IOUtil;
+import sun.nio.ch.Net;
+import com.sun.nio.sctp.SctpSocketOption;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
+
+public class SctpNet {
+ static final String osName = AccessController.doPrivileged(
+ new GetPropertyAction("os.name"));
+
+ /* -- Miscellaneous SCTP utilities -- */
+
+ private static boolean IPv4MappedAddresses() {
+ if ("SunOS".equals(osName)) {
+ /* Solaris supports IPv4Mapped Addresses with bindx */
+ return true;
+ } /* else { //other OS/implementations */
+
+ /* lksctp/linux requires Ipv4 addresses */
+ return false;
+ }
+
+ static boolean throwAlreadyBoundException() throws IOException {
+ throw new AlreadyBoundException();
+ }
+
+ static void listen(int fd, int backlog) throws IOException {
+ listen0(fd, backlog);
+ }
+
+ static int connect(int fd, InetAddress remote, int remotePort)
+ throws IOException {
+ return connect0(fd, remote, remotePort);
+ }
+
+ static void close(int fd) throws IOException {
+ close0(fd);
+ }
+
+ static void preClose(int fd) throws IOException {
+ preClose0(fd);
+ }
+
+ /**
+ * @param oneToOne
+ * if {@code true} returns a one-to-one sctp socket, otherwise
+ * returns a one-to-many sctp socket
+ */
+ static FileDescriptor socket(boolean oneToOne) throws IOException {
+ int nativefd = socket0(oneToOne);
+ return IOUtil.newFD(nativefd);
+ }
+
+ static void bindx(int fd, InetAddress[] addrs, int port, boolean add)
+ throws IOException {
+ bindx(fd, addrs, port, addrs.length, add,
+ IPv4MappedAddresses());
+ }
+
+ static Set<SocketAddress> getLocalAddresses(int fd)
+ throws IOException {
+ HashSet<SocketAddress> set = null;
+ SocketAddress[] saa = getLocalAddresses0(fd);
+
+ if (saa != null) {
+ set = new HashSet<SocketAddress>(saa.length);
+ for (SocketAddress sa : saa)
+ set.add(sa);
+ }
+
+ return set;
+ }
+
+ static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)
+ throws IOException {
+ HashSet<SocketAddress> set = null;
+ SocketAddress[] saa = getRemoteAddresses0(fd, assocId);
+
+ if (saa != null) {
+ set = new HashSet<SocketAddress>(saa.length);
+ for (SocketAddress sa : saa)
+ set.add(sa);
+ }
+
+ return set;
+ }
+
+ static <T> void setSocketOption(int fd,
+ SctpSocketOption<T> name,
+ T value,
+ int assocId)
+ throws IOException {
+ if (value == null)
+ throw new IllegalArgumentException("Invalid option value");
+
+ if (name.equals(SCTP_INIT_MAXSTREAMS)) {
+ InitMaxStreams maxStreamValue = (InitMaxStreams)value;
+ SctpNet.setInitMsgOption0(fd,
+ maxStreamValue.maxInStreams(), maxStreamValue.maxOutStreams());
+ } else if (name.equals(SCTP_PRIMARY_ADDR) ||
+ name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {
+
+ SocketAddress addr = (SocketAddress) value;
+ if (addr == null)
+ throw new IllegalArgumentException("Invalid option value");
+
+ Net.checkAddress(addr);
+ InetSocketAddress netAddr = (InetSocketAddress)addr;
+
+ if (name.equals(SCTP_PRIMARY_ADDR)) {
+ setPrimAddrOption0(fd,
+ assocId,
+ netAddr.getAddress(),
+ netAddr.getPort());
+ } else {
+ setPeerPrimAddrOption0(fd,
+ assocId,
+ netAddr.getAddress(),
+ netAddr.getPort(),
+ IPv4MappedAddresses());
+ }
+ } else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||
+ name.equals(SCTP_EXPLICIT_COMPLETE) ||
+ name.equals(SCTP_FRAGMENT_INTERLEAVE) ||
+ name.equals(SCTP_NODELAY) ||
+ name.equals(SO_SNDBUF) ||
+ name.equals(SO_RCVBUF) ||
+ name.equals(SO_LINGER)) {
+ setIntOption(fd, name, value);
+ } else {
+ throw new AssertionError("Unknown socket option");
+ }
+ }
+
+ static Object getSocketOption(int fd, SctpSocketOption<?> name, int assocId)
+ throws IOException {
+ if (name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {
+ throw new IllegalArgumentException(
+ "SCTP_SET_PEER_PRIMARY_ADDR cannot be retrieved");
+ } else if (name.equals(SCTP_INIT_MAXSTREAMS)) {
+ /* container for holding maxIn/Out streams */
+ int[] values = new int[2];
+ SctpNet.getInitMsgOption0(fd, values);
+ return InitMaxStreams.create(values[0], values[1]);
+ } else if (name.equals(SCTP_PRIMARY_ADDR)) {
+ return getPrimAddrOption0(fd, assocId);
+ } else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||
+ name.equals(SCTP_EXPLICIT_COMPLETE) ||
+ name.equals(SCTP_FRAGMENT_INTERLEAVE) ||
+ name.equals(SCTP_NODELAY) ||
+ name.equals(SO_SNDBUF) ||
+ name.equals(SO_RCVBUF) ||
+ name.equals(SO_LINGER)) {
+ return getIntOption(fd, name);
+ } else {
+ throw new AssertionError("Unknown socket option");
+ }
+ }
+
+ static void setIntOption(int fd, SctpSocketOption<?> name, Object value)
+ throws IOException {
+ if (value == null)
+ throw new IllegalArgumentException("Invalid option value");
+
+ Class<?> type = name.type();
+ if (type != Integer.class && type != Boolean.class)
+ throw new AssertionError("Should not reach here");
+
+ if (name == SO_RCVBUF ||
+ name == SO_SNDBUF)
+ {
+ int i = ((Integer)value).intValue();
+ if (i < 0)
+ throw new IllegalArgumentException(
+ "Invalid send/receive buffer size");
+ } else if (name == SO_LINGER) {
+ int i = ((Integer)value).intValue();
+ if (i < 0)
+ value = Integer.valueOf(-1);
+ if (i > 65535)
+ value = Integer.valueOf(65535);
+ } else if (name.equals(SCTP_FRAGMENT_INTERLEAVE)) {
+ int i = ((Integer)value).intValue();
+ if (i < 0 || i > 2)
+ throw new IllegalArgumentException(
+ "Invalid value for SCTP_FRAGMENT_INTERLEAVE");
+ }
+
+ int arg;
+ if (type == Integer.class) {
+ arg = ((Integer)value).intValue();
+ } else {
+ boolean b = ((Boolean)value).booleanValue();
+ arg = (b) ? 1 : 0;
+ }
+
+ setIntOption0(fd, ((SctpStdSocketOption)name).constValue(), arg);
+ }
+
+ static Object getIntOption(int fd, SctpSocketOption<?> name)
+ throws IOException {
+ Class<?> type = name.type();
+
+ if (type != Integer.class && type != Boolean.class)
+ throw new AssertionError("Should not reach here");
+
+ if (!(name instanceof SctpStdSocketOption))
+ throw new AssertionError("Should not reach here");
+
+ int value = getIntOption0(fd,
+ ((SctpStdSocketOption)name).constValue());
+
+ if (type == Integer.class) {
+ return Integer.valueOf(value);
+ } else {
+ return (value == 0) ? Boolean.FALSE : Boolean.TRUE;
+ }
+ }
+
+ static void shutdown(int fd, int assocId)
+ throws IOException {
+ shutdown0(fd, assocId);
+ }
+
+ static FileDescriptor branch(int fd, int assocId) throws IOException {
+ int nativefd = branch0(fd, assocId);
+ return IOUtil.newFD(nativefd);
+ }
+
+ /* Native Methods */
+ static native int socket0(boolean oneToOne) throws IOException;
+
+ static native void listen0(int fd, int backlog) throws IOException;
+
+ static native int connect0(int fd, InetAddress remote, int remotePort)
+ throws IOException;
+
+ static native void close0(int fd) throws IOException;
+
+ static native void preClose0(int fd) throws IOException;
+
+ static native void bindx(int fd, InetAddress[] addrs, int port, int length,
+ boolean add, boolean preferIPv6) throws IOException;
+
+ static native int getIntOption0(int fd, int opt) throws IOException;
+
+ static native void setIntOption0(int fd, int opt, int arg)
+ throws IOException;
+
+ static native SocketAddress[] getLocalAddresses0(int fd) throws IOException;
+
+ static native SocketAddress[] getRemoteAddresses0(int fd, int assocId)
+ throws IOException;
+
+ static native int branch0(int fd, int assocId) throws IOException;
+
+ static native void setPrimAddrOption0(int fd, int assocId, InetAddress ia,
+ int port) throws IOException;
+
+ static native void setPeerPrimAddrOption0(int fd, int assocId,
+ InetAddress ia, int port, boolean preferIPv6) throws IOException;
+
+ static native SocketAddress getPrimAddrOption0(int fd, int assocId)
+ throws IOException;
+
+ /* retVals [0] maxInStreams, [1] maxOutStreams */
+ static native void getInitMsgOption0(int fd, int[] retVals) throws IOException;
+
+ static native void setInitMsgOption0(int fd, int arg1, int arg2)
+ throws IOException;
+
+ static native void shutdown0(int fd, int assocId);
+
+ static native void init();
+
+ static {
+ init();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpNotification.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.Notification;
+
+/**
+ * All Notification implemenations MUST implement this interface to provide
+ * access to the native association identidier.
+ */
+interface SctpNotification extends Notification {
+ int assocId();
+ void setAssociation(Association association);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
+import java.net.InetAddress;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.HashSet;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.IllegalUnbindException;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpServerChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+import com.sun.nio.sctp.SctpStandardSocketOptions;
+import sun.nio.ch.DirectBuffer;
+import sun.nio.ch.NativeThread;
+import sun.nio.ch.IOStatus;
+import sun.nio.ch.IOUtil;
+import sun.nio.ch.Net;
+import sun.nio.ch.PollArrayWrapper;
+import sun.nio.ch.SelChImpl;
+import sun.nio.ch.SelectionKeyImpl;
+import sun.nio.ch.Util;
+
+/**
+ * An implementation of SctpServerChannel
+ */
+public class SctpServerChannelImpl extends SctpServerChannel
+ implements SelChImpl
+{
+ private final FileDescriptor fd;
+
+ private final int fdVal;
+
+ /* IDs of native thread doing accept, for signalling */
+ private volatile long thread = 0;
+
+ /* Lock held by thread currently blocked in this channel */
+ private final Object lock = new Object();
+
+ /* Lock held by any thread that modifies the state fields declared below
+ * DO NOT invoke a blocking I/O operation while holding this lock! */
+ private final Object stateLock = new Object();
+
+ private enum ChannelState {
+ UNINITIALIZED,
+ INUSE,
+ KILLPENDING,
+ KILLED,
+ }
+ /* -- The following fields are protected by stateLock -- */
+ private ChannelState state = ChannelState.UNINITIALIZED;
+
+ /* Binding: Once bound the port will remain constant. */
+ int port = -1;
+ private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
+ /* Has the channel been bound to the wildcard address */
+ private boolean wildcard; /* false */
+
+ /* -- End of fields protected by stateLock -- */
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ public SctpServerChannelImpl(SelectorProvider provider)
+ throws IOException {
+ //TODO: update provider remove public modifier
+ super(provider);
+ this.fd = SctpNet.socket(true);
+ this.fdVal = IOUtil.fdVal(fd);
+ this.state = ChannelState.INUSE;
+ }
+
+ @Override
+ public SctpServerChannel bind(SocketAddress local, int backlog)
+ throws IOException {
+ synchronized (lock) {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (isBound())
+ SctpNet.throwAlreadyBoundException();
+
+ InetSocketAddress isa = (local == null) ?
+ new InetSocketAddress(0) : Net.checkAddress(local);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkListen(isa.getPort());
+ Net.bind(fd, isa.getAddress(), isa.getPort());
+
+ InetSocketAddress boundIsa = Net.localAddress(fd);
+ port = boundIsa.getPort();
+ localAddresses.add(isa);
+ if (isa.getAddress().isAnyLocalAddress())
+ wildcard = true;
+
+ SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public SctpServerChannel bindAddress(InetAddress address)
+ throws IOException {
+ return bindUnbindAddress(address, true);
+ }
+
+ @Override
+ public SctpServerChannel unbindAddress(InetAddress address)
+ throws IOException {
+ return bindUnbindAddress(address, false);
+ }
+
+ private SctpServerChannel bindUnbindAddress(InetAddress address, boolean add)
+ throws IOException {
+ if (address == null)
+ throw new IllegalArgumentException();
+
+ synchronized (lock) {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ throw new NotYetBoundException();
+ if (wildcard)
+ throw new IllegalStateException(
+ "Cannot add or remove addresses from a channel that is bound to the wildcard address");
+ if (address.isAnyLocalAddress())
+ throw new IllegalArgumentException(
+ "Cannot add or remove the wildcard address");
+ if (add) {
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ SctpNet.throwAlreadyBoundException();
+ }
+ }
+ } else { /*removing */
+ /* Verify that there is more than one address
+ * and that address is already bound */
+ if (localAddresses.size() <= 1)
+ throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
+ boolean foundAddress = false;
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ foundAddress = true;
+ break;
+ }
+ }
+ if (!foundAddress )
+ throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
+ }
+
+ SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
+
+ /* Update our internal Set to reflect the addition/removal */
+ if (add)
+ localAddresses.add(new InetSocketAddress(address, port));
+ else {
+ for (InetSocketAddress addr : localAddresses) {
+ if (addr.getAddress().equals(address)) {
+ localAddresses.remove(addr);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return this;
+ }
+
+ private boolean isBound() {
+ synchronized (stateLock) {
+ return port == -1 ? false : true;
+ }
+ }
+
+ private void acceptCleanup() throws IOException {
+ synchronized (stateLock) {
+ thread = 0;
+ if (state == ChannelState.KILLPENDING)
+ kill();
+ }
+ }
+
+ @Override
+ public SctpChannel accept() throws IOException {
+ synchronized (lock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ throw new NotYetBoundException();
+ SctpChannel sc = null;
+
+ int n = 0;
+ FileDescriptor newfd = new FileDescriptor();
+ InetSocketAddress[] isaa = new InetSocketAddress[1];
+
+ try {
+ begin();
+ if (!isOpen())
+ return null;
+ thread = NativeThread.current();
+ for (;;) {
+ n = accept0(fd, newfd, isaa);
+ if ((n == IOStatus.INTERRUPTED) && isOpen())
+ continue;
+ break;
+ }
+ } finally {
+ acceptCleanup();
+ end(n > 0);
+ assert IOStatus.check(n);
+ }
+
+ if (n < 1)
+ return null;
+
+ IOUtil.configureBlocking(newfd, true);
+ InetSocketAddress isa = isaa[0];
+ sc = new SctpChannelImpl(provider(), newfd);
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkAccept(isa.getAddress().getHostAddress(),
+ isa.getPort());
+
+ return sc;
+ }
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ IOUtil.configureBlocking(fd, block);
+ }
+
+ @Override
+ public void implCloseSelectableChannel() throws IOException {
+ synchronized (stateLock) {
+ SctpNet.preClose(fdVal);
+ if (thread != 0)
+ NativeThread.signal(thread);
+ if (!isRegistered())
+ kill();
+ }
+ }
+
+ @Override
+ public void kill() throws IOException {
+ synchronized (stateLock) {
+ if (state == ChannelState.KILLED)
+ return;
+ if (state == ChannelState.UNINITIALIZED) {
+ state = ChannelState.KILLED;
+ return;
+ }
+ assert !isOpen() && !isRegistered();
+
+ // Postpone the kill if there is a thread in accept
+ if (thread == 0) {
+ SctpNet.close(fdVal);
+ state = ChannelState.KILLED;
+ } else {
+ state = ChannelState.KILLPENDING;
+ }
+ }
+ }
+
+ @Override
+ public FileDescriptor getFD() {
+ return fd;
+ }
+
+ @Override
+ public int getFDVal() {
+ return fdVal;
+ }
+
+ /**
+ * Translates native poll revent ops into a ready operation ops
+ */
+ private boolean translateReadyOps(int ops, int initialOps,
+ SelectionKeyImpl sk) {
+ int intOps = sk.nioInterestOps();
+ int oldOps = sk.nioReadyOps();
+ int newOps = initialOps;
+
+ if ((ops & PollArrayWrapper.POLLNVAL) != 0) {
+ /* This should only happen if this channel is pre-closed while a
+ * selection operation is in progress
+ * ## Throw an error if this channel has not been pre-closed */
+ return false;
+ }
+
+ if ((ops & (PollArrayWrapper.POLLERR
+ | PollArrayWrapper.POLLHUP)) != 0) {
+ newOps = intOps;
+ sk.nioReadyOps(newOps);
+ return (newOps & ~oldOps) != 0;
+ }
+
+ if (((ops & PollArrayWrapper.POLLIN) != 0) &&
+ ((intOps & SelectionKey.OP_ACCEPT) != 0))
+ newOps |= SelectionKey.OP_ACCEPT;
+
+ sk.nioReadyOps(newOps);
+ return (newOps & ~oldOps) != 0;
+ }
+
+ @Override
+ public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
+ return translateReadyOps(ops, sk.nioReadyOps(), sk);
+ }
+
+ @Override
+ public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
+ return translateReadyOps(ops, 0, sk);
+ }
+
+ @Override
+ public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
+ int newOps = 0;
+
+ /* Translate ops */
+ if ((ops & SelectionKey.OP_ACCEPT) != 0)
+ newOps |= PollArrayWrapper.POLLIN;
+ /* Place ops into pollfd array */
+ sk.selector.putEventOps(sk, newOps);
+
+ }
+
+ @Override
+ public <T> SctpServerChannel setOption(SctpSocketOption<T> name, T value)
+ throws IOException {
+ if (name == null)
+ throw new NullPointerException();
+ if (!supportedOptions().contains(name))
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ SctpNet.setSocketOption(fdVal, name, value, 0 /*oneToOne*/);
+ return this;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T> T getOption(SctpSocketOption<T> name) throws IOException {
+ if (name == null)
+ throw new NullPointerException();
+ if (!supportedOptions().contains(name))
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+ return (T) SctpNet.getSocketOption(fdVal, name, 0 /*oneToOne*/);
+ }
+ }
+
+ private static class DefaultOptionsHolder {
+ static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
+
+ private static Set<SctpSocketOption<?>> defaultOptions() {
+ HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(1);
+ set.add(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS);
+ return Collections.unmodifiableSet(set);
+ }
+ }
+
+ @Override
+ public final Set<SctpSocketOption<?>> supportedOptions() {
+ return DefaultOptionsHolder.defaultOptions;
+ }
+
+ @Override
+ public Set<SocketAddress> getAllLocalAddresses()
+ throws IOException {
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (!isBound())
+ return Collections.emptySet();
+
+ return SctpNet.getLocalAddresses(fdVal);
+ }
+ }
+
+ /* Native */
+ private static native void initIDs();
+
+ private static native int accept0(FileDescriptor ssfd,
+ FileDescriptor newfd, InetSocketAddress[] isaa) throws IOException;
+
+ static {
+ Util.load(); // loads nio & net native libraries
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.LoadLibraryAction("sctp"));
+ initIDs();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SendFailed.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.nio.ByteBuffer;
+import java.net.SocketAddress;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.SendFailedNotification;
+
+/**
+ * An implementation of SendFailedNotification
+ */
+public class SendFailed extends SendFailedNotification
+ implements SctpNotification
+{
+ private Association association;
+ /* assocId is used to lookup the association before the notification is
+ * returned to user code */
+ private int assocId;
+ private SocketAddress address;
+ private ByteBuffer buffer;
+ private int errorCode;
+ private int streamNumber;
+
+ /* Invoked from native */
+ private SendFailed(int assocId,
+ SocketAddress address,
+ ByteBuffer buffer,
+ int errorCode,
+ int streamNumber) {
+ this.assocId = assocId;
+ this.errorCode = errorCode;
+ this.streamNumber = streamNumber;
+ this.address = address;
+ this.buffer = buffer;
+ }
+
+ @Override
+ public int assocId() {
+ return assocId;
+ }
+
+ @Override
+ public void setAssociation(Association association) {
+ this.association = association;
+ }
+
+ @Override
+ public Association association() {
+ /* may be null */
+ return association;
+ }
+
+ @Override
+ public SocketAddress address() {
+ assert address != null;
+ return address;
+ }
+
+ @Override
+ public ByteBuffer buffer() {
+ assert buffer != null;
+ return buffer;
+ }
+
+ @Override
+ public int errorCode() {
+ return errorCode;
+ }
+
+ @Override
+ public int streamNumber() {
+ return streamNumber;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString()).append(" [");
+ sb.append("Association:").append(association);
+ sb.append(", Address: ").append(address);
+ sb.append(", buffer: ").append(buffer);
+ sb.append(", errorCode: ").append(errorCode);
+ sb.append(", streamNumber: ").append(streamNumber);
+ sb.append("]");
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/Shutdown.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.ShutdownNotification;
+
+/**
+ * An implementation of ShutdownNotification
+ */
+public class Shutdown extends ShutdownNotification
+ implements SctpNotification
+{
+ private Association association;
+ /* assocId is used to lookup the association before the notification is
+ * returned to user code */
+ private int assocId;
+
+ /* Invoked from native */
+ private Shutdown(int assocId) {
+ this.assocId = assocId;
+ }
+
+ @Override
+ public int assocId() {
+ return assocId;
+ }
+
+ @Override
+ public void setAssociation(Association association) {
+ this.association = association;
+ }
+
+ @Override
+ public Association association() {
+ assert association != null;
+ return association;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString()).append(" [");
+ sb.append("Association:").append(association).append("]");
+ return sb.toString();
+ }
+}
--- a/jdk/src/solaris/doc/sun/man/man1/apt.1 Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-." Copyright (c) 2004, 2011, 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.
-."
-.TH apt 1 "10 May 2011"
-
-.LP
-.SH "NAME"
-.LP
-.LP
-\f2apt\fP \- annotation processing tool
-.LP
-.SH "SYNOPSIS"
-.LP
-.LP
-\f2apt [\-classpath \fP\f2classpath\fP] [\-sourcepath \f2sourcepath\fP] [\-d \f2directory\fP] [\-s \f2directory\fP] [\-factorypath \f2path\fP] [\-factory \f2class\fP] [\-print] [\-nocompile] [\-A\f2key\fP[\f2=val\fP] ...] [\f2javac option\fP] sourcefiles [@files]
-.LP
-.SH "PARAMETERS"
-.LP
-.LP
-Options may be in any order. For a discussion of parameters which apply to a specific option, see OPTIONS below.
-.LP
-.RS 3
-.TP 3
-sourcefiles
-Zero or more source files to be processed.
-.TP 3
-@files
-One or more files that list source files or other options
-.RE
-
-.LP
-.SH "DESCRIPTION"
-.LP
-.LP
-\f3Note\fP: The \f2apt\fP tool and its associated API contained in the package \f2com.sun.mirror\fP have been deprecated since JDK 7 and are planned to be removed in the next major JDK release. Use the options available in the \f2javac(1)\fP tool and the APIs contained in the packages \f2javax.annotation.processing\fP and \f2javax.lang.model\fP to process annotations.
-.LP
-.LP
-The tool \f2apt\fP, annotation processing tool, includes reflective APIs and supporting infrastructure to process program annotations. The \f2apt\fP reflective APIs provide a build\-time, source\-based, read\-only view of program structure. These reflective APIs are designed to cleanly model the Java(TM) programming language's type system after the addition of generics. First, \f2apt\fP runs annotation processors that can produce new source code and other files. Next, \f2apt\fP can cause compilation of both original and generated source files, easing development. The reflective APIs and other APIs used to interact with the tool are subpackages of \f2com.sun.mirror\fP.
-.LP
-.LP
-A fuller discussion of how the tool operates as well as instructions for developing with \f2apt\fP are in
-.na
-\f4Getting Started with \fP\f4apt\fP. @
-.fi
-http://download.oracle.com/javase/7/docs/technotes/guides/apt/GettingStarted.html
-.LP
-.SH "OPTIONS"
-.LP
-.SS
-apt specific options
-.LP
-.RS 3
-.TP 3
-\-s dir
-Specify the directory root under which processor\-generated source files will be placed; files are placed in subdirectories based on package namespace.
-.TP 3
-\-nocompile
-Do not compile source files to class files.
-.TP 3
-\-print
-Print out textual representation of specified types; perform no annotation processing or compilation.
-.TP 3
-\-A[key[=val]]
-Options to pass to annotation processors \-\- these are not interpreted by \f2apt\fP directly, but are made available for use by individual processors
-.TP 3
-\-factorypath path
-Specify where to find annotation processor factories; if this option is used, the classpath is \f2not\fP searched for factories.
-.TP 3
-\-factory classname
-Name of annotation processor factory to use; bypasses default discovery process
-.TP 3
-\-version
-Print version information.
-.TP 3
-\-X
-Display information about non\-standard options.
-.RE
-
-.LP
-.SS
-Options shared with javac
-.LP
-.RS 3
-.TP 3
-\-d dir
-Specify where to place processor and javac generated class files
-.TP 3
-\-cp path or \-classpath path
-Specify where to find user class files and annotation processor factories. If \f2\-factorypath\fP is given, the classpath is not searched for factories.
-.RE
-
-.LP
-.LP
-Consult the javac(1) man page for information on \f2javac\fP options.
-.LP
-.SS
-Non\-Standard Options
-.LP
-.RS 3
-.TP 3
-\-XListAnnotationTypes
-List found annotation types.
-.TP 3
-\-XListDeclarations
-List specified and included declarations.
-.TP 3
-\-XPrintAptRounds
-Print information about initial and recursive \f2apt\fP rounds.
-.TP 3
-\-XPrintFactoryInfo
-Print information about which annotations a factory is asked to process.
-.TP 3
-\-XclassesAsDecls
-Treat both class and source files as declarations to process.
-.RE
-
-.LP
-.LP
-\f3Note\fP: Because these options are non\-standard, they are subject to change without notice.
-.LP
-.SH "NOTES"
-.LP
-.LP
-The \f2apt\fP tool and its associated API contained in the package \f2com.sun.mirror\fP have been deprecated since JDK 7 and are planned to be removed in the next major JDK release. Use the options available in the \f2javac(1)\fP tool and the APIs contained in the packages \f2javax.annotation.processing\fP and \f2javax.lang.model\fP to process annotations.
-.LP
-.SH "SEE ALSO"
-.LP
-.RS 3
-.TP 2
-o
-javac(1), java(1)
-.RE
-
-.LP
-
--- a/jdk/src/solaris/doc/sun/man/man1/ja/apt.1 Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-." Copyright (c) 2004, 2011, 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.
-."
-.TH apt 1 "07 May 2011"
-
-.LP
-.SH "NAME"
-.LP
-.LP
-\f2apt\fP \- Ãí¼á½èÍý¥Ä¡¼¥ë
-.LP
-.SH "·Á¼°"
-.LP
-.LP
-\f2apt [\-classpath \fP\f2classpath\fP] [\-sourcepath \f2sourcepath\fP] [\-d \f2directory\fP] [\-s \f2directory\fP] [\-factorypath \f2path\fP] [\-factory \f2class\fP] [\-print] [\-nocompile] [\-A\f2key\fP[\f2=val\fP] ...] [\f2javac option\fP] sourcefiles [@files]
-.LP
-.SH "¥Ñ¥é¥á¡¼¥¿"
-.LP
-.LP
-¥ª¥×¥·¥ç¥ó¤Î»ØÄê½ç½ø¤Ë·è¤Þ¤ê¤Ï¤¢¤ê¤Þ¤»¤ó¡£ÆÃÄê¤Î¥ª¥×¥·¥ç¥ó¤ËŬÍѤµ¤ì¤ë¥Ñ¥é¥á¡¼¥¿¤Ë¤Ä¤¤¤Æ¤Ï¡¢²¼µ¤Î¡Ö¥ª¥×¥·¥ç¥ó¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.RS 3
-.TP 3
-sourcefiles
-¥¼¥í¡¢1 ¤Ä¡¢¤Þ¤¿¤ÏÊ£¿ô¤Î½èÍýÂоݤΥ½¡¼¥¹¥Õ¥¡¥¤¥ë
-.TP 3
-@files
-¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¾¤Î¥ª¥×¥·¥ç¥ó¤ò°ìÍ÷ɽ¼¨¤¹¤ë 1 ¤Ä¤Þ¤¿¤ÏÊ£¿ô¤Î¥Õ¥¡¥¤¥ë
-.RE
-
-.LP
-.SH "ÀâÌÀ"
-.LP
-.LP
-\f3Ãí\fP: \f2apt\fP ¥Ä¡¼¥ë¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2com.sun.mirror\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤½¤ì¤Ë´ØÏ¢¤·¤¿ API ¤Ï¡¢JDK 7 °Ê¹ßÈó¿ä¾©¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢JDK ¤Î¼¡¤Î¥á¥¸¥ã¡¼¥ê¥ê¡¼¥¹¤Çºï½ü¤µ¤ì¤ëͽÄê¤Ç¤¹¡£\f2javac(1)\fP ¥Ä¡¼¥ë¤ÇÍøÍѲÄǽ¤Ê¥ª¥×¥·¥ç¥ó¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2javax.annotation.processing\fP ¤ª¤è¤Ó \f2javax.lang.model\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë API ¤ò»ÈÍѤ·¤Æ¡¢Ãí¼á¤ò½èÍý¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.LP
-Ãí¼á½èÍý¥Ä¡¼¥ë \f2apt\fP ¤Ï¡¢¥ê¥Õ¥ì¥¯¥È API ¤È¥µ¥Ý¡¼¥È¥¤¥ó¥Õ¥é¥¹¥È¥é¥¯¥Á¥ã¡¼¤«¤é¹½À®¤µ¤ì¡¢¥×¥í¥°¥é¥àÃí¼á¤ò½èÍý¤·¤Þ¤¹¡£\f2apt\fP ¥ê¥Õ¥ì¥¯¥È API ¤Ï¡¢ ¹½ÃÛ»þ¤Î¥½¡¼¥¹¥Ù¡¼¥¹¤Ç¡¢¥×¥í¥°¥é¥à¹½Â¤¤Ë´Ø¤¹¤ëÆɤ߼è¤êÀìÍѥӥ塼¤òÄ󶡤·¤Þ¤¹¡£¤³¤ì¤é¤Î¥ê¥Õ¥ì¥¯¥È API ¤Ï¡¢Áí¾Î¤òÄɲä·¤¿¸å¤Ë¡¢Java(TM) ¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Î·¿¥·¥¹¥Æ¥à¤òÀµ¤·¤¯¥â¥Ç¥ë²½¤¹¤ë¤è¤¦¤ËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ºÇ½é¤Ë¡¢\f2apt\fP ¤Ï¡¢¿·¤·¤¤¥½¡¼¥¹¥³¡¼¥É¤È¾¤Î¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ëÃí¼á¥×¥í¥»¥Ã¥µ¤ò¼Â¹Ô¤·¤Þ¤¹¡£¼¡¤Ë¡¢\f2apt\fP ¤Ï¡¢¸µ¤Î¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÈÀ¸À®¤·¤¿¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÎξÊý¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤¿¤á¡¢³«È¯¤¬³Ú¤Ë¤Ê¤ê¤Þ¤¹¡£¥Ä¡¼¥ë¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Ë»ÈÍѤµ¤ì¤ë¥ê¥Õ¥ì¥¯¥È API ¤Ê¤É¤Î API ¤Ï¡¢\f2com.sun.mirror\fP ¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Ç¤¹¡£
-.LP
-.LP
-¥Ä¡¼¥ë¤Îµ¡Ç½¤Ë´Ø¤¹¤ë¾ÜºÙ¤È¡¢\f2apt\fP ¤ò»ÈÍѤ·¤¿³«È¯ÊýË¡¤Ë¤Ä¤¤¤Æ¤Ï¡¢
-.na
-\f4¡Öapt ÆþÌç¡×\fP @
-.fi
-http://java.sun.com/javase/6/docs/technotes/guides/apt/GettingStarted.html¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.SH "¥ª¥×¥·¥ç¥ó"
-.LP
-.SS
-apt ¸ÇͤΥª¥×¥·¥ç¥ó
-.LP
-.RS 3
-.TP 3
-\-s dir
-¥×¥í¥»¥Ã¥µ¤ÎÀ¸À®¤¹¤ë¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤òÃÖ¤¯¥Ç¥£¥ì¥¯¥È¥ê¥ë¡¼¥È¤ò»ØÄꤷ¤Þ¤¹¡£ ¥Õ¥¡¥¤¥ë¤Ï¡¢¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¶õ´Ö¤Ë´ð¤Å¤¤¤Æ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ËÃÖ¤«¤ì¤Þ¤¹¡£
-.TP 3
-\-nocompile
-¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ò¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤Ë¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤»¤ó¡£
-.TP 3
-\-print
-»ØÄꤷ¤¿¥¿¥¤¥×¤Î¥Æ¥¥¹¥Èɽ¸½¤ò½ÐÎϤ·¤Þ¤¹¡£ Ãí¼á½èÍý¤Þ¤¿¤Ï¥³¥ó¥Ñ¥¤¥ë¤Ï¹Ô¤¤¤Þ¤»¤ó¡£
-.TP 3
-\-A[key[=val]]
-Ãí¼á¥×¥í¥»¥Ã¥µ¤ØÅϤ¹¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\f2apt\fP ¤¬Ä¾Àܲò¼á¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢¤½¤ì¤¾¤ì¤Î¥×¥í¥»¥Ã¥µ¤Ë¤è¤Ã¤Æ»ÈÍѤǤ¤ë¤è¤¦¤ËÊѤ¨¤é¤ì¤Þ¤¹¡£
-.TP 3
-\-factorypath path
-Ãí¼á¥×¥í¥»¥Ã¥µ¥Õ¥¡¥¯¥È¥ê¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢¥¯¥é¥¹¥Ñ¥¹¤Î¥Õ¥¡¥¯¥È¥ê¤Ï¸¡º÷¤µ¤ì¤Þ¤»¤ó¡£
-.TP 3
-\-factory classname
-»ÈÍѤ¹¤ëÃí¼á¥×¥í¥»¥Ã¥µ¥Õ¥¡¥¯¥È¥ê¤Î̾Á°¤Ç¤¹¡£ ¥Ç¥Õ¥©¥ë¥È¤Î¸¡½Ð¥×¥í¥»¥¹¤ò¾Êά¤·¤Þ¤¹¡£
-.TP 3
-\-version
-¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤ò½ÐÎϤ·¤Þ¤¹¡£
-.TP 3
-\-X
-Èóɸ½à¥ª¥×¥·¥ç¥ó¤Ë´Ø¤¹¤ë¾ðÊó¤òɽ¼¨¤·¤Þ¤¹¡£
-.RE
-
-.LP
-.SS
-javac ¤È¶¦ÍѤ¹¤ë¥ª¥×¥·¥ç¥ó
-.LP
-.RS 3
-.TP 3
-\-d dir
-¥×¥í¥»¥Ã¥µ¤È javac À¸À®¤Î¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤òÃÖ¤¯¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£
-.TP 3
-\-cp path ¤Þ¤¿¤Ï \-classpath path
-¥æ¡¼¥¶¡¼¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤ÈÃí¼á¥×¥í¥»¥Ã¥µ¥Õ¥¡¥¯¥È¥ê¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£\f2\-factorypath\fP ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥¯¥é¥¹¥Ñ¥¹¤Î¥Õ¥¡¥¯¥È¥ê¤Ï¸¡º÷¤µ¤ì¤Þ¤»¤ó¡£
-.RE
-
-.LP
-.LP
-\f2javac\fP ¥ª¥×¥·¥ç¥ó¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢javac(1) ¤Î¥Þ¥Ë¥å¥¢¥ë¥Ú¡¼¥¸¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.SS
-Èóɸ½à¥ª¥×¥·¥ç¥ó
-.LP
-.RS 3
-.TP 3
-\-XListAnnotationTypes
-Ãí¼á¤Î·¿¤Ë¸¡½Ð¤µ¤ì¤ë¥ê¥¹¥È.
-.TP 3
-\-XListDeclarations
-»ØÄꤪ¤è¤ÓÀë¸À¤¬¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤ë¥ê¥¹¥È.
-.TP 3
-\-XPrintAptRounds
-½é´ü¤ª¤è¤ÓºÆµ¢Åª¤Ê \f2apt\fP ¥é¥¦¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤ò½ÐÎϤ¹¤ë.
-.TP 3
-\-XPrintFactoryInfo
-½èÍý¤òÍ׵᤹¤ë¥Õ¥¡¥¯¥È¥ê¤ÎÃí¼á¤Ë´Ø¤¹¤ë¾ðÊó¤ò½ÐÎϤ¹¤ë.
-.TP 3
-\-XclassesAsDecls
-¥¯¥é¥¹¥Õ¥¡¥¤¥ë¤È¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÎξÊý¤ò¡¢½èÍýÂоݤÎÀë¸À¤È¤·¤Æ½èÍý¤·¤Þ¤¹¡£
-.RE
-
-.LP
-.LP
-\f3Ãí\fP: ¤³¤ì¤é¤ÏÈóɸ½à¥ª¥×¥·¥ç¥ó¤Ê¤Î¤Ç¡¢Í½¹ð¤Ê¤¯Êѹ¹¤µ¤ì¤ë²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹¡£
-.LP
-.SH "Ãí"
-.LP
-.LP
-\f2apt\fP ¥Ä¡¼¥ë¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2com.sun.mirror\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤½¤ì¤Ë´ØÏ¢¤·¤¿ API ¤Ï¡¢JDK 7 °Ê¹ßÈó¿ä¾©¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢JDK ¤Î¼¡¤Î¥á¥¸¥ã¡¼¥ê¥ê¡¼¥¹¤Çºï½ü¤µ¤ì¤ëͽÄê¤Ç¤¹¡£\f2javac(1)\fP ¥Ä¡¼¥ë¤ÇÍøÍѲÄǽ¤Ê¥ª¥×¥·¥ç¥ó¤È¡¢¥Ñ¥Ã¥±¡¼¥¸ \f2javax.annotation.processing\fP ¤ª¤è¤Ó \f2javax.lang.model\fP ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë API ¤ò»ÈÍѤ·¤Æ¡¢Ãí¼á¤ò½èÍý¤·¤Æ¤¯¤À¤µ¤¤¡£
-.LP
-.SH "´ØÏ¢¹àÌÜ"
-.LP
-.RS 3
-.TP 2
-o
-javac(1), java(1)
-.RE
-
-.LP
-
--- a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Wed Jul 05 18:03:08 2017 +0200
@@ -171,6 +171,53 @@
return array;
}
+/**
+ * Convert a GSList to an array of filenames (with the parent folder)
+ */
+static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list)
+{
+ jstring str;
+ jclass stringCls;
+ GSList *iterator;
+ jobjectArray array;
+ int i;
+ char* entry;
+
+
+ if (list == NULL) {
+ return NULL;
+ }
+
+ stringCls = (*env)->FindClass(env, "java/lang/String");
+ if (stringCls == NULL) {
+ JNU_ThrowInternalError(env, "Could not get java.lang.String class");
+ return NULL;
+ }
+
+ array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls,
+ NULL);
+ if (array == NULL) {
+ JNU_ThrowInternalError(env, "Could not instantiate array files array");
+ return NULL;
+ }
+
+ i = 0;
+ for (iterator = list; iterator; iterator = iterator->next) {
+ entry = (char*) iterator->data;
+
+ //check for leading slash.
+ if (entry[0] == '/') {
+ entry++;
+ }
+
+ str = (*env)->NewStringUTF(env, entry);
+ (*env)->SetObjectArrayElement(env, array, i, str);
+ i++;
+ }
+
+ return array;
+}
+
static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
{
JNIEnv *env;
@@ -183,16 +230,25 @@
env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
current_folder = NULL;
filenames = NULL;
+ gboolean full_path_names = FALSE;
if (responseId == GTK_RESPONSE_ACCEPT) {
current_folder = fp_gtk_file_chooser_get_current_folder(
GTK_FILE_CHOOSER(aDialog));
+ if (current_folder == NULL) {
+ full_path_names = TRUE;
+ }
filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
}
-
- jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
- jfilenames = toFilenamesArray(env, filenames);
-
+ if (full_path_names) {
+ //This is a hack for use with "Recent Folders" in gtk where each
+ //file could have its own directory.
+ jcurrent_folder = (*env)->NewStringUTF(env, "/");
+ jfilenames = toPathAndFilenamesArray(env, filenames);
+ } else {
+ jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
+ jfilenames = toFilenamesArray(env, filenames);
+ }
(*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder,
jfilenames);
fp_g_free(current_folder);
--- a/jdk/src/solaris/native/sun/nio/ch/Sctp.h Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef SUN_NIO_CH_SCTP_H
-#define SUN_NIO_CH_SCTP_H
-
-#ifdef __solaris__
-
-#define _XPG4_2
-#define __EXTENSIONS__
-#include <sys/socket.h>
-#include <netinet/sctp.h>
-#include "jni.h"
-
-/* Current Solaris headers don't comply with draft rfc */
-#ifndef SCTP_EOF
-#define SCTP_EOF MSG_EOF
-#endif
-
-#ifndef SCTP_UNORDERED
-#define SCTP_UNORDERED MSG_UNORDERED
-#endif
-
-/* The current version of the socket API extension shipped with Solaris does
- * not define the following options that the Java API (optionally) supports */
-#ifndef SCTP_EXPLICIT_EOR
-#define SCTP_EXPLICIT_EOR -1
-#endif
-#ifndef SCTP_FRAGMENT_INTERLEAVE
-#define SCTP_FRAGMENT_INTERLEAVE -1
-#endif
-#ifndef SCTP_SET_PEER_PRIMARY_ADDR
-#define SCTP_SET_PEER_PRIMARY_ADDR -1
-#endif
-
-/* Function types to support dynamic linking of socket API extension functions
- * for SCTP. This is so that there is no linkage depandancy during build or
- * runtime for libsctp.*/
-typedef int sctp_getladdrs_func(int sock, sctp_assoc_t id, void **addrs);
-typedef int sctp_freeladdrs_func(void* addrs);
-typedef int sctp_getpaddrs_func(int sock, sctp_assoc_t id, void **addrs);
-typedef int sctp_freepaddrs_func(void *addrs);
-typedef int sctp_bindx_func(int sock, void *addrs, int addrcnt, int flags);
-typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
-
-
-
-#else /* __linux__ */
-#include <stdint.h>
-#include <linux/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "jni.h"
-
-//Causes compiler error if not found, should make warning and uncomment
-/*#include <netinet/sctp.h>*/
-
-#ifndef IPPROTO_SCTP
-#define IPPROTO_SCTP 132
-#endif
-
-/* The current version of lksctp does
- * not define the following option that the Java API (optionally) supports */
-#ifndef SCTP_EXPLICIT_EOR
-#define SCTP_EXPLICIT_EOR -1
-#endif
-
-/* Definitions taken from lksctp-tools-1.0.8/src/include/netinet/sctp.h */
-#ifndef SCTP_INITMSG
-
-enum sctp_optname {
- SCTP_RTOINFO,
-#define SCTP_RTOINFO SCTP_RTOINFO
- SCTP_ASSOCINFO,
-#define SCTP_ASSOCINFO SCTP_ASSOCINFO
- SCTP_INITMSG,
-#define SCTP_INITMSG SCTP_INITMSG
- SCTP_NODELAY, /* Get/set nodelay option. */
-#define SCTP_NODELAY SCTP_NODELAY
- SCTP_AUTOCLOSE,
-#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE
- SCTP_SET_PEER_PRIMARY_ADDR,
-#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR
- SCTP_PRIMARY_ADDR,
-#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR
- SCTP_ADAPTATION_LAYER,
-#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER
- SCTP_DISABLE_FRAGMENTS,
-#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS
- SCTP_PEER_ADDR_PARAMS,
-#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS
- SCTP_DEFAULT_SEND_PARAM,
-#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM
- SCTP_EVENTS,
-#define SCTP_EVENTS SCTP_EVENTS
- SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */
-#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR
- SCTP_MAXSEG, /* Get/set maximum fragment. */
-#define SCTP_MAXSEG SCTP_MAXSEG
- SCTP_STATUS,
-#define SCTP_STATUS SCTP_STATUS
- SCTP_GET_PEER_ADDR_INFO,
-#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
- SCTP_DELAYED_ACK_TIME,
-#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
- SCTP_CONTEXT, /* Receive Context */
-#define SCTP_CONTEXT SCTP_CONTEXT
- SCTP_FRAGMENT_INTERLEAVE,
-#define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE
- SCTP_PARTIAL_DELIVERY_POINT, /* Set/Get partial delivery point */
-#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT
- SCTP_MAX_BURST, /* Set/Get max burst */
-#define SCTP_MAX_BURST SCTP_MAX_BURST
-};
-
-enum sctp_sac_state {
- SCTP_COMM_UP,
- SCTP_COMM_LOST,
- SCTP_RESTART,
- SCTP_SHUTDOWN_COMP,
- SCTP_CANT_STR_ASSOC,
-};
-
-enum sctp_spc_state {
- SCTP_ADDR_AVAILABLE,
- SCTP_ADDR_UNREACHABLE,
- SCTP_ADDR_REMOVED,
- SCTP_ADDR_ADDED,
- SCTP_ADDR_MADE_PRIM,
- SCTP_ADDR_CONFIRMED,
-};
-
-enum sctp_sinfo_flags {
- SCTP_UNORDERED = 1, /* Send/receive message unordered. */
- SCTP_ADDR_OVER = 2, /* Override the primary destination. */
- SCTP_ABORT=4, /* Send an ABORT message to the peer. */
- SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */
-};
-
-enum sctp_sn_type {
- SCTP_SN_TYPE_BASE = (1<<15),
- SCTP_ASSOC_CHANGE,
- SCTP_PEER_ADDR_CHANGE,
- SCTP_SEND_FAILED,
- SCTP_REMOTE_ERROR,
- SCTP_SHUTDOWN_EVENT,
- SCTP_PARTIAL_DELIVERY_EVENT,
- SCTP_ADAPTATION_INDICATION,
-};
-
-typedef enum sctp_cmsg_type {
- SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */
-#define SCTP_INIT SCTP_INIT
- SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */
-#define SCTP_SNDRCV SCTP_SNDRCV
-} sctp_cmsg_t;
-
-enum sctp_msg_flags {
- MSG_NOTIFICATION = 0x8000,
-#define MSG_NOTIFICATION MSG_NOTIFICATION
-};
-
-#define SCTP_BINDX_ADD_ADDR 0x01
-#define SCTP_BINDX_REM_ADDR 0x02
-
-typedef __s32 sctp_assoc_t;
-
-struct sctp_initmsg {
- __u16 sinit_num_ostreams;
- __u16 sinit_max_instreams;
- __u16 sinit_max_attempts;
- __u16 sinit_max_init_timeo;
-};
-
-struct sctp_sndrcvinfo {
- __u16 sinfo_stream;
- __u16 sinfo_ssn;
- __u16 sinfo_flags;
- __u32 sinfo_ppid;
- __u32 sinfo_context;
- __u32 sinfo_timetolive;
- __u32 sinfo_tsn;
- __u32 sinfo_cumtsn;
- sctp_assoc_t sinfo_assoc_id;
-};
-
-struct sctp_event_subscribe {
- __u8 sctp_data_io_event;
- __u8 sctp_association_event;
- __u8 sctp_address_event;
- __u8 sctp_send_failure_event;
- __u8 sctp_peer_error_event;
- __u8 sctp_shutdown_event;
- __u8 sctp_partial_delivery_event;
- __u8 sctp_adaptation_layer_event;
-};
-
-struct sctp_send_failed {
- __u16 ssf_type;
- __u16 ssf_flags;
- __u32 ssf_length;
- __u32 ssf_error;
- struct sctp_sndrcvinfo ssf_info;
- sctp_assoc_t ssf_assoc_id;
- __u8 ssf_data[0];
-};
-
-struct sctp_assoc_change {
- __u16 sac_type;
- __u16 sac_flags;
- __u32 sac_length;
- __u16 sac_state;
- __u16 sac_error;
- __u16 sac_outbound_streams;
- __u16 sac_inbound_streams;
- sctp_assoc_t sac_assoc_id;
- __u8 sac_info[0];
-};
-
-struct sctp_shutdown_event {
- __u16 sse_type;
- __u16 sse_flags;
- __u32 sse_length;
- sctp_assoc_t sse_assoc_id;
-};
-
-struct sctp_paddr_change {
- __u16 spc_type;
- __u16 spc_flags;
- __u32 spc_length;
- struct sockaddr_storage spc_aaddr;
- int spc_state;
- int spc_error;
- sctp_assoc_t spc_assoc_id;
-} __attribute__((packed, aligned(4)));
-
-struct sctp_remote_error {
- __u16 sre_type;
- __u16 sre_flags;
- __u32 sre_length;
- __u16 sre_error;
- sctp_assoc_t sre_assoc_id;
- __u8 sre_data[0];
-};
-
-struct sctp_adaptation_event {
- __u16 sai_type;
- __u16 sai_flags;
- __u32 sai_length;
- __u32 sai_adaptation_ind;
- sctp_assoc_t sai_assoc_id;
-};
-
-struct sctp_setprim {
- sctp_assoc_t ssp_assoc_id;
- struct sockaddr_storage ssp_addr;
-} __attribute__((packed, aligned(4)));
-
-struct sctp_setpeerprim {
- sctp_assoc_t sspp_assoc_id;
- struct sockaddr_storage sspp_addr;
-} __attribute__((packed, aligned(4)));
-
-
-struct sctp_pdapi_event {
- __u16 pdapi_type;
- __u16 pdapi_flags;
- __u32 pdapi_length;
- __u32 pdapi_indication;
- sctp_assoc_t pdapi_assoc_id;
-};
-
-union sctp_notification {
- struct {
- __u16 sn_type; /* Notification type. */
- __u16 sn_flags;
- __u32 sn_length;
- } sn_header;
- struct sctp_assoc_change sn_assoc_change;
- struct sctp_paddr_change sn_paddr_change;
- struct sctp_remote_error sn_remote_error;
- struct sctp_send_failed sn_send_failed;
- struct sctp_shutdown_event sn_shutdown_event;
- struct sctp_adaptation_event sn_adaptation_event;
- struct sctp_pdapi_event sn_pdapi_event;
-};
-
-#endif /* SCTP_INITMSG */
-
-/* Function types to support dynamic linking of socket API extension functions
- * for SCTP. This is so that there is no linkage depandancy during build or
- * runtime for libsctp.*/
-typedef int sctp_getladdrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
-typedef int sctp_freeladdrs_func(struct sockaddr *addrs);
-typedef int sctp_getpaddrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
-typedef int sctp_freepaddrs_func(struct sockaddr *addrs);
-typedef int sctp_bindx_func(int sd, struct sockaddr *addrs, int addrcnt, int flags);
-typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
-
-
-#endif /* __linux__ */
-
-sctp_getladdrs_func* nio_sctp_getladdrs;
-sctp_freeladdrs_func* nio_sctp_freeladdrs;
-sctp_getpaddrs_func* nio_sctp_getpaddrs;
-sctp_freepaddrs_func* nio_sctp_freepaddrs;
-sctp_bindx_func* nio_sctp_bindx;
-sctp_peeloff_func* nio_sctp_peeloff;
-
-jboolean loadSocketExtensionFuncs(JNIEnv* env);
-
-#endif /* !SUN_NIO_CH_SCTP_H */
--- a/jdk/src/solaris/native/sun/nio/ch/SctpChannelImpl.c Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,594 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "Sctp.h"
-
-#include "jni.h"
-#include "nio_util.h"
-#include "nio.h"
-#include "net_util.h"
-#include "net_util_md.h"
-#include "sun_nio_ch_SctpNet.h"
-#include "sun_nio_ch_SctpChannelImpl.h"
-#include "sun_nio_ch_SctpAssocChange.h"
-#include "sun_nio_ch_SctpResultContainer.h"
-#include "sun_nio_ch_SctpPeerAddrChange.h"
-
-/* sizeof(union sctp_notification */
-#define NOTIFICATION_BUFFER_SIZE 280
-
-#define MESSAGE_IMPL_CLASS "sun/nio/ch/SctpMessageInfoImpl"
-#define RESULT_CONTAINER_CLASS "sun/nio/ch/SctpResultContainer"
-#define SEND_FAILED_CLASS "sun/nio/ch/SctpSendFailed"
-#define ASSOC_CHANGE_CLASS "sun/nio/ch/SctpAssocChange"
-#define PEER_CHANGE_CLASS "sun/nio/ch/SctpPeerAddrChange"
-#define SHUTDOWN_CLASS "sun/nio/ch/SctpShutdown"
-
-struct controlData {
- int assocId;
- unsigned short streamNumber;
- jboolean unordered;
- unsigned int ppid;
-};
-
-static jclass smi_class; /* sun.nio.ch.SctpMessageInfoImpl */
-static jmethodID smi_ctrID; /* sun.nio.ch.SctpMessageInfoImpl.<init> */
-static jfieldID src_valueID; /* sun.nio.ch.SctpResultContainer.value */
-static jfieldID src_typeID; /* sun.nio.ch.SctpResultContainer.type */
-static jclass ssf_class; /* sun.nio.ch.SctpSendFailed */
-static jmethodID ssf_ctrID; /* sun.nio.ch.SctpSendFailed.<init> */
-static jclass sac_class; /* sun.nio.ch.SctpAssociationChanged */
-static jmethodID sac_ctrID; /* sun.nio.ch.SctpAssociationChanged.<init> */
-static jclass spc_class; /* sun.nio.ch.SctpPeerAddressChanged */
-static jmethodID spc_ctrID; /* sun.nio.ch.SctpPeerAddressChanged.<init> */
-static jclass ss_class; /* sun.nio.ch.SctpShutdown */
-static jmethodID ss_ctrID; /* sun.nio.ch.SctpShutdown.<init> */
-static jfieldID isa_addrID; /* java.net.InetSocketAddress.addr */
-static jfieldID isa_portID; /* java.net.InetSocketAddress.port */
-
-/* defined in SctpNet.c */
-jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
-
-/* use SocketChannelImpl's checkConnect implementation */
-extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
- jobject this, jobject fdo, jboolean block, jboolean ready);
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: initIDs
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpChannelImpl_initIDs
- (JNIEnv *env, jclass klass) {
- jclass cls;
-
- /* SctpMessageInfoImpl */
- cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
- CHECK_NULL(cls);
- smi_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(smi_class);
- smi_ctrID = (*env)->GetMethodID(env, cls, "<init>",
- "(ILjava/net/SocketAddress;IIZZI)V");
- CHECK_NULL(smi_ctrID);
-
- /* SctpResultContainer */
- cls = (*env)->FindClass(env, RESULT_CONTAINER_CLASS);
- CHECK_NULL(cls);
- src_valueID = (*env)->GetFieldID(env, cls, "value", "Ljava/lang/Object;");
- CHECK_NULL(src_valueID);
- src_typeID = (*env)->GetFieldID(env, cls, "type", "I");
- CHECK_NULL(src_typeID);
-
- /* SctpSendFailed */
- cls = (*env)->FindClass(env, SEND_FAILED_CLASS);
- CHECK_NULL(cls);
- ssf_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(ssf_class);
- ssf_ctrID = (*env)->GetMethodID(env, cls, "<init>",
- "(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
- CHECK_NULL(ssf_ctrID);
-
- /* SctpAssocChange */
- cls = (*env)->FindClass(env, ASSOC_CHANGE_CLASS);
- CHECK_NULL(cls);
- sac_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(sac_class);
- sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
- CHECK_NULL(sac_ctrID);
-
- /* SctpPeerAddrChange */
- cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
- CHECK_NULL(cls);
- spc_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(spc_class);
- spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
- "(ILjava/net/SocketAddress;I)V");
- CHECK_NULL(spc_ctrID);
-
- /* sun.nio.ch.SctpShutdown */
- cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
- CHECK_NULL(cls);
- ss_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(ss_class);
- ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
- CHECK_NULL(ss_ctrID);
-
- /* InetSocketAddress */
- cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
- CHECK_NULL(cls);
- isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
- CHECK_NULL(isa_addrID);
- isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
-}
-
-void getControlData
- (struct msghdr* msg, struct controlData* cdata) {
- struct cmsghdr* cmsg;
-
- for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
- if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
- struct sctp_sndrcvinfo *sri;
-
- sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
- cdata->assocId = sri->sinfo_assoc_id;
- cdata->streamNumber = sri->sinfo_stream;
- cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
- JNI_FALSE;
- cdata->ppid = ntohl(sri->sinfo_ppid);
-
- return;
- }
- }
- return;
-}
-
-void setControlData
- (struct msghdr* msg, struct controlData* cdata) {
- struct cmsghdr* cmsg;
- struct sctp_sndrcvinfo *sri;
-
- cmsg = CMSG_FIRSTHDR(msg);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
-
- /* Initialize the payload */
- sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
- memset(sri, 0, sizeof (*sri));
-
- if (cdata->streamNumber > 0) {
- sri->sinfo_stream = cdata->streamNumber;
- }
- if (cdata->assocId > 0) {
- sri->sinfo_assoc_id = cdata->assocId;
- }
- if (cdata->unordered == JNI_TRUE) {
- sri->sinfo_flags = sri->sinfo_flags | SCTP_UNORDERED;
- }
-
- if (cdata->ppid > 0) {
- sri->sinfo_ppid = htonl(cdata->ppid);
- }
-
- /* Sum of the length of all control messages in the buffer. */
- msg->msg_controllen = cmsg->cmsg_len;
-}
-
-// TODO: test: can create send failed without any data? if so need to
-// update API so that buffer can be null if no data.
-void handleSendFailed
- (JNIEnv* env, int fd, jobject resultContainerObj, struct sctp_send_failed *ssf,
- int read, jboolean isEOR, struct sockaddr* sap) {
- jobject bufferObj = NULL, resultObj, isaObj;
- char *addressP;
- struct sctp_sndrcvinfo *sri;
- int remaining, dataLength;
-
- /* the actual undelivered message data is directly after the ssf */
- int dataOffset = sizeof(struct sctp_send_failed);
-
- sri = (struct sctp_sndrcvinfo*) &ssf->ssf_info;
-
- /* the number of bytes remaining to be read in the sctp_send_failed notif*/
- remaining = ssf->ssf_length - read;
-
- /* the size of the actual undelivered message */
- dataLength = ssf->ssf_length - dataOffset;
-
- /* retrieved address from sockaddr */
- isaObj = SockAddrToInetSocketAddress(env, sap);
-
- /* data retrieved from sff_data */
- if (dataLength > 0) {
- struct iovec iov[1];
- struct msghdr msg[1];
- int rv, alreadyRead;
- char *dataP = (char*) ssf;
- dataP += dataOffset;
-
- if ((addressP = malloc(dataLength)) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "handleSendFailed");
- return;
- }
-
- memset(msg, 0, sizeof (*msg));
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
-
- bufferObj = (*env)->NewDirectByteBuffer(env, addressP, dataLength);
- CHECK_NULL(bufferObj);
-
- alreadyRead = read - dataOffset;
- if (alreadyRead > 0) {
- memcpy(addressP, /*ssf->ssf_data*/ dataP, alreadyRead);
- iov->iov_base = addressP + alreadyRead;
- iov->iov_len = dataLength - alreadyRead;
- } else {
- iov->iov_base = addressP;
- iov->iov_len = dataLength;
- }
-
- if (remaining > 0) {
- if ((rv = recvmsg(fd, msg, 0)) < 0) {
- handleSocketError(env, errno);
- return;
- }
-
- if (rv != (dataLength - alreadyRead) || !(msg->msg_flags & MSG_EOR)) {
- //TODO: assert false: "should not reach here";
- return;
- }
- // TODO: Set and document (in API) buffers position.
- }
- }
-
- /* create SctpSendFailed */
- resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
- isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_SEND_FAILED);
-}
-
-void handleAssocChange
- (JNIEnv* env, jobject resultContainerObj, struct sctp_assoc_change *sac) {
- jobject resultObj;
- int state = 0;
-
- switch (sac->sac_state) {
- case SCTP_COMM_UP :
- state = sun_nio_ch_SctpAssocChange_SCTP_COMM_UP;
- break;
- case SCTP_COMM_LOST :
- state = sun_nio_ch_SctpAssocChange_SCTP_COMM_LOST;
- break;
- case SCTP_RESTART :
- state = sun_nio_ch_SctpAssocChange_SCTP_RESTART;
- break;
- case SCTP_SHUTDOWN_COMP :
- state = sun_nio_ch_SctpAssocChange_SCTP_SHUTDOWN;
- break;
- case SCTP_CANT_STR_ASSOC :
- state = sun_nio_ch_SctpAssocChange_SCTP_CANT_START;
- }
-
- /* create SctpAssociationChanged */
- resultObj = (*env)->NewObject(env, sac_class, sac_ctrID, sac->sac_assoc_id,
- state, sac->sac_outbound_streams, sac->sac_inbound_streams);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_ASSOCIATION_CHANGED);
-}
-
-void handleShutdown
- (JNIEnv* env, jobject resultContainerObj, struct sctp_shutdown_event* sse) {
- /* create SctpShutdown */
- jobject resultObj = (*env)->NewObject(env, ss_class, ss_ctrID, sse->sse_assoc_id);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_SHUTDOWN);
-}
-
-void handlePeerAddrChange
- (JNIEnv* env, jobject resultContainerObj, struct sctp_paddr_change* spc) {
- int event = 0;
- jobject addressObj, resultObj;
- unsigned int state = spc->spc_state;
-
- switch (state) {
- case SCTP_ADDR_AVAILABLE :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_AVAILABLE;
- break;
- case SCTP_ADDR_UNREACHABLE :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_UNREACHABLE;
- break;
- case SCTP_ADDR_REMOVED :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_REMOVED;
- break;
- case SCTP_ADDR_ADDED :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_ADDED;
- break;
- case SCTP_ADDR_MADE_PRIM :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_MADE_PRIM;
-#ifdef __linux__ /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */
- break;
- case SCTP_ADDR_CONFIRMED :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_CONFIRMED;
-#endif /* __linux__ */
- }
-
- addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
-
- /* create SctpPeerAddressChanged */
- resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
- addressObj, event);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_PEER_ADDRESS_CHANGED);
-}
-
-void handleUninteresting
- (union sctp_notification *snp) {
- //fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
-}
-
-/**
- * Handle notifications from the SCTP stack.
- * Returns JNI_TRUE if the notification is one that is of interest to the
- * Java API, otherwise JNI_FALSE.
- */
-jboolean handleNotification
- (JNIEnv* env, int fd, jobject resultContainerObj, union sctp_notification* snp,
- int read, jboolean isEOR, struct sockaddr* sap) {
- switch (snp->sn_header.sn_type) {
- case SCTP_SEND_FAILED:
- handleSendFailed(env, fd, resultContainerObj, &snp->sn_send_failed,
- read, isEOR, sap);
- return JNI_TRUE;
- case SCTP_ASSOC_CHANGE:
- handleAssocChange(env, resultContainerObj, &snp->sn_assoc_change);
- return JNI_TRUE;
- case SCTP_SHUTDOWN_EVENT:
- handleShutdown(env, resultContainerObj, &snp->sn_shutdown_event);
- return JNI_TRUE;
- case SCTP_PEER_ADDR_CHANGE:
- handlePeerAddrChange(env, resultContainerObj, &snp->sn_paddr_change);
- return JNI_TRUE;
- default :
- /* the Java API is not interested in this event, maybe we are? */
- handleUninteresting(snp);
- }
- return JNI_FALSE;
-}
-
-void handleMessage
- (JNIEnv* env, jobject resultContainerObj, struct msghdr* msg,int read,
- jboolean isEOR, struct sockaddr* sap) {
- jobject isa, resultObj;
- struct controlData cdata[1];
-
- if (read == 0) {
- /* we reached EOF */
- read = -1;
- }
-
- isa = SockAddrToInetSocketAddress(env, sap);
- getControlData(msg, cdata);
-
- /* create SctpMessageInfoImpl */
- resultObj = (*env)->NewObject(env, smi_class, smi_ctrID, cdata->assocId,
- isa, read, cdata->streamNumber,
- isEOR ? JNI_TRUE : JNI_FALSE,
- cdata->unordered, cdata->ppid);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_MESSAGE);
-}
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: receive0
- * Signature: (ILsun/nio/ch/SctpResultContainer;JIZ)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_receive0
- (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
- jlong address, jint length, jboolean peek) {
- SOCKADDR sa;
- int sa_len = sizeof(sa);
- ssize_t rv = 0;
- jlong *addr = jlong_to_ptr(address);
- struct iovec iov[1];
- struct msghdr msg[1];
- char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
- int flags = peek == JNI_TRUE ? MSG_PEEK : 0;
-
- /* Set up the msghdr structure for receiving */
- memset(msg, 0, sizeof (*msg));
- msg->msg_name = &sa;
- msg->msg_namelen = sa_len;
- iov->iov_base = addr;
- iov->iov_len = length;
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
- msg->msg_control = cbuf;
- msg->msg_controllen = sizeof(cbuf);
- msg->msg_flags = 0;
-
- do {
- if ((rv = recvmsg(fd, msg, flags)) < 0) {
- if (errno == EWOULDBLOCK) {
- return IOS_UNAVAILABLE;
- } else if (errno == EINTR) {
- return IOS_INTERRUPTED;
-
-#ifdef __linux__
- } else if (errno == ENOTCONN) {
- /* ENOTCONN when EOF reached */
- rv = 0;
- /* there will be no control data */
- msg->msg_controllen = 0;
-#endif /* __linux__ */
-
- } else {
- handleSocketError(env, errno);
- return 0;
- }
- }
-
- if (msg->msg_flags & MSG_NOTIFICATION) {
- char *bufp = (char*)addr;
- union sctp_notification *snp;
-
- if (!(msg->msg_flags & MSG_EOR) && length < NOTIFICATION_BUFFER_SIZE) {
- char buf[NOTIFICATION_BUFFER_SIZE];
- int rvSAVE = rv;
- memcpy(buf, addr, rv);
- iov->iov_base = buf + rv;
- iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv;
- if ((rv = recvmsg(fd, msg, flags)) < 0) {
- handleSocketError(env, errno);
- return 0;
- }
- bufp = buf;
- rv += rvSAVE;
- }
- snp = (union sctp_notification *) bufp;
- if (handleNotification(env, fd, resultContainerObj, snp, rv,
- (msg->msg_flags & MSG_EOR),
- (struct sockaddr*)&sa ) == JNI_TRUE) {
- /* We have received a notification that is of interest to
- to the Java API. The appropriate notification will be
- set in the result container. */
- return 0;
- }
-
- // set iov back to addr, and reset msg_controllen
- iov->iov_base = addr;
- iov->iov_len = length;
- msg->msg_control = cbuf;
- msg->msg_controllen = sizeof(cbuf);
- }
- } while (msg->msg_flags & MSG_NOTIFICATION);
-
- handleMessage(env, resultContainerObj, msg, rv,
- (msg->msg_flags & MSG_EOR), (struct sockaddr*)&sa);
- return rv;
-}
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: send0
- * Signature: (IJILjava/net/SocketAddress;IIZI)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_send0
- (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
- jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
- jint ppid) {
- SOCKADDR sa;
- int sa_len = sizeof(sa);
- ssize_t rv = 0;
- jlong *addr = jlong_to_ptr(address);
- struct iovec iov[1];
- struct msghdr msg[1];
- int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
- char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
- struct controlData cdata[1];
-
- /* SctpChannel:
- * saTarget may contain the preferred address or NULL to use primary,
- * assocId will always be -1
- * SctpMultiChannell:
- * Setup new association, saTarget will contain address, assocId = -1
- * Association already existing, assocId != -1, saTarget = preferred addr
- */
- if (saTarget != NULL /*&& assocId <= 0*/) {
-
- jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
- jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
-
- if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
- (struct sockaddr *)&sa,
- &sa_len, JNI_TRUE) != 0) {
- return IOS_THROWN;
- }
- } else {
- memset(&sa, '\x0', sa_len);
- sa_len = 0;
- }
-
- /* Set up the msghdr structure for sending */
- memset(msg, 0, sizeof (*msg));
- memset(cbuf, 0, cbuf_size);
- msg->msg_name = &sa;
- msg->msg_namelen = sa_len;
- iov->iov_base = addr;
- iov->iov_len = length;
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
- msg->msg_control = cbuf;
- msg->msg_controllen = cbuf_size;
- msg->msg_flags = 0;
-
- cdata->streamNumber = streamNumber;
- cdata->assocId = assocId;
- cdata->unordered = unordered;
- cdata->ppid = ppid;
- setControlData(msg, cdata);
-
- if ((rv = sendmsg(fd, msg, 0)) < 0) {
- if (errno == EWOULDBLOCK) {
- return IOS_UNAVAILABLE;
- } else if (errno == EINTR) {
- return IOS_INTERRUPTED;
- } else if (errno == EPIPE) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket is shutdown for writing");
- } else {
- handleSocketError(env, errno);
- return 0;
- }
- }
-
- return rv;
-}
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: checkConnect
- * Signature: (Ljava/io/FileDescriptor;ZZ)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_checkConnect
- (JNIEnv* env, jobject this, jobject fdo, jboolean block, jboolean ready) {
- return Java_sun_nio_ch_SocketChannelImpl_checkConnect(env, this,
- fdo, block, ready);
-}
-
--- a/jdk/src/solaris/native/sun/nio/ch/SctpNet.c Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,753 +0,0 @@
-/*
- * Copyright (c) 2009, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <dlfcn.h>
-
-#include "Sctp.h"
-#include "jni.h"
-#include "jni_util.h"
-#include "nio_util.h"
-#include "nio.h"
-#include "net_util.h"
-#include "net_util_md.h"
-#include "sun_nio_ch_SctpNet.h"
-#include "sun_nio_ch_SctpStdSocketOption.h"
-
-static jclass isaCls = 0;
-static jmethodID isaCtrID = 0;
-
-static const char* nativeSctpLib = "libsctp.so.1";
-static jboolean funcsLoaded = JNI_FALSE;
-
-JNIEXPORT jint JNICALL JNI_OnLoad
- (JavaVM *vm, void *reserved) {
- return JNI_VERSION_1_2;
-}
-
-static int preCloseFD = -1; /* File descriptor to which we dup other fd's
- before closing them for real */
-
-/**
- * Loads the native sctp library that contains the socket extension
- * functions, as well as locating the individual functions.
- * There will be a pending exception if this method returns false.
- */
-jboolean loadSocketExtensionFuncs
- (JNIEnv* env) {
- if (dlopen(nativeSctpLib, RTLD_GLOBAL | RTLD_LAZY) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- if ((nio_sctp_getladdrs = (sctp_getladdrs_func*)
- dlsym(RTLD_DEFAULT, "sctp_getladdrs")) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- if ((nio_sctp_freeladdrs = (sctp_freeladdrs_func*)
- dlsym(RTLD_DEFAULT, "sctp_freeladdrs")) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- if ((nio_sctp_getpaddrs = (sctp_getpaddrs_func*)
- dlsym(RTLD_DEFAULT, "sctp_getpaddrs")) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- if ((nio_sctp_freepaddrs = (sctp_freepaddrs_func*)
- dlsym(RTLD_DEFAULT, "sctp_freepaddrs")) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- if ((nio_sctp_bindx = (sctp_bindx_func*)
- dlsym(RTLD_DEFAULT, "sctp_bindx")) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- if ((nio_sctp_peeloff = (sctp_peeloff_func*)
- dlsym(RTLD_DEFAULT, "sctp_peeloff")) == NULL) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- dlerror());
- return JNI_FALSE;
- }
-
- funcsLoaded = JNI_TRUE;
- return JNI_TRUE;
-}
-
-jint
-handleSocketError(JNIEnv *env, jint errorValue)
-{
- char *xn;
- switch (errorValue) {
- case EINPROGRESS: /* Non-blocking connect */
- return 0;
- case EPROTO:
- xn= JNU_JAVANETPKG "ProtocolException";
- break;
- case ECONNREFUSED:
- xn = JNU_JAVANETPKG "ConnectException";
- break;
- case ETIMEDOUT:
- xn = JNU_JAVANETPKG "ConnectException";
- break;
- case EHOSTUNREACH:
- xn = JNU_JAVANETPKG "NoRouteToHostException";
- break;
- case EADDRINUSE: /* Fall through */
- case EADDRNOTAVAIL:
- xn = JNU_JAVANETPKG "BindException";
- break;
- default:
- xn = JNU_JAVANETPKG "SocketException";
- break;
- }
- errno = errorValue;
- JNU_ThrowByNameWithLastError(env, xn, "NioSocketError");
- return IOS_THROWN;
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SctpNet_init
- (JNIEnv *env, jclass cl) {
- int sp[2];
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
- return;
- }
- preCloseFD = sp[0];
- close(sp[1]);
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: socket0
- * Signature: (Z)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpNet_socket0
- (JNIEnv *env, jclass klass, jboolean oneToOne) {
- int fd;
- struct sctp_event_subscribe event;
-#ifdef AF_INET6
- int domain = ipv6_available() ? AF_INET6 : AF_INET;
-#else
- int domain = AF_INET;
-#endif
-
- /* Try to load the socket API extension functions */
- if (!funcsLoaded && !loadSocketExtensionFuncs(env)) {
- return 0;
- }
-
- fd = socket(domain, (oneToOne ? SOCK_STREAM : SOCK_SEQPACKET), IPPROTO_SCTP);
-
- if (fd < 0) {
- return handleSocketError(env, errno);
- }
-
- /* Enable events */
- memset(&event, 0, sizeof(event));
- event.sctp_data_io_event = 1;
- event.sctp_association_event = 1;
- event.sctp_address_event = 1;
- event.sctp_send_failure_event = 1;
- //event.sctp_peer_error_event = 1;
- event.sctp_shutdown_event = 1;
- //event.sctp_partial_delivery_event = 1;
- //event.sctp_adaptation_layer_event = 1;
- if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) {
- handleSocketError(env, errno);
- }
- return fd;
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: bindx
- * Signature: (I[Ljava/net/InetAddress;IIZ)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_bindx
- (JNIEnv *env, jclass klass, jint fd, jobjectArray addrs, jint port,
- jint addrsLength, jboolean add, jboolean preferIPv6) {
- SOCKADDR *sap, *tmpSap;
- int i, sa_len = sizeof(SOCKADDR);
- jobject ia;
-
- if (addrsLength < 1)
- return;
-
- if ((sap = calloc(addrsLength, sa_len)) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
- return;
- }
-
- tmpSap = sap;
- for (i=0; i<addrsLength; i++) {
- ia = (*env)->GetObjectArrayElement(env, addrs, i);
- if (NET_InetAddressToSockaddr(env, ia, port, (struct sockaddr*)tmpSap,
- &sa_len, preferIPv6) != 0) {
- free(sap);
- return;
- }
- tmpSap++;
- }
-
- if (nio_sctp_bindx(fd, (void*)sap, addrsLength, add ? SCTP_BINDX_ADD_ADDR :
- SCTP_BINDX_REM_ADDR) != 0) {
- handleSocketError(env, errno);
- }
-
- free(sap);
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: listen0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SctpNet_listen0
- (JNIEnv *env, jclass cl, jint fd, jint backlog) {
- if (listen(fd, backlog) < 0)
- handleSocketError(env, errno);
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: connect0
- * Signature: (ILjava/net/InetAddress;I)I
- */
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_SctpNet_connect0
- (JNIEnv *env, jclass clazz, int fd, jobject iao, jint port) {
- SOCKADDR sa;
- int sa_len = SOCKADDR_LEN;
- int rv;
-
- if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *) &sa,
- &sa_len, JNI_TRUE) != 0) {
- return IOS_THROWN;
- }
-
- rv = connect(fd, (struct sockaddr *)&sa, sa_len);
- if (rv != 0) {
- if (errno == EINPROGRESS) {
- return IOS_UNAVAILABLE;
- } else if (errno == EINTR) {
- return IOS_INTERRUPTED;
- }
- return handleSocketError(env, errno);
- }
- return 1;
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: close0
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SctpNet_close0
- (JNIEnv *env, jclass clazz, jint fd) {
- if (fd != -1) {
- int rv = close(fd);
- if (rv < 0)
- JNU_ThrowIOExceptionWithLastError(env, "Close failed");
- }
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: preClose0
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SctpNet_preClose0
- (JNIEnv *env, jclass clazz, jint fd) {
- if (preCloseFD >= 0) {
- if (dup2(preCloseFD, fd) < 0)
- JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
- }
-}
-
-void initializeISA
- (JNIEnv* env) {
- if (isaCls == 0) {
- jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");
- CHECK_NULL(c);
- isaCls = (*env)->NewGlobalRef(env, c);
- CHECK_NULL(isaCls);
- (*env)->DeleteLocalRef(env, c);
- isaCtrID = (*env)->GetMethodID(env, isaCls, "<init>",
- "(Ljava/net/InetAddress;I)V");
- }
-}
-
-jobject SockAddrToInetSocketAddress
- (JNIEnv *env, struct sockaddr* sap) {
- int port = 0;
-
- jobject ia = NET_SockaddrToInetAddress(env, sap, &port);
- if (ia == NULL)
- return NULL;
-
- if (isaCls == 0) {
- initializeISA(env);
- CHECK_NULL_RETURN(isaCls, NULL);
- }
-
- return (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: getLocalAddresses0
- * Signature: (I)[Ljava/net/SocketAddress;
- */
-JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_SctpNet_getLocalAddresses0
- (JNIEnv *env, jclass klass, jint fd) {
- void *addr_buf, *laddr;
- struct sockaddr* sap;
- int i, addrCount;
- jobjectArray isaa;
-
-#ifdef __solaris__
- if ((addrCount = nio_sctp_getladdrs(fd, 0, (void **)&addr_buf)) == -1) {
-#else /* __linux__ */
- if ((addrCount = nio_sctp_getladdrs(fd, 0, (struct sockaddr **)&addr_buf)) == -1) {
-#endif
- handleSocketError(env, errno);
- return NULL;
- }
-
- if (addrCount < 1)
- return NULL;
-
- if (isaCls == 0) {
- initializeISA(env);
- CHECK_NULL_RETURN(isaCls, NULL);
- }
-
- isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);
- if (isaa == NULL) {
- nio_sctp_freeladdrs(addr_buf);
- return NULL;
- }
-
- laddr = addr_buf;
- for (i=0; i<addrCount; i++) {
- int port = 0;
- jobject isa = NULL, ia;
- sap = (struct sockaddr*)addr_buf;
- ia = NET_SockaddrToInetAddress(env, sap, &port);
- if (ia != NULL)
- isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
- if (isa != NULL)
- (*env)->SetObjectArrayElement(env, isaa, i, isa);
-
- if (sap->sa_family == AF_INET)
- addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
- else
- addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;
- }
-
- nio_sctp_freeladdrs(laddr);
- return isaa;
-}
-
-jobjectArray getRemoteAddresses
- (JNIEnv *env, jint fd, sctp_assoc_t id) {
- void *addr_buf, *paddr;
- struct sockaddr* sap;
- int i, addrCount;
- jobjectArray isaa;
-
-#if __solaris__
- if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) {
-#else /* __linux__ */
- if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr**)&addr_buf)) == -1) {
-#endif
- handleSocketError(env, errno);
- return NULL;
- }
-
- if (addrCount < 1)
- return NULL;
-
- if (isaCls == 0) {
- initializeISA(env);
- CHECK_NULL_RETURN(isaCls, NULL);
- }
-
- isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);
- if (isaa == NULL) {
- nio_sctp_freepaddrs(addr_buf);
- return NULL;
- }
-
- paddr = addr_buf;
- for (i=0; i<addrCount; i++) {
- jobject ia, isa = NULL;
- int port;
- sap = (struct sockaddr*)addr_buf;
- ia = NET_SockaddrToInetAddress(env, sap, &port);
- if (ia != NULL)
- isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
- if (isa != NULL)
- (*env)->SetObjectArrayElement(env, isaa, i, isa);
-
- if (sap->sa_family == AF_INET)
- addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
- else
- addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;
- }
-
- nio_sctp_freepaddrs(paddr);
-
- return isaa;
-}
-
- /*
- * Class: sun_nio_ch_SctpNet
- * Method: getRemoteAddresses0
- * Signature: (II)[Ljava/net/SocketAddress;
- */
-JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_SctpNet_getRemoteAddresses0
- (JNIEnv *env, jclass klass, jint fd, jint assocId) {
- return getRemoteAddresses(env, fd, assocId);
-}
-
-/* Map the Java level option to the native level */
-int mapSocketOption
- (jint cmd, int *level, int *optname) {
- static struct {
- jint cmd;
- int level;
- int optname;
- } const opts[] = {
- { sun_nio_ch_SctpStdSocketOption_SCTP_DISABLE_FRAGMENTS, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS },
- { sun_nio_ch_SctpStdSocketOption_SCTP_EXPLICIT_COMPLETE, IPPROTO_SCTP, SCTP_EXPLICIT_EOR },
- { sun_nio_ch_SctpStdSocketOption_SCTP_FRAGMENT_INTERLEAVE, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE },
- { sun_nio_ch_SctpStdSocketOption_SCTP_NODELAY, IPPROTO_SCTP, SCTP_NODELAY },
- { sun_nio_ch_SctpStdSocketOption_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },
- { sun_nio_ch_SctpStdSocketOption_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
- { sun_nio_ch_SctpStdSocketOption_SO_LINGER, SOL_SOCKET, SO_LINGER } };
-
- int i;
- for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) {
- if (cmd == opts[i].cmd) {
- *level = opts[i].level;
- *optname = opts[i].optname;
- return 0;
- }
- }
-
- /* not found */
- return -1;
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: setIntOption0
- * Signature: (III)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_setIntOption0
- (JNIEnv *env, jclass klass, jint fd, jint opt, int arg) {
- int klevel, kopt;
- int result;
- struct linger linger;
- void *parg;
- int arglen;
-
- if (mapSocketOption(opt, &klevel, &kopt) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Unsupported socket option");
- return;
- }
-
- if (opt == sun_nio_ch_SctpStdSocketOption_SO_LINGER) {
- parg = (void *)&linger;
- arglen = sizeof(linger);
- if (arg >= 0) {
- linger.l_onoff = 1;
- linger.l_linger = arg;
- } else {
- linger.l_onoff = 0;
- linger.l_linger = 0;
- }
- } else {
- parg = (void *)&arg;
- arglen = sizeof(arg);
- }
-
- if (NET_SetSockOpt(fd, klevel, kopt, parg, arglen) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun_nio_ch_SctpNet.setIntOption0");
- }
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: getIntOption0
- * Signature: (II)I
- */
-JNIEXPORT int JNICALL Java_sun_nio_ch_SctpNet_getIntOption0
- (JNIEnv *env, jclass klass, jint fd, jint opt) {
- int klevel, kopt;
- int result;
- struct linger linger;
- void *arg;
- int arglen;
-
- if (mapSocketOption(opt, &klevel, &kopt) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Unsupported socket option");
- return -1;
- }
-
- if (opt == sun_nio_ch_SctpStdSocketOption_SO_LINGER) {
- arg = (void *)&linger;
- arglen = sizeof(linger);
- } else {
- arg = (void *)&result;
- arglen = sizeof(result);
- }
-
- if (NET_GetSockOpt(fd, klevel, kopt, arg, &arglen) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun.nio.ch.Net.getIntOption");
- return -1;
- }
-
- if (opt == sun_nio_ch_SctpStdSocketOption_SO_LINGER)
- return linger.l_onoff ? linger.l_linger : -1;
- else
- return result;
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: getPrimAddrOption0
- * Signature: (II)Ljava/net/SocketAddress;
- */
-JNIEXPORT jobject JNICALL Java_sun_nio_ch_SctpNet_getPrimAddrOption0
- (JNIEnv *env, jclass klass, jint fd, jint assocId) {
- struct sctp_setprim prim;
- unsigned int prim_len = sizeof(prim);
- struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
-
- prim.ssp_assoc_id = assocId;
-
- if (getsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, &prim_len) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun.nio.ch.SctpNet.getPrimAddrOption0");
- return NULL;
- }
-
- return SockAddrToInetSocketAddress(env, sap);
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: setPrimAddrOption0
- * Signature: (IILjava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_setPrimAddrOption0
- (JNIEnv *env, jclass klass, jint fd, jint assocId, jobject iaObj, jint port) {
- struct sctp_setprim prim;
- struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
- int sap_len;
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
- &sap_len, JNI_TRUE) != 0) {
- return;
- }
-
- prim.ssp_assoc_id = assocId;
-
- if (setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, sizeof(prim)) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun.nio.ch.SctpNet.setPrimAddrOption0");
- }
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: setPeerPrimAddrOption0
- * Signature: (IILjava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_setPeerPrimAddrOption0
- (JNIEnv *env, jclass klass, jint fd, jint assocId,
- jobject iaObj, jint port, jboolean preferIPv6) {
- struct sctp_setpeerprim prim;
- struct sockaddr* sap = (struct sockaddr*)&prim.sspp_addr;
- int sap_len;
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
- &sap_len, preferIPv6) != 0) {
- return;
- }
-
- prim.sspp_assoc_id = assocId;
-
- if (setsockopt(fd, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, &prim,
- sizeof(prim)) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun.nio.ch.SctpNet.setPeerPrimAddrOption0");
- }
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: getInitMsgOption0
- * Signature: (I[I)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_getInitMsgOption0
- (JNIEnv *env, jclass klass, jint fd, jintArray retVal) {
- struct sctp_initmsg sctp_initmsg;
- unsigned int sim_len = sizeof(sctp_initmsg);
- int vals[2];
-
- if (getsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,
- &sim_len) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun.nio.ch.SctpNet.getInitMsgOption0");
- return;
- }
-
- vals[0] = sctp_initmsg.sinit_max_instreams;
- vals[1] = sctp_initmsg.sinit_num_ostreams;
- (*env)->SetIntArrayRegion(env, retVal, 0, 2, vals);
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: setInitMsgOption0
- * Signature: (III)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_setInitMsgOption0
- (JNIEnv *env, jclass klass, jint fd, jint inArg, jint outArg) {
- struct sctp_initmsg sctp_initmsg;
-
- sctp_initmsg.sinit_max_instreams = (unsigned int)inArg;
- sctp_initmsg.sinit_num_ostreams = (unsigned int)outArg;
- sctp_initmsg.sinit_max_attempts = 0; // default
- sctp_initmsg.sinit_max_init_timeo = 0; // default
-
- if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,
- sizeof(sctp_initmsg)) < 0) {
- JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "sun.nio.ch.SctpNet.setInitMsgOption0");
- }
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: shutdown0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpNet_shutdown0
- (JNIEnv *env, jclass klass, jint fd, jint assocId) {
- int rv;
- struct msghdr msg[1];
- struct iovec iov[1];
- int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
- char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
- struct cmsghdr* cmsg;
- struct sctp_sndrcvinfo *sri;
-
- /* SctpSocketChannel */
- if (assocId < 0) {
- shutdown(fd, SHUT_WR);
- return;
- }
-
- memset(msg, 0, sizeof (*msg));
- memset(cbuf, 0, cbuf_size);
- msg->msg_name = NULL;
- msg->msg_namelen = 0;
- iov->iov_base = NULL;
- iov->iov_len = 0;
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
- msg->msg_control = cbuf;
- msg->msg_controllen = cbuf_size;
- msg->msg_flags = 0;
-
- cmsg = CMSG_FIRSTHDR(msg);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
-
- /* Initialize the payload: */
- sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
- memset(sri, 0, sizeof (*sri));
-
- if (assocId > 0) {
- sri->sinfo_assoc_id = assocId;
- }
-
- sri->sinfo_flags = sri->sinfo_flags | SCTP_EOF;
-
- /* Sum of the length of all control messages in the buffer. */
- msg->msg_controllen = cmsg->cmsg_len;
-
- if ((rv = sendmsg(fd, msg, 0)) < 0) {
- handleSocketError(env, errno);
- }
-}
-
-/*
- * Class: sun_nio_ch_SctpNet
- * Method: branch
- * Signature: (II)I
- */
-JNIEXPORT int JNICALL Java_sun_nio_ch_SctpNet_branch0
- (JNIEnv *env, jclass klass, jint fd, jint assocId) {
- int newfd = 0;
- if ((newfd = nio_sctp_peeloff(fd, assocId)) < 0) {
- handleSocketError(env, errno);
- }
-
- return newfd;
-}
--- a/jdk/src/solaris/native/sun/nio/ch/SctpServerChannelImpl.c Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "sun_nio_ch_SctpServerChannelImpl.h"
-
-extern void Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv* env,
- jclass c);
-
-extern jint Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv* env,
- jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa);
-
-/*
- * Class: sun_nio_ch_SctpServerChannelImpl
- * Method: initIDs
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpServerChannelImpl_initIDs
- (JNIEnv* env, jclass c) {
- Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(env, c);
-}
-
-/*
- * Class: sun_nio_ch_SctpServerChannelImpl
- * Method: accept0
- * Signature: (Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/net/InetSocketAddress;)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpServerChannelImpl_accept0
- (JNIEnv* env, jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa) {
- return Java_sun_nio_ch_ServerSocketChannelImpl_accept0(env, this,
- ssfdo, newfdo, isaa);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SUN_NIO_CH_SCTP_H
+#define SUN_NIO_CH_SCTP_H
+
+#ifdef __solaris__
+
+#define _XPG4_2
+#define __EXTENSIONS__
+#include <sys/socket.h>
+#include <netinet/sctp.h>
+#include "jni.h"
+
+/* Current Solaris headers don't comply with draft rfc */
+#ifndef SCTP_EOF
+#define SCTP_EOF MSG_EOF
+#endif
+
+#ifndef SCTP_UNORDERED
+#define SCTP_UNORDERED MSG_UNORDERED
+#endif
+
+/* The current version of the socket API extension shipped with Solaris does
+ * not define the following options that the Java API (optionally) supports */
+#ifndef SCTP_EXPLICIT_EOR
+#define SCTP_EXPLICIT_EOR -1
+#endif
+#ifndef SCTP_FRAGMENT_INTERLEAVE
+#define SCTP_FRAGMENT_INTERLEAVE -1
+#endif
+#ifndef SCTP_SET_PEER_PRIMARY_ADDR
+#define SCTP_SET_PEER_PRIMARY_ADDR -1
+#endif
+
+/* Function types to support dynamic linking of socket API extension functions
+ * for SCTP. This is so that there is no linkage depandancy during build or
+ * runtime for libsctp.*/
+typedef int sctp_getladdrs_func(int sock, sctp_assoc_t id, void **addrs);
+typedef int sctp_freeladdrs_func(void* addrs);
+typedef int sctp_getpaddrs_func(int sock, sctp_assoc_t id, void **addrs);
+typedef int sctp_freepaddrs_func(void *addrs);
+typedef int sctp_bindx_func(int sock, void *addrs, int addrcnt, int flags);
+typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
+
+
+
+#else /* __linux__ */
+#include <stdint.h>
+#include <linux/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "jni.h"
+
+//Causes compiler error if not found, should make warning and uncomment
+/*#include <netinet/sctp.h>*/
+
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+
+/* The current version of lksctp does
+ * not define the following option that the Java API (optionally) supports */
+#ifndef SCTP_EXPLICIT_EOR
+#define SCTP_EXPLICIT_EOR -1
+#endif
+
+/* Definitions taken from lksctp-tools-1.0.8/src/include/netinet/sctp.h */
+#ifndef SCTP_INITMSG
+
+enum sctp_optname {
+ SCTP_RTOINFO,
+#define SCTP_RTOINFO SCTP_RTOINFO
+ SCTP_ASSOCINFO,
+#define SCTP_ASSOCINFO SCTP_ASSOCINFO
+ SCTP_INITMSG,
+#define SCTP_INITMSG SCTP_INITMSG
+ SCTP_NODELAY, /* Get/set nodelay option. */
+#define SCTP_NODELAY SCTP_NODELAY
+ SCTP_AUTOCLOSE,
+#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE
+ SCTP_SET_PEER_PRIMARY_ADDR,
+#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR
+ SCTP_PRIMARY_ADDR,
+#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR
+ SCTP_ADAPTATION_LAYER,
+#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER
+ SCTP_DISABLE_FRAGMENTS,
+#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS
+ SCTP_PEER_ADDR_PARAMS,
+#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS
+ SCTP_DEFAULT_SEND_PARAM,
+#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM
+ SCTP_EVENTS,
+#define SCTP_EVENTS SCTP_EVENTS
+ SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */
+#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR
+ SCTP_MAXSEG, /* Get/set maximum fragment. */
+#define SCTP_MAXSEG SCTP_MAXSEG
+ SCTP_STATUS,
+#define SCTP_STATUS SCTP_STATUS
+ SCTP_GET_PEER_ADDR_INFO,
+#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
+ SCTP_DELAYED_ACK_TIME,
+#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
+ SCTP_CONTEXT, /* Receive Context */
+#define SCTP_CONTEXT SCTP_CONTEXT
+ SCTP_FRAGMENT_INTERLEAVE,
+#define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE
+ SCTP_PARTIAL_DELIVERY_POINT, /* Set/Get partial delivery point */
+#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT
+ SCTP_MAX_BURST, /* Set/Get max burst */
+#define SCTP_MAX_BURST SCTP_MAX_BURST
+};
+
+enum sctp_sac_state {
+ SCTP_COMM_UP,
+ SCTP_COMM_LOST,
+ SCTP_RESTART,
+ SCTP_SHUTDOWN_COMP,
+ SCTP_CANT_STR_ASSOC,
+};
+
+enum sctp_spc_state {
+ SCTP_ADDR_AVAILABLE,
+ SCTP_ADDR_UNREACHABLE,
+ SCTP_ADDR_REMOVED,
+ SCTP_ADDR_ADDED,
+ SCTP_ADDR_MADE_PRIM,
+ SCTP_ADDR_CONFIRMED,
+};
+
+enum sctp_sinfo_flags {
+ SCTP_UNORDERED = 1, /* Send/receive message unordered. */
+ SCTP_ADDR_OVER = 2, /* Override the primary destination. */
+ SCTP_ABORT=4, /* Send an ABORT message to the peer. */
+ SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */
+};
+
+enum sctp_sn_type {
+ SCTP_SN_TYPE_BASE = (1<<15),
+ SCTP_ASSOC_CHANGE,
+ SCTP_PEER_ADDR_CHANGE,
+ SCTP_SEND_FAILED,
+ SCTP_REMOTE_ERROR,
+ SCTP_SHUTDOWN_EVENT,
+ SCTP_PARTIAL_DELIVERY_EVENT,
+ SCTP_ADAPTATION_INDICATION,
+};
+
+typedef enum sctp_cmsg_type {
+ SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */
+#define SCTP_INIT SCTP_INIT
+ SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */
+#define SCTP_SNDRCV SCTP_SNDRCV
+} sctp_cmsg_t;
+
+enum sctp_msg_flags {
+ MSG_NOTIFICATION = 0x8000,
+#define MSG_NOTIFICATION MSG_NOTIFICATION
+};
+
+#define SCTP_BINDX_ADD_ADDR 0x01
+#define SCTP_BINDX_REM_ADDR 0x02
+
+typedef __s32 sctp_assoc_t;
+
+struct sctp_initmsg {
+ __u16 sinit_num_ostreams;
+ __u16 sinit_max_instreams;
+ __u16 sinit_max_attempts;
+ __u16 sinit_max_init_timeo;
+};
+
+struct sctp_sndrcvinfo {
+ __u16 sinfo_stream;
+ __u16 sinfo_ssn;
+ __u16 sinfo_flags;
+ __u32 sinfo_ppid;
+ __u32 sinfo_context;
+ __u32 sinfo_timetolive;
+ __u32 sinfo_tsn;
+ __u32 sinfo_cumtsn;
+ sctp_assoc_t sinfo_assoc_id;
+};
+
+struct sctp_event_subscribe {
+ __u8 sctp_data_io_event;
+ __u8 sctp_association_event;
+ __u8 sctp_address_event;
+ __u8 sctp_send_failure_event;
+ __u8 sctp_peer_error_event;
+ __u8 sctp_shutdown_event;
+ __u8 sctp_partial_delivery_event;
+ __u8 sctp_adaptation_layer_event;
+};
+
+struct sctp_send_failed {
+ __u16 ssf_type;
+ __u16 ssf_flags;
+ __u32 ssf_length;
+ __u32 ssf_error;
+ struct sctp_sndrcvinfo ssf_info;
+ sctp_assoc_t ssf_assoc_id;
+ __u8 ssf_data[0];
+};
+
+struct sctp_assoc_change {
+ __u16 sac_type;
+ __u16 sac_flags;
+ __u32 sac_length;
+ __u16 sac_state;
+ __u16 sac_error;
+ __u16 sac_outbound_streams;
+ __u16 sac_inbound_streams;
+ sctp_assoc_t sac_assoc_id;
+ __u8 sac_info[0];
+};
+
+struct sctp_shutdown_event {
+ __u16 sse_type;
+ __u16 sse_flags;
+ __u32 sse_length;
+ sctp_assoc_t sse_assoc_id;
+};
+
+struct sctp_paddr_change {
+ __u16 spc_type;
+ __u16 spc_flags;
+ __u32 spc_length;
+ struct sockaddr_storage spc_aaddr;
+ int spc_state;
+ int spc_error;
+ sctp_assoc_t spc_assoc_id;
+} __attribute__((packed, aligned(4)));
+
+struct sctp_remote_error {
+ __u16 sre_type;
+ __u16 sre_flags;
+ __u32 sre_length;
+ __u16 sre_error;
+ sctp_assoc_t sre_assoc_id;
+ __u8 sre_data[0];
+};
+
+struct sctp_adaptation_event {
+ __u16 sai_type;
+ __u16 sai_flags;
+ __u32 sai_length;
+ __u32 sai_adaptation_ind;
+ sctp_assoc_t sai_assoc_id;
+};
+
+struct sctp_setprim {
+ sctp_assoc_t ssp_assoc_id;
+ struct sockaddr_storage ssp_addr;
+} __attribute__((packed, aligned(4)));
+
+struct sctp_setpeerprim {
+ sctp_assoc_t sspp_assoc_id;
+ struct sockaddr_storage sspp_addr;
+} __attribute__((packed, aligned(4)));
+
+
+struct sctp_pdapi_event {
+ __u16 pdapi_type;
+ __u16 pdapi_flags;
+ __u32 pdapi_length;
+ __u32 pdapi_indication;
+ sctp_assoc_t pdapi_assoc_id;
+};
+
+union sctp_notification {
+ struct {
+ __u16 sn_type; /* Notification type. */
+ __u16 sn_flags;
+ __u32 sn_length;
+ } sn_header;
+ struct sctp_assoc_change sn_assoc_change;
+ struct sctp_paddr_change sn_paddr_change;
+ struct sctp_remote_error sn_remote_error;
+ struct sctp_send_failed sn_send_failed;
+ struct sctp_shutdown_event sn_shutdown_event;
+ struct sctp_adaptation_event sn_adaptation_event;
+ struct sctp_pdapi_event sn_pdapi_event;
+};
+
+#endif /* SCTP_INITMSG */
+
+/* Function types to support dynamic linking of socket API extension functions
+ * for SCTP. This is so that there is no linkage depandancy during build or
+ * runtime for libsctp.*/
+typedef int sctp_getladdrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
+typedef int sctp_freeladdrs_func(struct sockaddr *addrs);
+typedef int sctp_getpaddrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
+typedef int sctp_freepaddrs_func(struct sockaddr *addrs);
+typedef int sctp_bindx_func(int sd, struct sockaddr *addrs, int addrcnt, int flags);
+typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
+
+
+#endif /* __linux__ */
+
+sctp_getladdrs_func* nio_sctp_getladdrs;
+sctp_freeladdrs_func* nio_sctp_freeladdrs;
+sctp_getpaddrs_func* nio_sctp_getpaddrs;
+sctp_freepaddrs_func* nio_sctp_freepaddrs;
+sctp_bindx_func* nio_sctp_bindx;
+sctp_peeloff_func* nio_sctp_peeloff;
+
+jboolean loadSocketExtensionFuncs(JNIEnv* env);
+
+#endif /* !SUN_NIO_CH_SCTP_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "Sctp.h"
+
+#include "jni.h"
+#include "nio_util.h"
+#include "nio.h"
+#include "net_util.h"
+#include "net_util_md.h"
+#include "sun_nio_ch_sctp_SctpNet.h"
+#include "sun_nio_ch_sctp_SctpChannelImpl.h"
+#include "sun_nio_ch_sctp_AssociationChange.h"
+#include "sun_nio_ch_sctp_ResultContainer.h"
+#include "sun_nio_ch_sctp_PeerAddrChange.h"
+
+/* sizeof(union sctp_notification */
+#define NOTIFICATION_BUFFER_SIZE 280
+
+#define MESSAGE_IMPL_CLASS "sun/nio/ch/sctp/MessageInfoImpl"
+#define RESULT_CONTAINER_CLASS "sun/nio/ch/sctp/ResultContainer"
+#define SEND_FAILED_CLASS "sun/nio/ch/sctp/SendFailed"
+#define ASSOC_CHANGE_CLASS "sun/nio/ch/sctp/AssociationChange"
+#define PEER_CHANGE_CLASS "sun/nio/ch/sctp/PeerAddrChange"
+#define SHUTDOWN_CLASS "sun/nio/ch/sctp/Shutdown"
+
+struct controlData {
+ int assocId;
+ unsigned short streamNumber;
+ jboolean unordered;
+ unsigned int ppid;
+};
+
+static jclass smi_class; /* sun.nio.ch.sctp.MessageInfoImpl */
+static jmethodID smi_ctrID; /* sun.nio.ch.sctp.MessageInfoImpl.<init> */
+static jfieldID src_valueID; /* sun.nio.ch.sctp.ResultContainer.value */
+static jfieldID src_typeID; /* sun.nio.ch.sctp.ResultContainer.type */
+static jclass ssf_class; /* sun.nio.ch.sctp.SendFailed */
+static jmethodID ssf_ctrID; /* sun.nio.ch.sctp.SendFailed.<init> */
+static jclass sac_class; /* sun.nio.ch.sctp.AssociationChange */
+static jmethodID sac_ctrID; /* sun.nio.ch.sctp.AssociationChange.<init> */
+static jclass spc_class; /* sun.nio.ch.sctp.PeerAddressChanged */
+static jmethodID spc_ctrID; /* sun.nio.ch.sctp.PeerAddressChanged.<init> */
+static jclass ss_class; /* sun.nio.ch.sctp.Shutdown */
+static jmethodID ss_ctrID; /* sun.nio.ch.sctp.Shutdown.<init> */
+static jfieldID isa_addrID; /* java.net.InetSocketAddress.addr */
+static jfieldID isa_portID; /* java.net.InetSocketAddress.port */
+
+/* defined in SctpNet.c */
+jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
+
+jint handleSocketError(JNIEnv *env, jint errorValue);
+
+/* use SocketChannelImpl's checkConnect implementation */
+extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
+ jobject this, jobject fdo, jboolean block, jboolean ready);
+
+/*
+ * Class: sun_nio_ch_sctp_SctpChannelImpl
+ * Method: initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_initIDs
+ (JNIEnv *env, jclass klass) {
+ jclass cls;
+
+ /* MessageInfoImpl */
+ cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
+ CHECK_NULL(cls);
+ smi_class = (*env)->NewGlobalRef(env, cls);
+ CHECK_NULL(smi_class);
+ smi_ctrID = (*env)->GetMethodID(env, cls, "<init>",
+ "(ILjava/net/SocketAddress;IIZZI)V");
+ CHECK_NULL(smi_ctrID);
+
+ /* ResultContainer */
+ cls = (*env)->FindClass(env, RESULT_CONTAINER_CLASS);
+ CHECK_NULL(cls);
+ src_valueID = (*env)->GetFieldID(env, cls, "value", "Ljava/lang/Object;");
+ CHECK_NULL(src_valueID);
+ src_typeID = (*env)->GetFieldID(env, cls, "type", "I");
+ CHECK_NULL(src_typeID);
+
+ /* SendFailed */
+ cls = (*env)->FindClass(env, SEND_FAILED_CLASS);
+ CHECK_NULL(cls);
+ ssf_class = (*env)->NewGlobalRef(env, cls);
+ CHECK_NULL(ssf_class);
+ ssf_ctrID = (*env)->GetMethodID(env, cls, "<init>",
+ "(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
+ CHECK_NULL(ssf_ctrID);
+
+ /* AssociationChange */
+ cls = (*env)->FindClass(env, ASSOC_CHANGE_CLASS);
+ CHECK_NULL(cls);
+ sac_class = (*env)->NewGlobalRef(env, cls);
+ CHECK_NULL(sac_class);
+ sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
+ CHECK_NULL(sac_ctrID);
+
+ /* PeerAddrChange */
+ cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
+ CHECK_NULL(cls);
+ spc_class = (*env)->NewGlobalRef(env, cls);
+ CHECK_NULL(spc_class);
+ spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
+ "(ILjava/net/SocketAddress;I)V");
+ CHECK_NULL(spc_ctrID);
+
+ /* Shutdown */
+ cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
+ CHECK_NULL(cls);
+ ss_class = (*env)->NewGlobalRef(env, cls);
+ CHECK_NULL(ss_class);
+ ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
+ CHECK_NULL(ss_ctrID);
+
+ /* InetSocketAddress */
+ cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL(cls);
+ isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
+ CHECK_NULL(isa_addrID);
+ isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
+}
+
+void getControlData
+ (struct msghdr* msg, struct controlData* cdata) {
+ struct cmsghdr* cmsg;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
+ struct sctp_sndrcvinfo *sri;
+
+ sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
+ cdata->assocId = sri->sinfo_assoc_id;
+ cdata->streamNumber = sri->sinfo_stream;
+ cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
+ JNI_FALSE;
+ cdata->ppid = ntohl(sri->sinfo_ppid);
+
+ return;
+ }
+ }
+ return;
+}
+
+void setControlData
+ (struct msghdr* msg, struct controlData* cdata) {
+ struct cmsghdr* cmsg;
+ struct sctp_sndrcvinfo *sri;
+
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ /* Initialize the payload */
+ sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
+ memset(sri, 0, sizeof (*sri));
+
+ if (cdata->streamNumber > 0) {
+ sri->sinfo_stream = cdata->streamNumber;
+ }
+ if (cdata->assocId > 0) {
+ sri->sinfo_assoc_id = cdata->assocId;
+ }
+ if (cdata->unordered == JNI_TRUE) {
+ sri->sinfo_flags = sri->sinfo_flags | SCTP_UNORDERED;
+ }
+
+ if (cdata->ppid > 0) {
+ sri->sinfo_ppid = htonl(cdata->ppid);
+ }
+
+ /* Sum of the length of all control messages in the buffer. */
+ msg->msg_controllen = cmsg->cmsg_len;
+}
+
+// TODO: test: can create send failed without any data? if so need to
+// update API so that buffer can be null if no data.
+void handleSendFailed
+ (JNIEnv* env, int fd, jobject resultContainerObj, struct sctp_send_failed *ssf,
+ int read, jboolean isEOR, struct sockaddr* sap) {
+ jobject bufferObj = NULL, resultObj, isaObj;
+ char *addressP;
+ struct sctp_sndrcvinfo *sri;
+ int remaining, dataLength;
+
+ /* the actual undelivered message data is directly after the ssf */
+ int dataOffset = sizeof(struct sctp_send_failed);
+
+ sri = (struct sctp_sndrcvinfo*) &ssf->ssf_info;
+
+ /* the number of bytes remaining to be read in the sctp_send_failed notif*/
+ remaining = ssf->ssf_length - read;
+
+ /* the size of the actual undelivered message */
+ dataLength = ssf->ssf_length - dataOffset;
+
+ /* retrieved address from sockaddr */
+ isaObj = SockAddrToInetSocketAddress(env, sap);
+
+ /* data retrieved from sff_data */
+ if (dataLength > 0) {
+ struct iovec iov[1];
+ struct msghdr msg[1];
+ int rv, alreadyRead;
+ char *dataP = (char*) ssf;
+ dataP += dataOffset;
+
+ if ((addressP = malloc(dataLength)) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "handleSendFailed");
+ return;
+ }
+
+ memset(msg, 0, sizeof (*msg));
+ msg->msg_iov = iov;
+ msg->msg_iovlen = 1;
+
+ bufferObj = (*env)->NewDirectByteBuffer(env, addressP, dataLength);
+ CHECK_NULL(bufferObj);
+
+ alreadyRead = read - dataOffset;
+ if (alreadyRead > 0) {
+ memcpy(addressP, /*ssf->ssf_data*/ dataP, alreadyRead);
+ iov->iov_base = addressP + alreadyRead;
+ iov->iov_len = dataLength - alreadyRead;
+ } else {
+ iov->iov_base = addressP;
+ iov->iov_len = dataLength;
+ }
+
+ if (remaining > 0) {
+ if ((rv = recvmsg(fd, msg, 0)) < 0) {
+ handleSocketError(env, errno);
+ return;
+ }
+
+ if (rv != (dataLength - alreadyRead) || !(msg->msg_flags & MSG_EOR)) {
+ //TODO: assert false: "should not reach here";
+ return;
+ }
+ // TODO: Set and document (in API) buffers position.
+ }
+ }
+
+ /* create SendFailed */
+ resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
+ isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
+ CHECK_NULL(resultObj);
+ (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
+ (*env)->SetIntField(env, resultContainerObj, src_typeID,
+ sun_nio_ch_sctp_ResultContainer_SEND_FAILED);
+}
+
+void handleAssocChange
+ (JNIEnv* env, jobject resultContainerObj, struct sctp_assoc_change *sac) {
+ jobject resultObj;
+ int state = 0;
+
+ switch (sac->sac_state) {
+ case SCTP_COMM_UP :
+ state = sun_nio_ch_sctp_AssociationChange_SCTP_COMM_UP;
+ break;
+ case SCTP_COMM_LOST :
+ state = sun_nio_ch_sctp_AssociationChange_SCTP_COMM_LOST;
+ break;
+ case SCTP_RESTART :
+ state = sun_nio_ch_sctp_AssociationChange_SCTP_RESTART;
+ break;
+ case SCTP_SHUTDOWN_COMP :
+ state = sun_nio_ch_sctp_AssociationChange_SCTP_SHUTDOWN;
+ break;
+ case SCTP_CANT_STR_ASSOC :
+ state = sun_nio_ch_sctp_AssociationChange_SCTP_CANT_START;
+ }
+
+ /* create AssociationChange */
+ resultObj = (*env)->NewObject(env, sac_class, sac_ctrID, sac->sac_assoc_id,
+ state, sac->sac_outbound_streams, sac->sac_inbound_streams);
+ CHECK_NULL(resultObj);
+ (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
+ (*env)->SetIntField(env, resultContainerObj, src_typeID,
+ sun_nio_ch_sctp_ResultContainer_ASSOCIATION_CHANGED);
+}
+
+void handleShutdown
+ (JNIEnv* env, jobject resultContainerObj, struct sctp_shutdown_event* sse) {
+ /* create Shutdown */
+ jobject resultObj = (*env)->NewObject(env, ss_class, ss_ctrID, sse->sse_assoc_id);
+ CHECK_NULL(resultObj);
+ (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
+ (*env)->SetIntField(env, resultContainerObj, src_typeID,
+ sun_nio_ch_sctp_ResultContainer_SHUTDOWN);
+}
+
+void handlePeerAddrChange
+ (JNIEnv* env, jobject resultContainerObj, struct sctp_paddr_change* spc) {
+ int event = 0;
+ jobject addressObj, resultObj;
+ unsigned int state = spc->spc_state;
+
+ switch (state) {
+ case SCTP_ADDR_AVAILABLE :
+ event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_AVAILABLE;
+ break;
+ case SCTP_ADDR_UNREACHABLE :
+ event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_UNREACHABLE;
+ break;
+ case SCTP_ADDR_REMOVED :
+ event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_REMOVED;
+ break;
+ case SCTP_ADDR_ADDED :
+ event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_ADDED;
+ break;
+ case SCTP_ADDR_MADE_PRIM :
+ event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_MADE_PRIM;
+#ifdef __linux__ /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */
+ break;
+ case SCTP_ADDR_CONFIRMED :
+ event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_CONFIRMED;
+#endif /* __linux__ */
+ }
+
+ addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
+
+ /* create PeerAddressChanged */
+ resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
+ addressObj, event);
+ CHECK_NULL(resultObj);
+ (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
+ (*env)->SetIntField(env, resultContainerObj, src_typeID,
+ sun_nio_ch_sctp_ResultContainer_PEER_ADDRESS_CHANGED);
+}
+
+void handleUninteresting
+ (union sctp_notification *snp) {
+ //fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
+}
+
+/**
+ * Handle notifications from the SCTP stack.
+ * Returns JNI_TRUE if the notification is one that is of interest to the
+ * Java API, otherwise JNI_FALSE.
+ */
+jboolean handleNotification
+ (JNIEnv* env, int fd, jobject resultContainerObj, union sctp_notification* snp,
+ int read, jboolean isEOR, struct sockaddr* sap) {
+ switch (snp->sn_header.sn_type) {
+ case SCTP_SEND_FAILED:
+ handleSendFailed(env, fd, resultContainerObj, &snp->sn_send_failed,
+ read, isEOR, sap);
+ return JNI_TRUE;
+ case SCTP_ASSOC_CHANGE:
+ handleAssocChange(env, resultContainerObj, &snp->sn_assoc_change);
+ return JNI_TRUE;
+ case SCTP_SHUTDOWN_EVENT:
+ handleShutdown(env, resultContainerObj, &snp->sn_shutdown_event);
+ return JNI_TRUE;
+ case SCTP_PEER_ADDR_CHANGE:
+ handlePeerAddrChange(env, resultContainerObj, &snp->sn_paddr_change);
+ return JNI_TRUE;
+ default :
+ /* the Java API is not interested in this event, maybe we are? */
+ handleUninteresting(snp);
+ }
+ return JNI_FALSE;
+}
+
+void handleMessage
+ (JNIEnv* env, jobject resultContainerObj, struct msghdr* msg,int read,
+ jboolean isEOR, struct sockaddr* sap) {
+ jobject isa, resultObj;
+ struct controlData cdata[1];
+
+ if (read == 0) {
+ /* we reached EOF */
+ read = -1;
+ }
+
+ isa = SockAddrToInetSocketAddress(env, sap);
+ getControlData(msg, cdata);
+
+ /* create MessageInfoImpl */
+ resultObj = (*env)->NewObject(env, smi_class, smi_ctrID, cdata->assocId,
+ isa, read, cdata->streamNumber,
+ isEOR ? JNI_TRUE : JNI_FALSE,
+ cdata->unordered, cdata->ppid);
+ CHECK_NULL(resultObj);
+ (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
+ (*env)->SetIntField(env, resultContainerObj, src_typeID,
+ sun_nio_ch_sctp_ResultContainer_MESSAGE);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpChannelImpl
+ * Method: receive0
+ * Signature: (ILsun/nio/ch/sctp/ResultContainer;JIZ)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_receive0
+ (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
+ jlong address, jint length, jboolean peek) {
+ SOCKADDR sa;
+ int sa_len = sizeof(sa);
+ ssize_t rv = 0;
+ jlong *addr = jlong_to_ptr(address);
+ struct iovec iov[1];
+ struct msghdr msg[1];
+ char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
+ int flags = peek == JNI_TRUE ? MSG_PEEK : 0;
+
+ /* Set up the msghdr structure for receiving */
+ memset(msg, 0, sizeof (*msg));
+ msg->msg_name = &sa;
+ msg->msg_namelen = sa_len;
+ iov->iov_base = addr;
+ iov->iov_len = length;
+ msg->msg_iov = iov;
+ msg->msg_iovlen = 1;
+ msg->msg_control = cbuf;
+ msg->msg_controllen = sizeof(cbuf);
+ msg->msg_flags = 0;
+
+ do {
+ if ((rv = recvmsg(fd, msg, flags)) < 0) {
+ if (errno == EWOULDBLOCK) {
+ return IOS_UNAVAILABLE;
+ } else if (errno == EINTR) {
+ return IOS_INTERRUPTED;
+
+#ifdef __linux__
+ } else if (errno == ENOTCONN) {
+ /* ENOTCONN when EOF reached */
+ rv = 0;
+ /* there will be no control data */
+ msg->msg_controllen = 0;
+#endif /* __linux__ */
+
+ } else {
+ handleSocketError(env, errno);
+ return 0;
+ }
+ }
+
+ if (msg->msg_flags & MSG_NOTIFICATION) {
+ char *bufp = (char*)addr;
+ union sctp_notification *snp;
+
+ if (!(msg->msg_flags & MSG_EOR) && length < NOTIFICATION_BUFFER_SIZE) {
+ char buf[NOTIFICATION_BUFFER_SIZE];
+ int rvSAVE = rv;
+ memcpy(buf, addr, rv);
+ iov->iov_base = buf + rv;
+ iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv;
+ if ((rv = recvmsg(fd, msg, flags)) < 0) {
+ handleSocketError(env, errno);
+ return 0;
+ }
+ bufp = buf;
+ rv += rvSAVE;
+ }
+ snp = (union sctp_notification *) bufp;
+ if (handleNotification(env, fd, resultContainerObj, snp, rv,
+ (msg->msg_flags & MSG_EOR),
+ (struct sockaddr*)&sa ) == JNI_TRUE) {
+ /* We have received a notification that is of interest to
+ to the Java API. The appropriate notification will be
+ set in the result container. */
+ return 0;
+ }
+
+ // set iov back to addr, and reset msg_controllen
+ iov->iov_base = addr;
+ iov->iov_len = length;
+ msg->msg_control = cbuf;
+ msg->msg_controllen = sizeof(cbuf);
+ }
+ } while (msg->msg_flags & MSG_NOTIFICATION);
+
+ handleMessage(env, resultContainerObj, msg, rv,
+ (msg->msg_flags & MSG_EOR), (struct sockaddr*)&sa);
+ return rv;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpChannelImpl
+ * Method: send0
+ * Signature: (IJILjava/net/SocketAddress;IIZI)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
+ (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
+ jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
+ jint ppid) {
+ SOCKADDR sa;
+ int sa_len = sizeof(sa);
+ ssize_t rv = 0;
+ jlong *addr = jlong_to_ptr(address);
+ struct iovec iov[1];
+ struct msghdr msg[1];
+ int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
+ char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
+ struct controlData cdata[1];
+
+ /* SctpChannel:
+ * saTarget may contain the preferred address or NULL to use primary,
+ * assocId will always be -1
+ * SctpMultiChannell:
+ * Setup new association, saTarget will contain address, assocId = -1
+ * Association already existing, assocId != -1, saTarget = preferred addr
+ */
+ if (saTarget != NULL /*&& assocId <= 0*/) {
+
+ jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
+ jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
+
+ if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
+ (struct sockaddr *)&sa,
+ &sa_len, JNI_TRUE) != 0) {
+ return IOS_THROWN;
+ }
+ } else {
+ memset(&sa, '\x0', sa_len);
+ sa_len = 0;
+ }
+
+ /* Set up the msghdr structure for sending */
+ memset(msg, 0, sizeof (*msg));
+ memset(cbuf, 0, cbuf_size);
+ msg->msg_name = &sa;
+ msg->msg_namelen = sa_len;
+ iov->iov_base = addr;
+ iov->iov_len = length;
+ msg->msg_iov = iov;
+ msg->msg_iovlen = 1;
+ msg->msg_control = cbuf;
+ msg->msg_controllen = cbuf_size;
+ msg->msg_flags = 0;
+
+ cdata->streamNumber = streamNumber;
+ cdata->assocId = assocId;
+ cdata->unordered = unordered;
+ cdata->ppid = ppid;
+ setControlData(msg, cdata);
+
+ if ((rv = sendmsg(fd, msg, 0)) < 0) {
+ if (errno == EWOULDBLOCK) {
+ return IOS_UNAVAILABLE;
+ } else if (errno == EINTR) {
+ return IOS_INTERRUPTED;
+ } else if (errno == EPIPE) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ "Socket is shutdown for writing");
+ } else {
+ handleSocketError(env, errno);
+ return 0;
+ }
+ }
+
+ return rv;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpChannelImpl
+ * Method: checkConnect
+ * Signature: (Ljava/io/FileDescriptor;ZZ)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_checkConnect
+ (JNIEnv* env, jobject this, jobject fdo, jboolean block, jboolean ready) {
+ return Java_sun_nio_ch_SocketChannelImpl_checkConnect(env, this,
+ fdo, block, ready);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,753 @@
+/*
+ * Copyright (c) 2009, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Sctp.h"
+#include "jni.h"
+#include "jni_util.h"
+#include "nio_util.h"
+#include "nio.h"
+#include "net_util.h"
+#include "net_util_md.h"
+#include "sun_nio_ch_sctp_SctpNet.h"
+#include "sun_nio_ch_sctp_SctpStdSocketOption.h"
+
+static jclass isaCls = 0;
+static jmethodID isaCtrID = 0;
+
+static const char* nativeSctpLib = "libsctp.so.1";
+static jboolean funcsLoaded = JNI_FALSE;
+
+JNIEXPORT jint JNICALL JNI_OnLoad
+ (JavaVM *vm, void *reserved) {
+ return JNI_VERSION_1_2;
+}
+
+static int preCloseFD = -1; /* File descriptor to which we dup other fd's
+ before closing them for real */
+
+/**
+ * Loads the native sctp library that contains the socket extension
+ * functions, as well as locating the individual functions.
+ * There will be a pending exception if this method returns false.
+ */
+jboolean loadSocketExtensionFuncs
+ (JNIEnv* env) {
+ if (dlopen(nativeSctpLib, RTLD_GLOBAL | RTLD_LAZY) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ if ((nio_sctp_getladdrs = (sctp_getladdrs_func*)
+ dlsym(RTLD_DEFAULT, "sctp_getladdrs")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ if ((nio_sctp_freeladdrs = (sctp_freeladdrs_func*)
+ dlsym(RTLD_DEFAULT, "sctp_freeladdrs")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ if ((nio_sctp_getpaddrs = (sctp_getpaddrs_func*)
+ dlsym(RTLD_DEFAULT, "sctp_getpaddrs")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ if ((nio_sctp_freepaddrs = (sctp_freepaddrs_func*)
+ dlsym(RTLD_DEFAULT, "sctp_freepaddrs")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ if ((nio_sctp_bindx = (sctp_bindx_func*)
+ dlsym(RTLD_DEFAULT, "sctp_bindx")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ if ((nio_sctp_peeloff = (sctp_peeloff_func*)
+ dlsym(RTLD_DEFAULT, "sctp_peeloff")) == NULL) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ dlerror());
+ return JNI_FALSE;
+ }
+
+ funcsLoaded = JNI_TRUE;
+ return JNI_TRUE;
+}
+
+jint
+handleSocketError(JNIEnv *env, jint errorValue)
+{
+ char *xn;
+ switch (errorValue) {
+ case EINPROGRESS: /* Non-blocking connect */
+ return 0;
+ case EPROTO:
+ xn= JNU_JAVANETPKG "ProtocolException";
+ break;
+ case ECONNREFUSED:
+ xn = JNU_JAVANETPKG "ConnectException";
+ break;
+ case ETIMEDOUT:
+ xn = JNU_JAVANETPKG "ConnectException";
+ break;
+ case EHOSTUNREACH:
+ xn = JNU_JAVANETPKG "NoRouteToHostException";
+ break;
+ case EADDRINUSE: /* Fall through */
+ case EADDRNOTAVAIL:
+ xn = JNU_JAVANETPKG "BindException";
+ break;
+ default:
+ xn = JNU_JAVANETPKG "SocketException";
+ break;
+ }
+ errno = errorValue;
+ JNU_ThrowByNameWithLastError(env, xn, "NioSocketError");
+ return IOS_THROWN;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_sctp_SctpNet_init
+ (JNIEnv *env, jclass cl) {
+ int sp[2];
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
+ return;
+ }
+ preCloseFD = sp[0];
+ close(sp[1]);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: socket0
+ * Signature: (Z)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpNet_socket0
+ (JNIEnv *env, jclass klass, jboolean oneToOne) {
+ int fd;
+ struct sctp_event_subscribe event;
+#ifdef AF_INET6
+ int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+ int domain = AF_INET;
+#endif
+
+ /* Try to load the socket API extension functions */
+ if (!funcsLoaded && !loadSocketExtensionFuncs(env)) {
+ return 0;
+ }
+
+ fd = socket(domain, (oneToOne ? SOCK_STREAM : SOCK_SEQPACKET), IPPROTO_SCTP);
+
+ if (fd < 0) {
+ return handleSocketError(env, errno);
+ }
+
+ /* Enable events */
+ memset(&event, 0, sizeof(event));
+ event.sctp_data_io_event = 1;
+ event.sctp_association_event = 1;
+ event.sctp_address_event = 1;
+ event.sctp_send_failure_event = 1;
+ //event.sctp_peer_error_event = 1;
+ event.sctp_shutdown_event = 1;
+ //event.sctp_partial_delivery_event = 1;
+ //event.sctp_adaptation_layer_event = 1;
+ if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) {
+ handleSocketError(env, errno);
+ }
+ return fd;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: bindx
+ * Signature: (I[Ljava/net/InetAddress;IIZ)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_bindx
+ (JNIEnv *env, jclass klass, jint fd, jobjectArray addrs, jint port,
+ jint addrsLength, jboolean add, jboolean preferIPv6) {
+ SOCKADDR *sap, *tmpSap;
+ int i, sa_len = sizeof(SOCKADDR);
+ jobject ia;
+
+ if (addrsLength < 1)
+ return;
+
+ if ((sap = calloc(addrsLength, sa_len)) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
+ return;
+ }
+
+ tmpSap = sap;
+ for (i=0; i<addrsLength; i++) {
+ ia = (*env)->GetObjectArrayElement(env, addrs, i);
+ if (NET_InetAddressToSockaddr(env, ia, port, (struct sockaddr*)tmpSap,
+ &sa_len, preferIPv6) != 0) {
+ free(sap);
+ return;
+ }
+ tmpSap++;
+ }
+
+ if (nio_sctp_bindx(fd, (void*)sap, addrsLength, add ? SCTP_BINDX_ADD_ADDR :
+ SCTP_BINDX_REM_ADDR) != 0) {
+ handleSocketError(env, errno);
+ }
+
+ free(sap);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: listen0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_sctp_SctpNet_listen0
+ (JNIEnv *env, jclass cl, jint fd, jint backlog) {
+ if (listen(fd, backlog) < 0)
+ handleSocketError(env, errno);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: connect0
+ * Signature: (ILjava/net/InetAddress;I)I
+ */
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_sctp_SctpNet_connect0
+ (JNIEnv *env, jclass clazz, int fd, jobject iao, jint port) {
+ SOCKADDR sa;
+ int sa_len = SOCKADDR_LEN;
+ int rv;
+
+ if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *) &sa,
+ &sa_len, JNI_TRUE) != 0) {
+ return IOS_THROWN;
+ }
+
+ rv = connect(fd, (struct sockaddr *)&sa, sa_len);
+ if (rv != 0) {
+ if (errno == EINPROGRESS) {
+ return IOS_UNAVAILABLE;
+ } else if (errno == EINTR) {
+ return IOS_INTERRUPTED;
+ }
+ return handleSocketError(env, errno);
+ }
+ return 1;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: close0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_sctp_SctpNet_close0
+ (JNIEnv *env, jclass clazz, jint fd) {
+ if (fd != -1) {
+ int rv = close(fd);
+ if (rv < 0)
+ JNU_ThrowIOExceptionWithLastError(env, "Close failed");
+ }
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: preClose0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_sctp_SctpNet_preClose0
+ (JNIEnv *env, jclass clazz, jint fd) {
+ if (preCloseFD >= 0) {
+ if (dup2(preCloseFD, fd) < 0)
+ JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
+ }
+}
+
+void initializeISA
+ (JNIEnv* env) {
+ if (isaCls == 0) {
+ jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL(c);
+ isaCls = (*env)->NewGlobalRef(env, c);
+ CHECK_NULL(isaCls);
+ (*env)->DeleteLocalRef(env, c);
+ isaCtrID = (*env)->GetMethodID(env, isaCls, "<init>",
+ "(Ljava/net/InetAddress;I)V");
+ }
+}
+
+jobject SockAddrToInetSocketAddress
+ (JNIEnv *env, struct sockaddr* sap) {
+ int port = 0;
+
+ jobject ia = NET_SockaddrToInetAddress(env, sap, &port);
+ if (ia == NULL)
+ return NULL;
+
+ if (isaCls == 0) {
+ initializeISA(env);
+ CHECK_NULL_RETURN(isaCls, NULL);
+ }
+
+ return (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: getLocalAddresses0
+ * Signature: (I)[Ljava/net/SocketAddress;
+ */
+JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getLocalAddresses0
+ (JNIEnv *env, jclass klass, jint fd) {
+ void *addr_buf, *laddr;
+ struct sockaddr* sap;
+ int i, addrCount;
+ jobjectArray isaa;
+
+#ifdef __solaris__
+ if ((addrCount = nio_sctp_getladdrs(fd, 0, (void **)&addr_buf)) == -1) {
+#else /* __linux__ */
+ if ((addrCount = nio_sctp_getladdrs(fd, 0, (struct sockaddr **)&addr_buf)) == -1) {
+#endif
+ handleSocketError(env, errno);
+ return NULL;
+ }
+
+ if (addrCount < 1)
+ return NULL;
+
+ if (isaCls == 0) {
+ initializeISA(env);
+ CHECK_NULL_RETURN(isaCls, NULL);
+ }
+
+ isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);
+ if (isaa == NULL) {
+ nio_sctp_freeladdrs(addr_buf);
+ return NULL;
+ }
+
+ laddr = addr_buf;
+ for (i=0; i<addrCount; i++) {
+ int port = 0;
+ jobject isa = NULL, ia;
+ sap = (struct sockaddr*)addr_buf;
+ ia = NET_SockaddrToInetAddress(env, sap, &port);
+ if (ia != NULL)
+ isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
+ if (isa != NULL)
+ (*env)->SetObjectArrayElement(env, isaa, i, isa);
+
+ if (sap->sa_family == AF_INET)
+ addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
+ else
+ addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;
+ }
+
+ nio_sctp_freeladdrs(laddr);
+ return isaa;
+}
+
+jobjectArray getRemoteAddresses
+ (JNIEnv *env, jint fd, sctp_assoc_t id) {
+ void *addr_buf, *paddr;
+ struct sockaddr* sap;
+ int i, addrCount;
+ jobjectArray isaa;
+
+#if __solaris__
+ if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) {
+#else /* __linux__ */
+ if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr**)&addr_buf)) == -1) {
+#endif
+ handleSocketError(env, errno);
+ return NULL;
+ }
+
+ if (addrCount < 1)
+ return NULL;
+
+ if (isaCls == 0) {
+ initializeISA(env);
+ CHECK_NULL_RETURN(isaCls, NULL);
+ }
+
+ isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);
+ if (isaa == NULL) {
+ nio_sctp_freepaddrs(addr_buf);
+ return NULL;
+ }
+
+ paddr = addr_buf;
+ for (i=0; i<addrCount; i++) {
+ jobject ia, isa = NULL;
+ int port;
+ sap = (struct sockaddr*)addr_buf;
+ ia = NET_SockaddrToInetAddress(env, sap, &port);
+ if (ia != NULL)
+ isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
+ if (isa != NULL)
+ (*env)->SetObjectArrayElement(env, isaa, i, isa);
+
+ if (sap->sa_family == AF_INET)
+ addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
+ else
+ addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;
+ }
+
+ nio_sctp_freepaddrs(paddr);
+
+ return isaa;
+}
+
+ /*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: getRemoteAddresses0
+ * Signature: (II)[Ljava/net/SocketAddress;
+ */
+JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getRemoteAddresses0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId) {
+ return getRemoteAddresses(env, fd, assocId);
+}
+
+/* Map the Java level option to the native level */
+int mapSocketOption
+ (jint cmd, int *level, int *optname) {
+ static struct {
+ jint cmd;
+ int level;
+ int optname;
+ } const opts[] = {
+ { sun_nio_ch_sctp_SctpStdSocketOption_SCTP_DISABLE_FRAGMENTS, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS },
+ { sun_nio_ch_sctp_SctpStdSocketOption_SCTP_EXPLICIT_COMPLETE, IPPROTO_SCTP, SCTP_EXPLICIT_EOR },
+ { sun_nio_ch_sctp_SctpStdSocketOption_SCTP_FRAGMENT_INTERLEAVE, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE },
+ { sun_nio_ch_sctp_SctpStdSocketOption_SCTP_NODELAY, IPPROTO_SCTP, SCTP_NODELAY },
+ { sun_nio_ch_sctp_SctpStdSocketOption_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },
+ { sun_nio_ch_sctp_SctpStdSocketOption_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
+ { sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER, SOL_SOCKET, SO_LINGER } };
+
+ int i;
+ for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) {
+ if (cmd == opts[i].cmd) {
+ *level = opts[i].level;
+ *optname = opts[i].optname;
+ return 0;
+ }
+ }
+
+ /* not found */
+ return -1;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: setIntOption0
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setIntOption0
+ (JNIEnv *env, jclass klass, jint fd, jint opt, int arg) {
+ int klevel, kopt;
+ int result;
+ struct linger linger;
+ void *parg;
+ int arglen;
+
+ if (mapSocketOption(opt, &klevel, &kopt) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "Unsupported socket option");
+ return;
+ }
+
+ if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER) {
+ parg = (void *)&linger;
+ arglen = sizeof(linger);
+ if (arg >= 0) {
+ linger.l_onoff = 1;
+ linger.l_linger = arg;
+ } else {
+ linger.l_onoff = 0;
+ linger.l_linger = 0;
+ }
+ } else {
+ parg = (void *)&arg;
+ arglen = sizeof(arg);
+ }
+
+ if (NET_SetSockOpt(fd, klevel, kopt, parg, arglen) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun_nio_ch_sctp_SctpNet.setIntOption0");
+ }
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: getIntOption0
+ * Signature: (II)I
+ */
+JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_getIntOption0
+ (JNIEnv *env, jclass klass, jint fd, jint opt) {
+ int klevel, kopt;
+ int result;
+ struct linger linger;
+ void *arg;
+ int arglen;
+
+ if (mapSocketOption(opt, &klevel, &kopt) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "Unsupported socket option");
+ return -1;
+ }
+
+ if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER) {
+ arg = (void *)&linger;
+ arglen = sizeof(linger);
+ } else {
+ arg = (void *)&result;
+ arglen = sizeof(result);
+ }
+
+ if (NET_GetSockOpt(fd, klevel, kopt, arg, &arglen) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.Net.getIntOption");
+ return -1;
+ }
+
+ if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER)
+ return linger.l_onoff ? linger.l_linger : -1;
+ else
+ return result;
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: getPrimAddrOption0
+ * Signature: (II)Ljava/net/SocketAddress;
+ */
+JNIEXPORT jobject JNICALL Java_sun_nio_ch_sctp_SctpNet_getPrimAddrOption0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId) {
+ struct sctp_setprim prim;
+ unsigned int prim_len = sizeof(prim);
+ struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
+
+ prim.ssp_assoc_id = assocId;
+
+ if (getsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, &prim_len) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.SctpNet.getPrimAddrOption0");
+ return NULL;
+ }
+
+ return SockAddrToInetSocketAddress(env, sap);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: setPrimAddrOption0
+ * Signature: (IILjava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPrimAddrOption0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId, jobject iaObj, jint port) {
+ struct sctp_setprim prim;
+ struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
+ int sap_len;
+
+ if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
+ &sap_len, JNI_TRUE) != 0) {
+ return;
+ }
+
+ prim.ssp_assoc_id = assocId;
+
+ if (setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, sizeof(prim)) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.SctpNet.setPrimAddrOption0");
+ }
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: setPeerPrimAddrOption0
+ * Signature: (IILjava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPeerPrimAddrOption0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId,
+ jobject iaObj, jint port, jboolean preferIPv6) {
+ struct sctp_setpeerprim prim;
+ struct sockaddr* sap = (struct sockaddr*)&prim.sspp_addr;
+ int sap_len;
+
+ if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
+ &sap_len, preferIPv6) != 0) {
+ return;
+ }
+
+ prim.sspp_assoc_id = assocId;
+
+ if (setsockopt(fd, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, &prim,
+ sizeof(prim)) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.SctpNet.setPeerPrimAddrOption0");
+ }
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: getInitMsgOption0
+ * Signature: (I[I)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_getInitMsgOption0
+ (JNIEnv *env, jclass klass, jint fd, jintArray retVal) {
+ struct sctp_initmsg sctp_initmsg;
+ unsigned int sim_len = sizeof(sctp_initmsg);
+ int vals[2];
+
+ if (getsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,
+ &sim_len) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.SctpNet.getInitMsgOption0");
+ return;
+ }
+
+ vals[0] = sctp_initmsg.sinit_max_instreams;
+ vals[1] = sctp_initmsg.sinit_num_ostreams;
+ (*env)->SetIntArrayRegion(env, retVal, 0, 2, vals);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: setInitMsgOption0
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setInitMsgOption0
+ (JNIEnv *env, jclass klass, jint fd, jint inArg, jint outArg) {
+ struct sctp_initmsg sctp_initmsg;
+
+ sctp_initmsg.sinit_max_instreams = (unsigned int)inArg;
+ sctp_initmsg.sinit_num_ostreams = (unsigned int)outArg;
+ sctp_initmsg.sinit_max_attempts = 0; // default
+ sctp_initmsg.sinit_max_init_timeo = 0; // default
+
+ if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,
+ sizeof(sctp_initmsg)) < 0) {
+ JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.SctpNet.setInitMsgOption0");
+ }
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: shutdown0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_shutdown0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId) {
+ int rv;
+ struct msghdr msg[1];
+ struct iovec iov[1];
+ int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
+ char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
+ struct cmsghdr* cmsg;
+ struct sctp_sndrcvinfo *sri;
+
+ /* SctpSocketChannel */
+ if (assocId < 0) {
+ shutdown(fd, SHUT_WR);
+ return;
+ }
+
+ memset(msg, 0, sizeof (*msg));
+ memset(cbuf, 0, cbuf_size);
+ msg->msg_name = NULL;
+ msg->msg_namelen = 0;
+ iov->iov_base = NULL;
+ iov->iov_len = 0;
+ msg->msg_iov = iov;
+ msg->msg_iovlen = 1;
+ msg->msg_control = cbuf;
+ msg->msg_controllen = cbuf_size;
+ msg->msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+
+ /* Initialize the payload: */
+ sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
+ memset(sri, 0, sizeof (*sri));
+
+ if (assocId > 0) {
+ sri->sinfo_assoc_id = assocId;
+ }
+
+ sri->sinfo_flags = sri->sinfo_flags | SCTP_EOF;
+
+ /* Sum of the length of all control messages in the buffer. */
+ msg->msg_controllen = cmsg->cmsg_len;
+
+ if ((rv = sendmsg(fd, msg, 0)) < 0) {
+ handleSocketError(env, errno);
+ }
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpNet
+ * Method: branch
+ * Signature: (II)I
+ */
+JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_branch0
+ (JNIEnv *env, jclass klass, jint fd, jint assocId) {
+ int newfd = 0;
+ if ((newfd = nio_sctp_peeloff(fd, assocId)) < 0) {
+ handleSocketError(env, errno);
+ }
+
+ return newfd;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/nio/ch/sctp/SctpServerChannelImpl.c Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "sun_nio_ch_sctp_SctpServerChannelImpl.h"
+
+extern void Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv* env,
+ jclass c);
+
+extern jint Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv* env,
+ jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa);
+
+/*
+ * Class: sun_nio_ch_sctp_SctpServerChannelImpl
+ * Method: initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpServerChannelImpl_initIDs
+ (JNIEnv* env, jclass c) {
+ Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(env, c);
+}
+
+/*
+ * Class: sun_nio_ch_sctp_SctpServerChannelImpl
+ * Method: accept0
+ * Signature: (Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/net/InetSocketAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpServerChannelImpl_accept0
+ (JNIEnv* env, jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa) {
+ return Java_sun_nio_ch_ServerSocketChannelImpl_accept0(env, this,
+ ssfdo, newfdo, isaa);
+}
--- a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Wed Jul 05 18:03:08 2017 +0200
@@ -605,9 +605,12 @@
JNIEXPORT jbyteArray JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
- char entry[sizeof(struct dirent64) + PATH_MAX + 1];
- struct dirent64* ptr = (struct dirent64*)&entry;
struct dirent64* result;
+ struct {
+ struct dirent64 buf;
+ char name_extra[PATH_MAX + 1 - sizeof result->d_name];
+ } entry;
+ struct dirent64* ptr = &entry.buf;
int res;
DIR* dirp = jlong_to_ptr(value);
--- a/jdk/src/windows/classes/sun/nio/ch/SctpChannelImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.SocketAddress;
-import java.net.InetAddress;
-import java.io.IOException;
-import java.util.Set;
-import java.nio.ByteBuffer;
-import java.nio.channels.spi.SelectorProvider;
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.MessageInfo;
-import com.sun.nio.sctp.NotificationHandler;
-import com.sun.nio.sctp.SctpChannel;
-import com.sun.nio.sctp.SctpSocketOption;
-
-/**
- * Unimplemented.
- */
-public class SctpChannelImpl extends SctpChannel
-{
- private static final String message = "SCTP not supported on this platform";
-
- public SctpChannelImpl(SelectorProvider provider) {
- super(provider);
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Association association() {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpChannel bind(SocketAddress local)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpChannel bindAddress(InetAddress address)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpChannel unbindAddress(InetAddress address)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public boolean connect(SocketAddress remote) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public boolean connect(SocketAddress remote, int maxOutStreams,
- int maxInStreams) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public boolean isConnectionPending() {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public boolean finishConnect() throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SocketAddress> getAllLocalAddresses()
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SocketAddress> getRemoteAddresses()
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpChannel shutdown() throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> T getOption(SctpSocketOption<T> name)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SctpSocketOption<?>> supportedOptions() {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> MessageInfo receive(ByteBuffer dst, T attachment,
- NotificationHandler<T> handler) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public int send(ByteBuffer src, MessageInfo messageInfo)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- protected void implConfigureBlocking(boolean block) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public void implCloseSelectableChannel() throws IOException {
- throw new UnsupportedOperationException(message);
- }
-}
--- a/jdk/src/windows/classes/sun/nio/ch/SctpMultiChannelImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.SocketAddress;
-import java.net.InetAddress;
-import java.io.IOException;
-import java.util.Set;
-import java.nio.ByteBuffer;
-import java.nio.channels.spi.SelectorProvider;
-import com.sun.nio.sctp.Association;
-import com.sun.nio.sctp.SctpChannel;
-import com.sun.nio.sctp.MessageInfo;
-import com.sun.nio.sctp.NotificationHandler;
-import com.sun.nio.sctp.SctpMultiChannel;
-import com.sun.nio.sctp.SctpSocketOption;
-
-/**
- * Unimplemented.
- */
-public class SctpMultiChannelImpl extends SctpMultiChannel
-{
- private static final String message = "SCTP not supported on this platform";
-
- public SctpMultiChannelImpl(SelectorProvider provider) {
- super(provider);
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<Association> associations() {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpMultiChannel bind(SocketAddress local,
- int backlog) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpMultiChannel bindAddress(InetAddress address)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpMultiChannel unbindAddress(InetAddress address)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SocketAddress> getAllLocalAddresses()
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SocketAddress> getRemoteAddresses
- (Association association) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpMultiChannel shutdown(Association association)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> T getOption(SctpSocketOption<T> name,
- Association association) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
- T value, Association association) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SctpSocketOption<?>> supportedOptions() {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> MessageInfo receive(ByteBuffer buffer, T attachment,
- NotificationHandler<T> handler) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public int send(ByteBuffer buffer, MessageInfo messageInfo)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpChannel branch(Association association)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- protected void implConfigureBlocking(boolean block) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public void implCloseSelectableChannel() throws IOException {
- throw new UnsupportedOperationException(message);
- }
-}
--- a/jdk/src/windows/classes/sun/nio/ch/SctpServerChannelImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.nio.ch;
-
-import java.net.SocketAddress;
-import java.net.InetAddress;
-import java.io.IOException;
-import java.util.Set;
-import java.nio.channels.spi.SelectorProvider;
-import com.sun.nio.sctp.SctpChannel;
-import com.sun.nio.sctp.SctpServerChannel;
-import com.sun.nio.sctp.SctpSocketOption;
-
-/**
- * Unimplemented.
- */
-public class SctpServerChannelImpl extends SctpServerChannel
-{
- private static final String message = "SCTP not supported on this platform";
-
- public SctpServerChannelImpl(SelectorProvider provider) {
- super(provider);
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpChannel accept() throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpServerChannel bind(SocketAddress local,
- int backlog) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpServerChannel bindAddress(InetAddress address)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public SctpServerChannel unbindAddress(InetAddress address)
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SocketAddress> getAllLocalAddresses()
- throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> T getOption(SctpSocketOption<T> name) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public <T> SctpServerChannel setOption(SctpSocketOption<T> name,
- T value) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public Set<SctpSocketOption<?>> supportedOptions() {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- protected void implConfigureBlocking(boolean block) throws IOException {
- throw new UnsupportedOperationException(message);
- }
-
- @Override
- public void implCloseSelectableChannel() throws IOException {
- throw new UnsupportedOperationException(message);
- }
-}
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -585,7 +585,7 @@
((SelChImpl)selch).kill();
}
- void putEventOps(SelectionKeyImpl sk, int ops) {
+ public void putEventOps(SelectionKeyImpl sk, int ops) {
synchronized (closeLock) {
if (pollWrapper == null)
throw new ClosedSelectorException();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/nio/ch/sctp/SctpChannelImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetAddress;
+import java.io.IOException;
+import java.util.Set;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.NotificationHandler;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+
+/**
+ * Unimplemented.
+ */
+public class SctpChannelImpl extends SctpChannel
+{
+ private static final String message = "SCTP not supported on this platform";
+
+ public SctpChannelImpl(SelectorProvider provider) {
+ super(provider);
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Association association() {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpChannel bind(SocketAddress local)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpChannel bindAddress(InetAddress address)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpChannel unbindAddress(InetAddress address)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public boolean connect(SocketAddress remote) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public boolean connect(SocketAddress remote, int maxOutStreams,
+ int maxInStreams) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public boolean isConnectionPending() {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public boolean finishConnect() throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SocketAddress> getAllLocalAddresses()
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SocketAddress> getRemoteAddresses()
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpChannel shutdown() throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> T getOption(SctpSocketOption<T> name)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SctpSocketOption<?>> supportedOptions() {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> MessageInfo receive(ByteBuffer dst, T attachment,
+ NotificationHandler<T> handler) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public int send(ByteBuffer src, MessageInfo messageInfo)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public void implCloseSelectableChannel() throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetAddress;
+import java.io.IOException;
+import java.util.Set;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.NotificationHandler;
+import com.sun.nio.sctp.SctpMultiChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+
+/**
+ * Unimplemented.
+ */
+public class SctpMultiChannelImpl extends SctpMultiChannel
+{
+ private static final String message = "SCTP not supported on this platform";
+
+ public SctpMultiChannelImpl(SelectorProvider provider) {
+ super(provider);
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<Association> associations() {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpMultiChannel bind(SocketAddress local,
+ int backlog) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpMultiChannel bindAddress(InetAddress address)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpMultiChannel unbindAddress(InetAddress address)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SocketAddress> getAllLocalAddresses()
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SocketAddress> getRemoteAddresses
+ (Association association) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpMultiChannel shutdown(Association association)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> T getOption(SctpSocketOption<T> name,
+ Association association) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
+ T value, Association association) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SctpSocketOption<?>> supportedOptions() {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> MessageInfo receive(ByteBuffer buffer, T attachment,
+ NotificationHandler<T> handler) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public int send(ByteBuffer buffer, MessageInfo messageInfo)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpChannel branch(Association association)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public void implCloseSelectableChannel() throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetAddress;
+import java.io.IOException;
+import java.util.Set;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpServerChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+
+/**
+ * Unimplemented.
+ */
+public class SctpServerChannelImpl extends SctpServerChannel
+{
+ private static final String message = "SCTP not supported on this platform";
+
+ public SctpServerChannelImpl(SelectorProvider provider) {
+ super(provider);
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpChannel accept() throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpServerChannel bind(SocketAddress local,
+ int backlog) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpServerChannel bindAddress(InetAddress address)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public SctpServerChannel unbindAddress(InetAddress address)
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SocketAddress> getAllLocalAddresses()
+ throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> T getOption(SctpSocketOption<T> name) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public <T> SctpServerChannel setOption(SctpSocketOption<T> name,
+ T value) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public Set<SctpSocketOption<?>> supportedOptions() {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+
+ @Override
+ public void implCloseSelectableChannel() throws IOException {
+ throw new UnsupportedOperationException(message);
+ }
+}
--- a/jdk/test/Makefile Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/Makefile Wed Jul 05 18:03:08 2017 +0200
@@ -517,14 +517,14 @@
JDK_ALL_TARGETS += jdk_nio2
JDK_DEFAULT_TARGETS += jdk_nio2
jdk_nio2: $(call TestDirs, java/nio/Buffer java/nio/ByteOrder \
- java/nio/channels java/nio/MappedByteBuffer)
+ java/nio/channels java/nio/MappedByteBuffer sun/nio/ch)
$(call SharedLibraryPermissions,java/nio/channels)
$(call RunAgentvmBatch)
# Stable agentvm testruns (minus items from PROBLEM_LIST)
JDK_ALL_TARGETS += jdk_nio3
JDK_DEFAULT_TARGETS += jdk_nio3
-jdk_nio3: $(call TestDirs, sun/nio)
+jdk_nio3: $(call TestDirs, java/nio/charset sun/nio/cs)
$(call RunAgentvmBatch)
# All nio tests
--- a/jdk/test/ProblemList.txt Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/ProblemList.txt Wed Jul 05 18:03:08 2017 +0200
@@ -211,78 +211,9 @@
# jdk_management
-# Failing, bug was filed: 6959636
-javax/management/loading/LibraryLoader/LibraryLoaderTest.java generic-all
-
-# Access denied messages on windows/mks, filed 6954450
-sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh windows-all
-
-# Fails on linux: KO: StringMonitor notification missed or not emitted
-javax/management/monitor/NonComparableAttributeValueTest.java generic-all
-
-# Port conflict? Fails with communication error
-sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.sh generic-all
-
-# Fails on Windows 2000, Test failed for iiop java.lang.NullPointerException
-# at org.omg.stub.javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke(Unknown Source)
-# at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:653)
-javax/management/remote/mandatory/connection/ReconnectTest.java generic-all
-
-# Solaris 10 sparc, NPE from org.omg.stub.javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke
-javax/management/remote/mandatory/threads/ExecutorTest.java generic-all
-
-# Linux 32bit Fedora 9, IllegalStateException
-javax/management/monitor/RuntimeExceptionTest.java generic-all
-
-# Problems with rmi connection, othervm
-javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java generic-all
-
-# Fails with port already in use
-sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.sh generic-all
-
-# Fails with port already in use
-sun/management/jmxremote/bootstrap/RmiRegistrySslTest.sh generic-all
-
-# Windows, connection can't last that long
-javax/management/eventService/LeaseTest.java generic-all
-
-# Linux othervm, X64, java.lang.Exception: Failed: ratio=102.4027795593753
-javax/management/remote/mandatory/notif/ListenerScaleTest.java generic-all
-
-# Windows run seems to have triggered a hotspot gc error (see 6801625)
-com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.sh generic-all
-
-# rmi problem? othervm, java.lang.reflect.UndeclaredThrowableException
-javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java generic-all
-
-# Linux Fedora 9 32bit NPE in rmi server somehere??? othervm
-javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java generic-all
-
-# Times out on solaris sparc, with othervm
-javax/management/eventService/AddRemoveListenerTest.java generic-all
-
-# Linux i586 and x64 -server, timed out waiting for threads to expire? othervm
-javax/management/eventService/EventClientThreadTest.java generic-all
-
-# Linux i586 -server, Expected to receive 20, but got 21, othervm
-# Fails on Linux X64 -server 20!=21
-javax/management/eventService/FetchingTest.java generic-all
-
-# NPE on windows 2000 i586 -client and -server
-javax/management/eventService/CustomForwarderTest.java windows-all
-
-# Windows i586 failure, callback did not complete
-javax/management/eventService/LeaseManagerDeadlockTest.java windows-all
-
-# Port already in use
-sun/management/jmxremote/bootstrap/LocalManagementTest.sh generic-all
-
-# Failed to initialize connector (also overflowing jtreg io buffers)
-sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh generic-all
-sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh generic-all
-
-# Windows X64, java.lang.IllegalStateException
-javax/management/monitor/AttributeArbitraryDataTypeTest.java generic-all
+# 7073626
+sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh windows-all
+sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh windows-all
############################################################################
@@ -410,71 +341,11 @@
# jdk_rmi
-# Port already in use, fails on sparc, othervm
-java/rmi/reliability/benchmark/runRmiBench.sh generic-all
-
-# Already in use port issues? othervm solaris
-java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java generic-all
-java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java generic-all
-
-java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java generic-all
-java/rmi/transport/dgcDeadLock/TestImpl_Stub.java generic-all
-
-# Address already in use, othervm mode, solaris
-java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java generic-all
-java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java generic-all
-
-# Registry already running on port, solaris
-java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java generic-all
-
-# Fails on Linux 32 and 64bit -server?, impl not garbage collected???
-java/rmi/transport/pinLastArguments/PinLastArguments.java generic-all
-
-# Times out on solaris sparc
-java/rmi/server/RemoteServer/AddrInUse.java generic-all
-
-# Connection error on Windows i586 -server
-# Also connection errors in othervm on Solaris 10 sparc, same port???
-sun/rmi/transport/tcp/DeadCachedConnection.java generic-all
+# 7140992
+java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all
-# Connection errors in othervm on Solaris 10 sparc, same port???
-java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java generic-all
-java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java generic-all
-java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java generic-all
-java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java generic-all
-java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java generic-all
-java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java generic-all
-java/rmi/activation/Activatable/extLoadedImpl/ext.sh generic-all
-java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java generic-all
-java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java generic-all
-java/rmi/activation/Activatable/nestedActivate/NestedActivate.java generic-all
-java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java generic-all
-java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java generic-all
-java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java generic-all
-java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java generic-all
-java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java generic-all
-java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java generic-all
-java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java generic-all
-java/rmi/reliability/juicer/AppleUserImpl.java generic-all
-java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java generic-all
-java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java generic-all
-java/rmi/transport/handshakeTimeout/HandshakeTimeout.java generic-all
-java/rmi/activation/Activatable/restartService/RestartService.java generic-all
-java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java generic-all
-java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java generic-all
-java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java generic-all
-java/rmi/activation/CommandEnvironment/SetChildEnv.java generic-all
-java/rmi/registry/classPathCodebase/ClassPathCodebase.java generic-all
-java/rmi/registry/reexport/Reexport.java generic-all
-java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all
-java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java generic-all
-java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java generic-all
-java/rmi/server/useCustomRef/UseCustomRef.java generic-all
-java/rmi/transport/checkFQDN/CheckFQDN.java generic-all
-java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java generic-all
-java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java generic-all
-java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java generic-all
-java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java generic-all
+# 6948101
+java/rmi/transport/pinLastArguments/PinLastArguments.java generic-all
# 7132247
java/rmi/registry/readTest/readTest.sh windows-all
@@ -557,6 +428,9 @@
# jdk_tools
+# 6461635
+com/sun/tools/attach/BasicTests.sh generic-all
+
# Filed 6952105
com/sun/jdi/SuspendThreadTest.java generic-all
@@ -572,15 +446,16 @@
# Filed 6402201
com/sun/jdi/ProcessAttachTest.sh generic-all
-# Filed 6986875
-sun/tools/jps/jps-Vvml.sh generic-all
-
# Filed 6979016
sun/tools/jconsole/ResourceCheckTest.sh generic-all
# 7132203
sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all
+# Tests take too long
+tools/pack200/CommandLineTests.java generic-all
+tools/pack200/Pack200Test.java generic-all
+
############################################################################
# jdk_util
@@ -588,11 +463,6 @@
# Filed 6933803
java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java generic-all
-# Filed 7022325
-# Fails with assertion error on windows
-# 11 separate stacktraces created... file reuse problem?
-java/util/zip/ZipFile/ReadLongZipFileName.java generic-all
-
# Filed 6772009
java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all
--- a/jdk/test/TEST.ROOT Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/TEST.ROOT Wed Jul 05 18:03:08 2017 +0200
@@ -4,3 +4,9 @@
# The list of keywords supported in the entire test suite
keys=2d dnd i18n
+
+# Tests that must run in othervm mode
+othervm.dirs=java/rmi sun/rmi javax/management
+
+# Tests that cannot run concurrently
+exclusiveAccess.dirs=java/rmi sun/rmi sun/management/jmxremote sun/tools/jstatd
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/ExecuteDiagnosticCommand.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2011, 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 7104647
- * @summary Basic Test for HotSpotDiagnosticMXBean.execute()
- * @author Frederic Parain
- *
- * @run main ExecuteDiagnosticCommand
- */
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.VMOption;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import javax.management.MBeanServer;
-
-public class ExecuteDiagnosticCommand {
- private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
- "com.sun.management:type=HotSpotDiagnostic";
-
- public static void main(String[] args) throws Exception {
- HotSpotDiagnosticMXBean mbean =
- ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
- executeDiagnosticCommand(mbean);
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
- HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
- HotSpotDiagnosticMXBean.class);
- executeDiagnosticCommand(mbean);
- }
-
- private static void executeDiagnosticCommand(HotSpotDiagnosticMXBean mbean) {
- String s = mbean.execute("help help");
- System.out.println(s);
- s = mbean.execute("help", "help");
- System.out.println(s);
- String tab[] = { "help"};
- s = mbean.execute("help", tab);
- System.out.println(s);
- }
-}
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticCommandInfo.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2011, 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 7104647
- * @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticCommandInfo()
- * @author Frederic Parain
- *
- * @run main GetDiagnosticCommandInfo
- */
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.DiagnosticCommandInfo;
-import com.sun.management.DiagnosticCommandArgumentInfo;
-import com.sun.management.VMOption;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import javax.management.MBeanServer;
-
-public class GetDiagnosticCommandInfo {
- private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
- "com.sun.management:type=HotSpotDiagnostic";
-
- public static void main(String[] args) throws Exception {
- HotSpotDiagnosticMXBean mbean =
- ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
- checkDiagnosticCommandArguments(mbean);
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
- HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
- HotSpotDiagnosticMXBean.class);
- checkDiagnosticCommandArguments(mbean);
- }
-
- private static void checkDiagnosticCommandArguments(HotSpotDiagnosticMXBean mbean) {
- // check getDiagnosticCommandInfo()
- StringBuilder sb = new StringBuilder();
- List<DiagnosticCommandInfo> infoList = mbean.getDiagnosticCommandInfo();
- for(DiagnosticCommandInfo info : infoList) {
- printCommandInfo(info,sb);
- }
- // check getDiagnosticCommandInfo(List<String>)
- List<String> commands = mbean.getDiagnosticCommands();
- List<DiagnosticCommandInfo> list2 =
- mbean.getDiagnosticCommandInfo(commands);
- for(DiagnosticCommandInfo info : list2) {
- printCommandInfo(info,sb);
- }
- // check getDiagnosticCommandInfo(String)
- for(String cmd : commands) {
- DiagnosticCommandInfo info2 = mbean.getDiagnosticCommandInfo(cmd);
- printCommandInfo(info2,sb);
- }
- System.out.println(sb.toString());
- }
-
- private static void printCommandInfo(DiagnosticCommandInfo info,
- StringBuilder sb) {
- sb.append("\t").append(info.getName()).append(":\n");
- sb.append("\t\tDescription=").append(info.getDescription()).append("\n");
- sb.append("\t\tImpact=").append(info.getImpact()).append("\n");
- sb.append("\t\tStatus=");
- if (info.isEnabled()) {
- sb.append("Enabled\n");
- } else {
- sb.append("Disbled\n");
- }
- sb.append("\t\tArguments=");
- for(DiagnosticCommandArgumentInfo arg : info.getArgumentsInfo()) {
- printArgumentInfo(arg,sb);
- }
- }
-
- private static void printArgumentInfo(DiagnosticCommandArgumentInfo info,
- StringBuilder sb) {
- sb.append("\t\t\t").append(info.getName()).append(":\n");
- sb.append("\t\t\t\tType=").append(info.getType()).append("\n");
- sb.append("\t\t\t\tDescription=").append(info.getDescription()).append("\n");
- if(info.getDefault() != null) {
- sb.append("\t\t\t\tDefault=").append(info.getDefault()).append("\n");
- }
- if(info.isMandatory()) {
- sb.append("\t\t\t\tMandatory\n");
- } else {
- sb.append("\t\t\t\tOptional\n");
- }
- if(info.isOption()) {
- sb.append("\t\t\t\tIs an option\n");
- } else {
- sb.append("\t\t\t\tIs an argument expected at position");
- sb.append(info.getPosition());
- sb.append("\n");
- }
- }
-}
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticCommands.java Thu Feb 16 13:01:32 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2011, 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 7104647
- * @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticCommands()
- * @author Frederic Parain
- *
- * @run main GetDiagnosticCommands
- */
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.VMOption;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import javax.management.MBeanServer;
-
-public class GetDiagnosticCommands {
- private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
- "com.sun.management:type=HotSpotDiagnostic";
-
- public static void main(String[] args) throws Exception {
- HotSpotDiagnosticMXBean mbean =
- ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
- checkDiagnosticCommands(mbean);
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
- HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
- HotSpotDiagnosticMXBean.class);
- checkDiagnosticCommands(mbean);
- }
-
- private static void checkDiagnosticCommands(HotSpotDiagnosticMXBean mbean) {
- List<String> commands = mbean.getDiagnosticCommands();
- System.out.println("Commands:");
- for (String cmd : commands) {
- System.out.println(cmd);
- }
- }
-}
--- a/jdk/test/java/awt/Choice/ChoiceMouseWheelTest/ChoiceMouseWheelTest.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/awt/Choice/ChoiceMouseWheelTest/ChoiceMouseWheelTest.java Wed Jul 05 18:03:08 2017 +0200
@@ -96,7 +96,10 @@
// Test mouse wheel over the choice
String name = Toolkit.getDefaultToolkit().getClass().getName();
- if(!name.equals("sun.awt.X11.XToolkit")) { // mouse wheel doesn't work for the choice on X11, so skip it
+
+ // mouse wheel doesn't work for the choice on X11 and Mac, so skip it
+ if(!name.equals("sun.awt.X11.XToolkit")
+ && !name.equals("sun.lwawt.macosx.LWCToolkit")) {
robot.mouseWheel(1);
Util.waitForIdle(robot);
--- a/jdk/test/java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java Wed Jul 05 18:03:08 2017 +0200
@@ -54,9 +54,12 @@
Util.clickOnComp(frame.button, robot);
}
- frame.panel.stop();
+ boolean ret = frame.panel.stop();
frame.dispose();
+ if (!ret) {
+ throw new RuntimeException("Test failed!");
+ }
System.out.println("Test passed.");
}
@@ -140,17 +143,19 @@
}
}
- public void stop() {
+ public boolean stop() {
active = false;
try {
- synchronized (sync) {
- sync.notify();
- }
- synchronized (thread) {
- thread.wait();
+ sync();
+ thread.join(1000);
+ if (thread.isAlive()) {
+ thread.interrupt();
+ return false;
}
} catch (InterruptedException ex) {
+ return false;
}
+ return true;
}
public void draw() {
--- a/jdk/test/java/nio/file/WatchService/Basic.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/nio/file/WatchService/Basic.java Wed Jul 05 18:03:08 2017 +0200
@@ -25,7 +25,7 @@
* @bug 4313887 6838333 7017446
* @summary Unit test for java.nio.file.WatchService
* @library ..
- * @run main/timeout=120 Basic
+ * @run main Basic
*/
import java.nio.file.*;
@@ -281,11 +281,11 @@
System.out.println("poll with timeout...");
try {
- long start = System.currentTimeMillis();
+ long start = System.nanoTime();
key = watcher.poll(3000, TimeUnit.MILLISECONDS);
if (key != null)
throw new RuntimeException("no keys registered");
- long waited = System.currentTimeMillis() - start;
+ long waited = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
if (waited < 2900)
throw new RuntimeException("poll was too short");
} catch (InterruptedException x) {
@@ -358,14 +358,14 @@
}
// assume that poll throws exception immediately
- long start = System.currentTimeMillis();
+ long start = System.nanoTime();
try {
watcher.poll(10000, TimeUnit.MILLISECONDS);
throw new RuntimeException("ClosedWatchServiceException not thrown");
} catch (InterruptedException x) {
throw new RuntimeException(x);
} catch (ClosedWatchServiceException x) {
- long waited = System.currentTimeMillis() - start;
+ long waited = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
if (waited > 5000)
throw new RuntimeException("poll was too long");
}
--- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Wed Jul 05 18:03:08 2017 +0200
@@ -23,9 +23,9 @@
/* @test
* @bug 4313887
- * @summary Sanity test for Sun-specific sensitivyt level watch event modifier
+ * @summary Sanity test for Sun-specific sensitivity level watch event modifier
* @library ..
- * @run main/timeout=330 Basic
+ * @run main/timeout=240 SensitivityModifier
*/
import java.nio.file.*;
@@ -96,6 +96,7 @@
// drain events (to avoid interference)
do {
+ key.pollEvents();
key.reset();
key = watcher.poll(1, TimeUnit.SECONDS);
} while (key != null);
--- a/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Wed Jul 05 18:03:08 2017 +0200
@@ -75,10 +75,10 @@
throw new Error("Executor stuck");
// Wait for the invocation thread to complete.
- thread.join(1000);
+ thread.join(5000);
if (thread.isAlive()) {
thread.interrupt();
- thread.join(1000);
+ thread.join(5000);
throw new Error("invokeAll stuck");
}
}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Wed Jul 05 18:03:08 2017 +0200
@@ -100,8 +100,8 @@
equal(countExecutorThreads(), threadCount);
equal(CustomTask.births.get(), threadCount);
tpe.shutdown();
- tpe.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
- Thread.sleep(10);
+ tpe.awaitTermination(120, TimeUnit.SECONDS);
+ Thread.sleep(1000);
equal(countExecutorThreads(), 0);
CustomSTPE stpe = new CustomSTPE();
@@ -110,8 +110,8 @@
equal(CustomSTPE.decorations.get(), threadCount);
equal(countExecutorThreads(), threadCount);
stpe.shutdown();
- stpe.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
- Thread.sleep(10);
+ stpe.awaitTermination(120, TimeUnit.SECONDS);
+ Thread.sleep(1000);
equal(countExecutorThreads(), 0);
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
--- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Wed Jul 05 18:03:08 2017 +0200
@@ -86,7 +86,7 @@
} catch (Throwable t) { unexpected(t); }}});}
barrier.await();
es.shutdown();
- check(es.awaitTermination(10, TimeUnit.SECONDS));
+ check(es.awaitTermination(30, TimeUnit.SECONDS));
}
private static class FlakySync extends AbstractQueuedLongSynchronizer {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/CipherSpi/DirectBBRemaining.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012, 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 7142509
+ * @summary Cipher.doFinal(ByteBuffer,ByteBuffer) fails to
+ * process when in.remaining() == 0
+ */
+
+import java.nio.ByteBuffer;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/*
+ * Simple test case to show that Cipher.doFinal(ByteBuffer, ByteBuffer) fails to
+ * process the data internally buffered inBB the cipher when input.remaining()
+ * == 0 and at least one buffer is a direct buffer.
+ */
+public class DirectBBRemaining {
+
+ private static Random random = new SecureRandom();
+ private static int testSizes = 40;
+ private static int outputFrequency = 5;
+
+ public static void main(String args[]) throws Exception {
+ boolean failedOnce = false;
+ Exception failedReason = null;
+
+ byte[] keyBytes = new byte[8];
+ random.nextBytes(keyBytes);
+ SecretKey key = new SecretKeySpec(keyBytes, "DES");
+
+ Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding", "SunJCE");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+
+ /*
+ * Iterate through various sizes to make sure that the code does empty
+ * blocks, single partial blocks, 1 full block, full + partial blocks,
+ * multiple full blocks, etc. 5 blocks (using DES) is probably overkill
+ * but will feel more confident the fix isn't breaking anything.
+ */
+ System.out.println("Output test results for every "
+ + outputFrequency + " tests...");
+
+ for (int size = 0; size <= testSizes; size++) {
+ boolean output = (size % outputFrequency) == 0;
+ if (output) {
+ System.out.print("\nTesting buffer size: " + size + ":");
+ }
+
+ int outSize = cipher.getOutputSize(size);
+
+ try {
+ encrypt(cipher, size,
+ ByteBuffer.allocate(size),
+ ByteBuffer.allocate(outSize),
+ ByteBuffer.allocateDirect(size),
+ ByteBuffer.allocateDirect(outSize),
+ output);
+ } catch (Exception e) {
+ System.out.print("\n Failed with size " + size);
+ failedOnce = true;
+ failedReason = e;
+
+ // If we got an exception, let's be safe for future
+ // testing and reset the cipher to a known good state.
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ }
+ }
+ if (failedOnce) {
+ throw failedReason;
+ }
+ System.out.println("\nTest Passed...");
+ }
+
+ private enum TestVariant {
+
+ HEAP_HEAP, HEAP_DIRECT, DIRECT_HEAP, DIRECT_DIRECT
+ };
+
+ private static void encrypt(Cipher cipher, int size,
+ ByteBuffer heapIn, ByteBuffer heapOut,
+ ByteBuffer directIn, ByteBuffer directOut,
+ boolean output) throws Exception {
+
+ ByteBuffer inBB = null;
+ ByteBuffer outBB = null;
+
+ // Set up data and encrypt to known/expected values.
+ byte[] testdata = new byte[size];
+ random.nextBytes(testdata);
+ byte[] expected = cipher.doFinal(testdata);
+
+ for (TestVariant tv : TestVariant.values()) {
+ if (output) {
+ System.out.print(" " + tv);
+ }
+
+ switch (tv) {
+ case HEAP_HEAP:
+ inBB = heapIn;
+ outBB = heapOut;
+ break;
+ case HEAP_DIRECT:
+ inBB = heapIn;
+ outBB = directOut;
+ break;
+ case DIRECT_HEAP:
+ inBB = directIn;
+ outBB = heapOut;
+ break;
+ case DIRECT_DIRECT:
+ inBB = directIn;
+ outBB = directOut;
+ break;
+ }
+
+ inBB.clear();
+ outBB.clear();
+
+ inBB.put(testdata);
+ inBB.flip();
+
+ // Process all data in one shot, but don't call doFinal() yet.
+ // May store up to n-1 bytes (w/block size n) internally.
+ cipher.update(inBB, outBB);
+ if (inBB.hasRemaining()) {
+ throw new Exception("buffer not empty");
+ }
+
+ // finish encryption and process all data buffered
+ cipher.doFinal(inBB, outBB);
+ outBB.flip();
+
+ // validate output size
+ if (outBB.remaining() != expected.length) {
+ throw new Exception(
+ "incomplete encryption output, expected "
+ + expected.length + " bytes but was only "
+ + outBB.remaining() + " bytes");
+ }
+
+ // validate output data
+ byte[] encrypted = new byte[outBB.remaining()];
+ outBB.get(encrypted);
+ if (!Arrays.equals(expected, encrypted)) {
+ throw new Exception("bad encryption output");
+ }
+
+ if (!Arrays.equals(cipher.doFinal(), cipher.doFinal())) {
+ throw new Exception("Internal buffers still held data!");
+ }
+ }
+ }
+}
--- a/jdk/test/javax/security/auth/x500/X500Principal/Parse.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/javax/security/auth/x500/X500Principal/Parse.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7024771
+ * @bug 7024771 7024604
* @summary various X500Principal DN parsing tests
*/
@@ -32,12 +32,18 @@
public class Parse {
private static TestCase[] testCases = {
- new TestCase("CN=prefix\\<>suffix", false)
+ new TestCase("CN=prefix\\<>suffix", false),
+ new TestCase("OID.1=value", false),
+ new TestCase("oid.1=value", false),
+ new TestCase("OID.1.2=value", true),
+ new TestCase("oid.1.2=value", true),
+ new TestCase("1=value", false),
+ new TestCase("1.2=value", true)
};
public static void main(String args[]) throws Exception {
- for (int i = 0; i < testCases.length; i++) {
- testCases[i].run();
+ for (TestCase testCase : testCases) {
+ testCase.run();
}
System.out.println("Test completed ok.");
}
--- a/jdk/test/javax/swing/JFileChooser/6396844/TwentyThousandTest.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/javax/swing/JFileChooser/6396844/TwentyThousandTest.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -26,28 +26,29 @@
* @bug 6396844
* @summary Tests memory leak for 20000 files
* @author Sergey Malenkov
- * @run main/othervm/timeout=1000 -mx256m TwentyThousandTest
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main/othervm/timeout=1000 -mx128m TwentyThousandTest
*/
+import sun.java2d.Disposer;
+import sun.java2d.DisposerRecord;
+
import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
import java.io.File;
import java.io.FileWriter;
-public class TwentyThousandTest implements ActionListener, Runnable {
+public class TwentyThousandTest {
private static final int FILES = 20000;
- private static final int ATTEMPTS = 100;
+ private static final int ATTEMPTS = 20;
private static final int INTERVAL = 100;
- private static final boolean ALWAYS_NEW_INSTANCE = false;
- private static final boolean UPDATE_UI_EACH_INTERVAL = true;
- private static final boolean AUTO_CLOSE_DIALOG = true;
+ private static String tmpDir;
- private static JFileChooser CHOOSER;
-
- private static String tmpDir;
+ private static volatile boolean disposerComplete;
public static void main(String[] args) throws Exception {
tmpDir = System.getProperty("java.io.tmpdir");
@@ -77,15 +78,13 @@
System.out.println("Do " + ATTEMPTS + " attempts for " + laf.getClassName());
- for ( int i = 0; i < ATTEMPTS; i++ ) {
+ for (int i = 0; i < ATTEMPTS; i++) {
System.out.print(i + " ");
doAttempt();
}
System.out.println();
-
- CHOOSER = null;
}
System.out.println("Removing " + FILES + " files");
@@ -94,7 +93,7 @@
getTempFile(i).delete();
}
- System.out.println( "Test passed successfully" );
+ System.out.println("Test passed successfully");
}
private static File getTempFile(int i) {
@@ -104,48 +103,55 @@
private static void doAttempt() throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- if ( ALWAYS_NEW_INSTANCE || ( CHOOSER == null ) )
- CHOOSER = new JFileChooser(tmpDir);
+ final JFileChooser chooser = new JFileChooser(tmpDir);
+
+ chooser.updateUI();
- if ( UPDATE_UI_EACH_INTERVAL )
- CHOOSER.updateUI();
+ // Postpone JFileChooser closing until it becomes visible
+ chooser.addHierarchyListener(new HierarchyListener() {
+ @Override
+ public void hierarchyChanged(HierarchyEvent e) {
+ if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
+ if (chooser.isShowing()) {
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(INTERVAL);
- if ( AUTO_CLOSE_DIALOG ) {
- Thread t = new Thread( new TwentyThousandTest( CHOOSER ) );
- t.start();
- CHOOSER.showOpenDialog( null );
- } else {
- CHOOSER.showOpenDialog( null );
- }
+ // Close JFileChooser
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ chooser.cancelSelection();
+ }
+ });
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+
+ thread.start();
+ }
+ }
+ }
+ });
+
+ chooser.showOpenDialog(null);
}
});
- // Allow to collect garbage by GC
- Thread.sleep(1000);
-
- System.gc();
- }
-
- private final JFileChooser chooser;
-
- TwentyThousandTest( JFileChooser chooser ) {
- this.chooser = chooser;
- }
+ DisposerRecord disposerRecord = new DisposerRecord() {
+ public void dispose() {
+ disposerComplete = true;
+ }
+ };
- public void run() {
- while ( !this.chooser.isShowing() ) {
- try {
- Thread.sleep( 30 );
- } catch ( InterruptedException exception ) {
- exception.printStackTrace();
- }
+ disposerComplete = false;
+
+ Disposer.addRecord(new Object(), disposerRecord);
+
+ while (!disposerComplete) {
+ Util.generateOOME();
}
- Timer timer = new Timer( INTERVAL, this );
- timer.setRepeats( false );
- timer.start();
- }
-
- public void actionPerformed( ActionEvent event ) {
- this.chooser.cancelSelection();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JOptionPane/7138665/bug7138665.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, 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 7138665
+ @summary JOptionPane.getValue() unexpected change between JRE 1.6 and JRE 1.7
+ @author Pavel Porvatov
+*/
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+
+public class bug7138665 {
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ JOptionPane pane = new JOptionPane("Enter value", JOptionPane.QUESTION_MESSAGE,
+ JOptionPane.OK_CANCEL_OPTION, null, null, null);
+ pane.setWantsInput(true);
+
+ JDialog dialog = pane.createDialog(null, "My Dialog");
+ dialog.setVisible(true);
+
+ Object result = pane.getValue();
+
+ if (result == null || ((Integer) result).intValue() != JOptionPane.OK_OPTION) {
+ throw new RuntimeException("Invalid result: " + result);
+ }
+
+ System.out.println("Test bug7138665 passed");
+ }
+ });
+
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+ toolkit.realSync();
+
+ Robot robot = new Robot();
+
+ robot.setAutoDelay(100);
+ robot.keyPress(KeyEvent.VK_ENTER);
+ robot.keyRelease(KeyEvent.VK_ENTER);
+
+ toolkit.realSync();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JProgressBar/7141573/bug7141573.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 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 7141573
+ @summary JProgressBar resize exception, if setStringPainted in Windows LAF
+ @author Pavel Porvatov
+*/
+
+import javax.swing.*;
+import java.awt.image.BufferedImage;
+
+public class bug7141573 {
+ public static void main(String[] args) throws Exception {
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+ } catch (Exception e) {
+ System.out.println("WindowsLookAndFeel is not supported. The test bug7141573 is skipped.");
+
+ return;
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
+
+ JProgressBar bar = new JProgressBar();
+
+ bar.setStringPainted(true);
+
+ bar.setSize(100, 1);
+ bar.paint(image.getGraphics());
+
+ bar.setSize(1, 100);
+ bar.paint(image.getGraphics());
+
+ System.out.println("The test bug7141573 is passed.");
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTree/4314199/bug4314199.html Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,8 @@
+<html>
+<body>
+Select the last tree node (marked "Here") and click on the menu.
+Look at the vertical line connecting nodes "Bug" and "Here". If
+this line disappears when the menu drops down, test fails.
+<applet code="bug4314199.class" width=200 height=200></applet>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTree/4314199/bug4314199.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, 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 4314199
+ * @summary Tests that JTree repaints correctly in a container with a JMenu
+ * @author Peter Zhelezniakov
+ * @run applet/manual=yesno bug4314199.html
+ */
+
+import javax.swing.*;
+import javax.swing.tree.*;
+
+public class bug4314199 extends JApplet {
+
+ public void init() {
+
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+ } catch (final Exception e) {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ public void run() {
+ createAndShowMessage("Test fails because of exception: "
+ + e.getMessage());
+ }
+ });
+ }
+
+ }
+
+ private void createAndShowMessage(String message) {
+ getContentPane().add(new JLabel(message));
+ }
+
+ private void createAndShowGUI() {
+ JMenuBar mb = new JMenuBar();
+
+ // needed to exactly align left edge of menu and angled line of tree
+ mb.add(Box.createHorizontalStrut(27));
+
+ JMenu mn = new JMenu("Menu");
+ JMenuItem mi = new JMenuItem("MenuItem");
+ mn.add(mi);
+ mb.add(mn);
+ setJMenuBar(mb);
+
+ DefaultMutableTreeNode n1 = new DefaultMutableTreeNode("Root");
+ DefaultMutableTreeNode n2 = new DefaultMutableTreeNode("Duke");
+ n1.add(n2);
+ DefaultMutableTreeNode n3 = new DefaultMutableTreeNode("Bug");
+ n2.add(n3);
+ n3.add(new DefaultMutableTreeNode("Blah"));
+ n3.add(new DefaultMutableTreeNode("Blah"));
+ n3.add(new DefaultMutableTreeNode("Blah"));
+ DefaultMutableTreeNode n4 = new DefaultMutableTreeNode("Here");
+ n2.add(n4);
+
+ JTree tree = new JTree(new DefaultTreeModel(n1));
+ tree.putClientProperty("JTree.lineStyle", "Angled");
+ tree.expandPath(new TreePath(new Object[]{n1, n2, n3}));
+ setContentPane(tree);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/tree/DefaultTreeCellRenderer/7142955/bug7142955.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012, 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 7142955
+ @summary DefaultTreeCellRenderer doesn't honor 'Tree.rendererFillBackground' LAF property
+ @author Pavel Porvatov
+*/
+
+import javax.swing.*;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+
+public class bug7142955 {
+ private static final Color TEST_COLOR = Color.RED;
+
+ public static void main(String[] args) throws Exception {
+ UIManager.put("Tree.rendererFillBackground", Boolean.FALSE);
+ UIManager.put("Tree.textBackground", TEST_COLOR);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ int w = 200;
+ int h = 100;
+
+ BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+
+ Graphics g = image.getGraphics();
+
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, image.getWidth(), image.getHeight());
+
+ DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
+
+ renderer.setSize(w, h);
+ renderer.paint(g);
+
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ if (image.getRGB(x, y) == TEST_COLOR.getRGB()) {
+ throw new RuntimeException("Test bug7142955 failed");
+ }
+ }
+ }
+
+ System.out.println("Test bug7142955 passed.");
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/NoCache.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012, 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 7133367
+ * @summary ResponseCache.put should not be called when setUseCaches(false)
+ */
+
+import java.net.*;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class NoCache
+{
+ public static void main(String[] args) throws IOException {
+ ResponseCache.setDefault(new ThrowingCache());
+
+ HttpServer server = startHttpServer();
+ try {
+ URL url = new URL("http://" + InetAddress.getLocalHost().getHostAddress()
+ + ":" + server.getAddress().getPort() + "/NoCache/");
+ URLConnection uc = url.openConnection();
+ uc.setUseCaches(false);
+ uc.getInputStream().close();
+ } finally {
+ server.stop(0);
+ // clear the system-wide cache handler, samevm/agentvm mode
+ ResponseCache.setDefault(null);
+ }
+ }
+
+ static class ThrowingCache extends ResponseCache {
+ @Override
+ public CacheResponse get(URI uri, String rqstMethod,
+ Map<String,List<String>> rqstHeaders) {
+ throw new RuntimeException("ResponseCache.get should not be called");
+ }
+
+ @Override
+ public CacheRequest put(URI uri, URLConnection conn) {
+ throw new RuntimeException("ResponseCache.put should not be called");
+ }
+ }
+
+ // HTTP Server
+ static HttpServer startHttpServer() throws IOException {
+ HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ httpServer.createContext("/NoCache/", new SimpleHandler());
+ httpServer.start();
+ return httpServer;
+ }
+
+ static class SimpleHandler implements HttpHandler {
+ @Override
+ public void handle(HttpExchange t) throws IOException {
+ t.sendResponseHeaders(200, -1);
+ t.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/EmptyPassword.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 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 6879540
+ * @summary enable empty password for kerberos 5
+ * @compile -XDignore.symbol.file EmptyPassword.java
+ * @run main/othervm EmptyPassword
+ */
+
+public class EmptyPassword {
+
+ public static void main(String[] args)
+ throws Exception {
+
+ OneKDC kdc = new OneKDC("aes128-cts");
+ kdc.addPrincipal("empty", "".toCharArray());
+
+ Context c = Context.fromUserPass("empty", "".toCharArray(), false);
+ c.status();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs12/Bug6415637.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2012, 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 6415637
+ * @summary Support PKCS#12 key stores protected with an empty password
+ */
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateCrtKey;
+
+public class Bug6415637 {
+
+ public static void main(String[] args) throws Exception {
+ check(WITH_NULL);
+ check(WITHOUT_NULL);
+ }
+
+ private static void check(String encodedBlob) throws Exception {
+ byte[] blob = new byte[encodedBlob.length() * 2];
+ for (int i = 0; i < blob.length; ) {
+ final char ch = encodedBlob.charAt(i / 2);
+ blob[i++] = (byte) (ch >> 8);
+ blob[i++] = (byte) ch;
+ }
+ KeyStore store = KeyStore.getInstance("PKCS12");
+ store.load(new ByteArrayInputStream(blob), new char[0]);
+ if (!store.aliases().nextElement().equals("test"))
+ throw new Exception("test alias not found");
+ KeyStore.PrivateKeyEntry e =
+ (KeyStore.PrivateKeyEntry) store.getEntry("test",
+ new KeyStore.PasswordProtection(new char[0]));
+ X509Certificate cert = (X509Certificate) e.getCertificateChain()[0];
+ if (!cert.getSubjectDN().toString().equals("CN=Test Key"))
+ throw new Exception("invalid certificate subject DN");
+ RSAPrivateCrtKey key = (RSAPrivateCrtKey) e.getPrivateKey();
+ if (!key.getPublicExponent().equals(BigInteger.valueOf(65537)))
+ throw new Exception("invalid public exponent");
+ }
+
+ private static final String WITH_NULL =
+ "\u3082\u097c\u0201\u0330\u8209\u3606\u092a\u8648\u86f7\u0d01" +
+ "\u0701\ua082\u0927\u0482\u0923\u3082\u091f\u3082\u0564\u0609" +
+ "\u2a86\u4886\uf70d\u0107\u01a0\u8205\u5504\u8205\u5130\u8205" +
+ "\u4d30\u8205\u4906\u0b2a\u8648\u86f7\u0d01\u0c0a\u0102\ua082" +
+ "\u04fa\u3082\u04f6\u3028\u060a\u2a86\u4886\uf70d\u010c\u0103" +
+ "\u301a\u0414\u8317\ucfd6\u89ab\uc03b\u79d6\u4c45\u1b10\uc3bd" +
+ "\u3923\ub806\u0202\u0400\u0482\u04c8\ud51d\uf953\ud79e\u92c6" +
+ "\u83c0\u92dc\ucd05\u69ab\ucc1b\ud538\u2ed9\u7796\ua426\uc14e" +
+ "\udcbf\ue541\u40be\ud264\u3b5b\uf51f\u8e1a\u892f\u2813\ucdd6" +
+ "\uf72e\uef55\u35ef\u4620\ude18\ued5e\ufae0\ubed4\uf84e\u276b" +
+ "\u3596\uc33f\ub251\ue617\u6e00\ua80f\u6c82\u4acd\u7303\u26be" +
+ "\uffb5\u1e49\u5fb1\uf87c\ua873\ue60a\u7415\u655c\u39f1\ucf16" +
+ "\u8f5c\u85c6\u4100\u4130\u565b\u649a\u60d6\u6054\u868d\u7267" +
+ "\u97a8\u8492\uc5a0\udb5e\u2880\udf55\ub0ee\ua641\u8224\u76d2" +
+ "\u9b1e\u2a67\u1e32\ue1fc\u0a77\u435b\u669f\ued00\u6c30\u963f" +
+ "\u7ee3\uc5c8\u198f\u8ede\u30e1\u015d\u1195\uc850\u3371\ub9e5" +
+ "\u6968\u84c3\ub0e4\u22b7\u2a08\u4a9d\u9166\ua9ba\ud945\u0529" +
+ "\ue1e7\u8aba\ub4ef\u7445\udc9a\ucf73\ud77b\ufafe\ue1df\u3180" +
+ "\u9585\ued73\uca40\u06b0\ufdee\u95ba\u1aa3\ubd67\ua5c1\u84b4" +
+ "\u4b50\uc1e1\u4547\ud837\u21bc\uac0d\u0a65\uebb5\u7281\ud9bc" +
+ "\u2e2c\ua9bc\u7714\u0fc0\uab41\uce09\ud5e8\u5f8c\uc35d\uba6e" +
+ "\u98a2\u95c3\u87ff\uba8c\u056a\udc9f\uf254\u3d38\uf40a\u77dd" +
+ "\u4e30\u01de\ubef7\ud288\ue59c\ua143\ub30b\ud0ae\u63b9\u138b" +
+ "\uc793\u3474\u18ca\udeed\u78d9\u2ae8\u63cc\ua5d1\u6779\u0229" +
+ "\u7b72\ucfd4\ueecb\ue167\u08c0\u7556\u181d\u8d62\uc401\ub092" +
+ "\u8cf5\ued71\uf29f\u843e\u13e1\u7e7b\uf589\u0329\u92bd\ud0e3" +
+ "\u8dcc\u7541\uf195\ueef2\u3f3a\ueb01\uf5b0\u1869\u2216\uf351" +
+ "\u488d\udffb\u6243\u1121\u9447\u8a3a\u006f\u008c\ue2b3\ued31" +
+ "\u7f57\u6492\ue02f\u6f68\u387d\u58c0\uaadf\u2ee3\uf304\u3de9" +
+ "\u9741\u47fa\udde8\ufe8a\u679a\u597d\u8c7c\u9c71\u570e\u1dbd" +
+ "\ud555\ue853\uff63\u0fcb\u4b28\u3691\u33c8\uc31f\uc510\u6cba" +
+ "\ud92c\u6462\u733a\u739e\uc792\ud861\u743e\u3bd3\u006b\u2276" +
+ "\u9fb3\u0a31\u1eb3\ub97e\u4a80\uc076\uaabc\u35a0\u678d\u17c3" +
+ "\ua225\ua77c\u7d9c\uef2d\u83e2\u6996\uba70\uf6f8\u79a1\u9399" +
+ "\uc86b\u1cc5\ub2a5\u02c1\ud676\ua274\u4933\u6c60\u6832\ub0be" +
+ "\u5354\u5af9\uae23\u0963\u722d\u9ad2\u4461\ub768\u2068\u0ccb" +
+ "\u94fd\u88ac\u0f58\u3bc0\u212d\u30c8\u8860\uf7c9\u1dde\ub6b4" +
+ "\u3549\u5bcd\ucf83\u9420\u3a40\u16ad\uc4d7\ucd87\ue73a\ue1c7" +
+ "\u21df\u7f4f\u8659\u9f79\u5b36\uf206\uac66\uc9f3\u6336\u164d" +
+ "\u9046\uf4d5\u285d\ufcd8\ubd55\u1fb9\ua533\u9101\u1e87\uc7b0" +
+ "\u64e9\u3817\u216c\u8d41\uba51\u743a\uc74e\ue4ab\u2820\u972f" +
+ "\ue191\u85b4\u0ea7\ud896\u23cf\u7df5\u1653\ua9f3\ub724\ucbc9" +
+ "\u9738\ud2f8\u464e\ucf12\u99b8\u64e0\uf03b\u8d02\u85a8\uab52" +
+ "\u8da3\uea34\ube99\ue5f8\u2b38\ub082\u399d\ue61e\u64a1\u7f90" +
+ "\u26e9\ueb74\u6107\ufe2f\u82ca\u87a5\u3028\u8e1f\ue859\u61d4" +
+ "\ud26d\u23a9\uaadc\u02a7\u8ab2\u43d4\uf6b9\udf7a\u8935\u45a4" +
+ "\ufad6\ue7e4\u92b7\u35d7\u1044\u8ed3\u74ef\uaaa9\u713f\u6ebc" +
+ "\u1158\u5e5c\u7522\ufe17\ua515\u59a1\u75dd\ue7ac\uafd9\u16a9" +
+ "\u190e\u18fc\uc041\ufc9e\u3e16\u60c4\ufe51\u6d53\ufa52\u4c08" +
+ "\uce2a\ue546\u017b\ud96b\ube18\u8cb9\udd50\ued40\u14b0\u7da1" +
+ "\u2f2c\ubf9d\uc7c7\u1b73\ua155\ucaf8\ue54d\uebb0\u160a\ubd64" +
+ "\u5ef7\ue1cf\u4633\u86c1\ubc91\u839d\ub148\u9f31\uf2b1\ud133" +
+ "\u168f\u9374\u4667\u6aa9\u0482\ua2a6\ub5c0\ud9b7\ua070\uf6bd" +
+ "\u16fe\u0f41\u986b\u3d33\u7cb9\u291d\u24f0\u704a\uc946\u10a2" +
+ "\udbcf\u6c5f\u5a83\u5507\u036e\ube9f\uf60a\u9da8\u72dd\u23c9" +
+ "\u8878\udd67\uf486\u1384\u751f\u4694\uee3c\udc2e\ud5d7\ud99a" +
+ "\u5ee2\u5455\ub82d\u1837\u336d\u5724\u635b\ubd0b\u2e7c\u92be" +
+ "\u2110\u9c0e\u1662\u43f6\u62ae\u32e3\uaea4\u1cc5\uadc0\u7511" +
+ "\u6ad4\u0228\ue399\u5741\u2050\ue31a\u7dc8\uf6db\u67bb\u994a" +
+ "\u5b5a\uaac6\u2210\u95b0\u462e\u0684\u335e\uac36\u7ab9\uab1e" +
+ "\u0b75\u0f05\u74c5\ufcb3\ua0a5\ube7e\u45f8\u92d5\u3399\u7dd6" +
+ "\uf96e\u7e01\u7823\u6690\u231c\u4c47\u2d10\u7e7f\u5eb8\u70dd" +
+ "\u98d2\u6204\u3a92\u3990\u502b\u7cdb\u952a\ufa97\uea3b\ud990" +
+ "\u436f\uf33a\u070d\u2aff\u7497\u2591\u37e4\ua590\ue7ba\u2c1e" +
+ "\u53d9\u73fa\udc53\u944f\ua3a5\u5093\u33a4\uf080\u1193\u37f2" +
+ "\u7642\ub033\u7f90\u9b44\uff89\ue6ef\u81be\u9e6e\u68a4\u5a00" +
+ "\u9232\u4372\u40aa\u2748\u229d\u534d\u316b\u6e89\ufcb7\uff2e" +
+ "\ub654\u1649\ucb13\u3c28\u4940\u43aa\uc07d\u247c\u313c\u3017" +
+ "\u0609\u2a86\u4886\uf70d\u0109\u1431\u0a1e\u0800\u7400\u6500" +
+ "\u7300\u7430\u2106\u092a\u8648\u86f7\u0d01\u0915\u3114\u0412" +
+ "\u5469\u6d65\u2031\u3330\u3833\u3132\u3234\u3236\u3437\u3082" +
+ "\u03b3\u0609\u2a86\u4886\uf70d\u0107\u06a0\u8203\ua430\u8203" +
+ "\ua002\u0100\u3082\u0399\u0609\u2a86\u4886\uf70d\u0107\u0130" +
+ "\u2806\u0a2a\u8648\u86f7\u0d01\u0c01\u0630\u1a04\u14de\ud8d8" +
+ "\ua792\uf9d9\u6875\ua51d\u98ec\udf03\uc2b6\u5100\u8a02\u0204" +
+ "\u0080\u8203\u6074\ub909\u3c60\ua522\ue4ac\u0f60\u2396\u7baa" +
+ "\ud208\ub76c\u89a5\ue4ef\u205d\u2062\u4a5b\ua684\uceae\u01b9" +
+ "\u1e7a\u6e03\ud996\u555a\u615b\uba70\u406f\u80a9\u901e\ua947" +
+ "\u5b8f\u73f3\udea3\ud8b1\u9782\uac87\u231a\udcd2\u3ef0\u3a17" +
+ "\u4092\u509f\u0e79\u4cd7\u8516\u5111\uebe1\u86e0\uc548\u5ffc" +
+ "\u9a99\u11ed\uef13\u17af\u2707\u8984\u8770\u7064\u1943\u1dd3" +
+ "\u45cf\u9f80\u65f8\u9b3e\u1f70\u6bd0\uc726\u5506\ufb20\u6bdc" +
+ "\uba8c\u0b19\ucd01\ud0f0\u7040\udf63\u48a5\udf5f\u6559\u1b33" +
+ "\ubdae\u8183\uc13f\ued10\ud6dc\ud0f0\u6a7f\ubc36\uc7ca\u320f" +
+ "\u50b8\ud422\ufd99\u8843\u65e8\ue201\u843b\u64ee\ub891\u3ba2" +
+ "\uecae\ufda0\u72d6\u8394\u2551\ufc44\u3778\u27c3\u061a\u6d3b" +
+ "\ubd80\ue010\u06df\u39e7\u3d6a\u5ae2\u93fa\u4de4\u938f\u6f27" +
+ "\ufd39\u4380\u60da\uf215\u79d4\uf6f1\ua02f\u959a\ua0ea\u1c38" +
+ "\u80e3\u2744\u7506\u54b3\u77ad\u18ce\ucfec\u555e\u7bbe\u2e2f" +
+ "\u9900\ub2ef\ua5b9\ubdf0\u5e15\ua681\u92c7\u4f86\u2e1a\ub893" +
+ "\u01fc\u01d2\ub674\uff19\u04c3\ua1a0\u2cea\u72e0\ua8f1\u1358" +
+ "\ube79\u7caa\u269d\u728a\ue435\u37bd\u6495\uc106\u8830\u9b17" +
+ "\ue16d\uef78\uae2b\u5313\u1c96\uc0ee\u3098\ud743\ucd1c\u7407" +
+ "\uf4f9\uee72\ub95e\u31e7\u6435\u0173\u0336\u93c5\u8a1b\u05b4" +
+ "\u4359\uc4be\ud92b\u8d21\u83a9\u32b7\u6433\ua9bc\u27c2\ud842" +
+ "\ua4f2\u81c5\ua86c\u2fd2\uba30\u53bd\uc277\u659f\u203b\u60e5" +
+ "\u37f7\u0984\u31c2\u838a\u2107\u5840\u6411\u1b8d\u044e\ub0b6" +
+ "\uf558\ue6d3\u62bb\u5464\uf83a\u4d5b\uf153\u9e18\ua353\ubd05" +
+ "\uf204\ud543\u037d\ue5aa\u473a\ueb13\uac19\u0494\ua08e\u76c3" +
+ "\ufbd7\u9f1c\u8ca9\u57ad\ud218\uc018\u67ac\u0ae9\ub559\ufe38" +
+ "\u5641\uec0c\ue0ee\u606c\u1989\ue5a2\uff09\u8c61\u1386\ueb51" +
+ "\u7cbd\u95cd\u80c5\u3532\u8605\u596d\u4cfd\u7797\u1e82\ud2fe" +
+ "\uad6b\ua16e\ub6cf\u8fce\ud5a9\u207f\u1d0a\udabe\uc3a6\u5633" +
+ "\u2023\u925f\u809f\uee7c\u5362\u5fd9\u8dfc\u6b5f\uc95b\u0ae9" +
+ "\u7b26\u9e5b\u97e8\u9d6e\uaf91\u6d1a\u1d19\ufc27\u0815\uccbc" +
+ "\u83d4\u2ce2\ue06e\u21a1\u88da\u09af\u9671\uc510\uac23\u398d" +
+ "\ubea2\ua9a1\uf0d3\u490d\ub94b\u7ff7\u6636\ub1fa\u9b10\u1be3" +
+ "\u179b\u6a8a\u4a6c\ude1f\u5da7\u7c02\u96ec\u70ac\u5045\udd2c" +
+ "\u9f6d\uc37d\u5ba6\u4895\ue142\u0db9\uf2dc\uba2e\ud054\ud33e" +
+ "\u1ed9\u144b\u5d85\u9156\u3a90\ue8cd\u0a01\u67f5\ua81b\u4f56" +
+ "\u99dd\u4950\ua551\uacdb\udf31\u1f05\u7169\u3231\u0071\u80ec" +
+ "\ua4e9\ud74e\u62cf\u8931\u11f1\uc925\u0319\uabd4\ufb86\u73c2" +
+ "\u1479\u005b\uf05d\u4f8d\u44e4\u942b\ud338\ud05d\u2b3b\uf6f5" +
+ "\udc0d\uf741\u798b\ud8e9\u36a5\u577b\u8a95\ud773\uffcb\u17b3" +
+ "\u7174\u9616\u9b5e\ua577\u983c\u6e7a\u6cc8\u4a04\u042b\u503e" +
+ "\ud744\ub65e\ue5de\ufa24\u8c71\u1127\ud47f\ud290\ufd4c\u5cbb" +
+ "\u0e21\u77fd\u6553\ub82b\ucb49\u41e7\u8e3d\u4539\u925d\u6ba9" +
+ "\uae47\u391c\ua79e\ub6e2\u7142\u7cb3\u02f5\u6495\u7a85\u2dea" +
+ "\u787b\u22b7\u6ec2\uea8d\uf930\u3d30\u2130\u0906\u052b\u0e03" +
+ "\u021a\u0500\u0414\ubfef\u99f5\u0bb0\uc9b3\uf96a\ue267\u6bc0" +
+ "\u0202\u6d78\ub923\u0414\u5500\u095a\u2a04\u2d7e\u708d\u9779" +
+ "\u9bdb\u2c4f\u82f2\uf89f\u0202\u0400";
+
+ private static final String WITHOUT_NULL =
+ "\u3082\u097c\u0201\u0330\u8209\u3606\u092a\u8648\u86f7\u0d01" +
+ "\u0701\ua082\u0927\u0482\u0923\u3082\u091f\u3082\u0564\u0609" +
+ "\u2a86\u4886\uf70d\u0107\u01a0\u8205\u5504\u8205\u5130\u8205" +
+ "\u4d30\u8205\u4906\u0b2a\u8648\u86f7\u0d01\u0c0a\u0102\ua082" +
+ "\u04fa\u3082\u04f6\u3028\u060a\u2a86\u4886\uf70d\u010c\u0103" +
+ "\u301a\u0414\ud258\ubbe7\ub641\ud196\u4969\u3c88\u70f1\u8c97" +
+ "\u95b1\u8bf3\u0202\u0400\u0482\u04c8\u096a\u4686\uf519\u61da" +
+ "\u1b3b\uebfd\u89b1\u044b\u3bd8\u79a7\ud022\ud880\ud173\ucde1" +
+ "\ud2c1\u2c5d\u8ebb\u6bd4\u46db\ub90b\u04b9\ub091\ud1f3\ud468" +
+ "\u3e93\u2c88\uca5a\u1c54\u5342\u1eca\u8565\ubbbd\ua022\u1ead" +
+ "\ud0bb\u1a8c\u69cf\uf0f4\ucbfb\u488a\ube99\uf190\ue01c\ud87d" +
+ "\u78ca\u9e5c\u82f9\u76ad\u811f\u37d0\u272b\u0481\u500c\u0a27" +
+ "\u08d3\ub637\u3e39\u6db1\ubcba\ue354\u6924\ua9d5\u3555\u20d6" +
+ "\u4c6b\u3189\u5f91\u382c\uf351\u4de2\ubade\u2a14\uea84\u16b6" +
+ "\uf7f7\u36de\ubba6\ue952\u5f5d\u8243\u2318\ucf3d\u8ac8\u33d3" +
+ "\u706c\ue3db\u6619\u7935\u7300\u89b3\u0bcd\uca9f\u0333\ua450" +
+ "\u1be1\u3e42\ub465\uced5\ub055\u5843\uf40f\ua0f2\u6fea\u94fa" +
+ "\ua51e\u4b5d\u93c9\ucb2e\u977e\uafd9\u2a2f\u784b\u0320\u5550" +
+ "\u273f\u469f\uc42b\u2ce7\uedea\u4e0d\u54a5\u1a25\u4fac\ue346" +
+ "\u2102\u7ab6\uea86\u554f\u7706\u8a80\uf6dd\u04f8\u3b37\u005a" +
+ "\u4562\u2ef8\u59f9\u32b7\u31c0\ue7dc\ucbde\ue0e1\u2fd9\u0960" +
+ "\u3e7a\ub4e5\u2a58\u1e2b\uef14\u9a44\u5444\u806d\uc475\u12ab" +
+ "\ucc3d\ua03b\ubd52\ubf1c\ua9a6\u58aa\uee8b\u96c2\ud0c9\ua029" +
+ "\u1db4\ub118\u4807\uecaa\ue182\uabb7\ud9ed\u66c5\u2c80\uc6a6" +
+ "\u3f54\ubc73\u2632\ue1b0\u0d74\u001c\u5740\uc74b\ufadb\u25b4" +
+ "\ua10e\u3191\u69e6\u0861\u452b\u955c\uac56\ud3c4\u86b7\u45f8" +
+ "\u777a\uc336\u8cc7\ud471\u76b6\u11d8\ueb84\u14e4\uf44f\uc9ff" +
+ "\u8929\u0d84\ubcfe\u8cc2\u9d07\u94e6\u1cf9\u19b5\u773a\u012d" +
+ "\u0453\u4ff3\u40f2\ub144\ufc80\u571c\u0e13\uf890\u9fed\u2045" +
+ "\u7baf\ufd88\u4920\u2b86\u491d\uecf8\ua5d9\u1e12\u48c7\u2c84" +
+ "\u3fbe\u4df5\u11ce\u7b81\u83fc\u3efa\u697d\u1f3d\u8d81\u01b0" +
+ "\u0bf1\u9012\u697f\u3b25\u3574\u5286\udded\u5be0\u7e92\u0a02" +
+ "\ua486\ud19b\ue0b5\ua05c\u5ac2\u0ad5\u0d04\ua763\ub5c8\uf7e6" +
+ "\u6e77\u2df3\ub9e7\uda30\ufccb\u7642\u5dc1\udf1f\uc922\uff69" +
+ "\u4471\u4749\u937a\ud77d\u7c0d\u917c\uf2ef\u122c\u13b2\u8943" +
+ "\u33aa\uad59\u86e8\u21c4\ueaa0\uf200\ue5f3\u6da0\ue8ef\uce7e" +
+ "\u37b2\u3ddf\u0480\u08fc\uf89a\ud927\u3f5b\u75d3\ubdfe\u6ebd" +
+ "\ufab1\u9f54\u1c20\u625b\u1391\u2af0\u43ba\u4395\udf22\u299e" +
+ "\uf3bf\u7750\u5f68\u0120\u0ee0\u6960\ud939\u621f\uf845\u0025" +
+ "\ue33c\u7ed9\ueadf\u0005\u6306\u7274\u5e67\ucf7a\uf3c6\u7371" +
+ "\u487b\u79d7\u2142\ubc1a\ubfe4\u3536\u15db\ufe23\u4352\u6321" +
+ "\u329d\uc251\u84c8\ufc0e\uc0ca\u5be6\uf530\u0177\ud9cb\ud132" +
+ "\uf752\u3f26\uda90\ud9cf\u2e46\u3e09\u5d9a\u6902\udb3e\ub06c" +
+ "\u722d\uf498\u3e93\u6cae\u43b5\u535a\u1cd1\uf0b2\u8d80\u9e53" +
+ "\ue02e\uf782\u01ce\u5063\u73d1\u5571\uf0e7\ufa22\u7e48\u0c31" +
+ "\u4642\u29fd\udcab\ue8d4\u7a77\u0880\u4855\u88c7\u7aa5\u0d9c" +
+ "\uf8b7\uc91c\u127d\u2dd7\ude53\u9d3f\u132b\u965c\ubc80\udd97" +
+ "\u87bf\ua0e8\ub2a2\u4e1f\u98fd\u72f3\u16ea\uc415\u5be3\ue8df" +
+ "\u5681\u1f11\u4e3a\uac5d\u1684\u6602\ueb14\u0a96\ufcef\uaebf" +
+ "\u1f2e\ud1a9\u435c\uf4e5\ub6b4\uaae2\u8244\u96a4\u0d3a\u752f" +
+ "\uce21\u1bc9\u219e\uf17b\ud95e\ucd12\u1b0a\ucb85\ub0cd\u4ecb" +
+ "\u6bb4\u5f7c\u2a93\ubb24\u9d7c\u6822\u80cd\u3f54\u78ad\u4fde" +
+ "\ud57f\uec1d\ub54c\u0d78\u5946\u84c1\ua9ad\u0dea\u0292\ub279" +
+ "\u1c76\u817e\ub910\ub1fa\ub1c0\u839d\u9eca\u6f83\u8211\u4112" +
+ "\u440c\u4fbd\u6ef2\u897d\udfa9\ude9e\u1aef\u0f21\u26fb\uaca4" +
+ "\u637e\ub072\u264f\ud24d\u9357\uc801\u0b84\u2d34\ueddf\u6063" +
+ "\udc5d\u90dd\u5c62\ufb48\u8c5e\u7c4e\u3bdb\ub590\u7a75\udbd1" +
+ "\udd78\uc8be\u5915\u7c8b\u8874\u578d\u3116\ub65a\uab8e\ud2ef" +
+ "\u5d35\ubf8b\u2828\u8983\ua790\uedcf\u9698\ue023\u5786\u627b" +
+ "\u9037\u1db7\u900e\u1f45\u0001\u7cf8\u14fd\ue437\u0dfd\ucacc" +
+ "\u5edf\u1742\u7f6e\u612a\ud57d\udca0\u73a4\ud601\uc7f0\uca0e" +
+ "\u5a44\u00b4\u233a\u84f2\u95b5\u5f16\uc291\u04fb\u369d\u6b99" +
+ "\ue127\u493f\u66be\u86e9\u9672\u2849\u64a7\u851b\ue420\u8491" +
+ "\ueb07\u6563\uc753\uc28e\ucad5\uec05\u6920\u8955\u5605\u25f6" +
+ "\u6193\ubee5\u7a1a\ub73d\ucc27\uc8ce\u7179\u57c1\u7a2a\u37c1" +
+ "\ua6c7\u2d8a\u4025\uc97d\u8c9d\u7b4b\u1ad5\uc6d7\u50fc\u246d" +
+ "\u91a9\ua55d\u677a\udc83\u04c7\u3e14\u9950\u420c\udf02\u749b" +
+ "\ude88\u5459\u2074\ua4ae\ud12d\uaf60\uba98\u630d\u313c\u3017" +
+ "\u0609\u2a86\u4886\uf70d\u0109\u1431\u0a1e\u0800\u7400\u6500" +
+ "\u7300\u7430\u2106\u092a\u8648\u86f7\u0d01\u0915\u3114\u0412" +
+ "\u5469\u6d65\u2031\u3330\u3833\u3132\u3431\u3138\u3238\u3082" +
+ "\u03b3\u0609\u2a86\u4886\uf70d\u0107\u06a0\u8203\ua430\u8203" +
+ "\ua002\u0100\u3082\u0399\u0609\u2a86\u4886\uf70d\u0107\u0130" +
+ "\u2806\u0a2a\u8648\u86f7\u0d01\u0c01\u0630\u1a04\u14af\ud4f5" +
+ "\u0ff4\u0ede\u0da0\u6cc5\ufd9d\u3502\uae5e\u4cef\u3102\u0204" +
+ "\u0080\u8203\u6028\ua7e6\u088b\u56b6\uf453\u9747\u68ec\uc064" +
+ "\u2254\u693f\u25c5\uaa39\u3d87\uc97c\uc558\u5194\u7553\ude3a" +
+ "\u4575\u9d85\ud843\u2bd0\ua2e8\u244f\u8593\uac84\u54b4\ubdc6" +
+ "\ucea6\uba1a\ud3da\ua510\uee9d\uaf31\ub5c2\u3329\u0fed\u0e08" +
+ "\u426b\u46fe\udcc5\u0979\ua9ed\u3123\u9a50\ud222\u3fc0\u771a" +
+ "\u6f55\u9664\ud56f\u6b03\u6020\u78a4\u63b2\ue35e\u0816\u43a7" +
+ "\u1909\u52e1\u8183\u1b8d\u9f5b\u19e4\uad73\u8461\ucc86\u3b49" +
+ "\u322e\ue9d9\u3c66\uea22\u091e\u6621\ua8bf\u0169\u72d0\u535e" +
+ "\u77dc\u1002\ubded\u7a91\u6cee\u58fa\uc295\uae8e\ue009\uabe9" +
+ "\u6638\ucaea\u8bbf\uca27\udef5\u2881\u72ec\u8aa5\u582b\u9d6e" +
+ "\u26bb\u3c70\u8bd6\uf5ec\u34ae\ua967\u5bb1\u22cb\u4b74\u0e50" +
+ "\u5062\uc6f7\u7cb4\u58a3\uf43d\u57c0\u9654\u2f9c\u9308\u4546" +
+ "\u6f4a\u37fe\u8d5d\u1465\u8621\u4cd8\u68d6\u0456\u96a4\ud3e2" +
+ "\u76d1\u2675\u7654\u7649\u10e9\u9d0e\u8b04\uffb6\u020a\u2eb4" +
+ "\uf24f\u150e\u7f0d\uf41b\u2c76\u538f\uc2df\u79dc\u0472\u1119" +
+ "\uc148\ue2e8\u1820\ucd45\u08a7\u6bcd\u6eb0\ubd0a\ufff4\uec28" +
+ "\u819b\u2adb\uefc8\ue8f7\ue233\u6535\uc938\u9771\u3681\u87cf" +
+ "\u3a24\u4c71\ue1df\u3e19\u259c\uae5b\u27ed\u8a67\uf3e6\u7af0" +
+ "\u48e1\uc542\uc471\ud8f4\ue317\u46e9\u0b4f\uec45\ua1d3\u2b88" +
+ "\u8a22\udda1\u7c1a\u273c\ua0f7\u8bac\u3771\u28d2\u6ef8\u28d2" +
+ "\ud83c\u196f\ue3fd\u9c79\u4305\u01b8\u3490\u0a91\ue4f3\uebc6" +
+ "\u25a2\u7dd2\u72db\u7531\ucfca\u432f\u2beb\uc649\uf9c5\uc533" +
+ "\u9f3a\ua611\u935c\ubca6\ud293\u54d6\u0dd1\u0aff\u82fb\u2d69" +
+ "\u3da0\u3b33\u0986\u45b3\u3353\ub968\u7348\u454f\u9117\ub3dc" +
+ "\ud7af\u06ca\ua34a\u9357\ue22f\uad3d\u4c76\ub386\ua8d7\u2a90" +
+ "\u6d17\u9321\u7b00\u21e4\u1994\u9d18\u6439\u04c8\u8282\ub269" +
+ "\uf786\u75c6\ua505\u983a\ua075\uffa0\ud662\u6ae5\ub126\u96d1" +
+ "\u9e5e\u346b\ub7ee\ub0a3\u4ee8\ud204\u77ec\u2325\u5da8\ua326" +
+ "\ua018\u0fd8\ue50e\u93cc\ucc40\u2d89\u2ffb\u54e0\u091a\u19fd" +
+ "\u45d7\uc0ab\u77a2\u66ae\u794b\u6644\u21c3\ud782\u1e9e\u53e5" +
+ "\u782e\u55e8\ud44e\u93e8\u379e\u5aa8\u353b\u95de\u7bc1\ucaf3" +
+ "\u5223\ub5e9\uacbb\ub86b\u6014\u0626\ue7ad\ufd93\ue43a\ud864" +
+ "\u1e6d\u14b2\ua12a\u94c5\u2ed9\ua7f7\u14f4\u0cbd\uca3b\u7c21" +
+ "\ua85a\uf834\u6c99\ue1aa\u3832\u2515\u8170\u3c93\u7def\u94fe" +
+ "\u9c3d\u4ab0\u73ed\u6c72\u8b94\ua407\uc719\uad1e\u6306\u4167" +
+ "\u921e\uae53\u3fd4\uf569\u6f0b\u82b0\u0ca6\ud61f\ud526\u23c9" +
+ "\u168d\u4baf\ucc4f\ud8a2\uc64a\ud649\u55e3\u7019\u8f20\u680c" +
+ "\u5581\u2cb1\ub3a4\u3e37\u5fd3\ua3ca\uc115\u979c\uf910\u3797" +
+ "\u05cb\u51d6\u74a4\uc5c0\u597b\uf27f\ud5e2\ue8ac\u4f3d\uc0c3" +
+ "\u9594\u7799\u6876\ub1a3\u059a\uff03\uc2ee\uc8c2\uf224\u3720" +
+ "\u9177\uabdb\u9202\u18d8\uffbe\u0516\u2a76\uedb5\ufe9e\u6d65" +
+ "\u4c35\ue4cb\u75aa\u02be\ud24c\ua482\ufc67\ue4f9\u70c7\u3567" +
+ "\ufc3f\uaa89\ue80a\u6507\u0a65\u4e18\uf919\u071d\u423c\u1756" +
+ "\u30e5\u37f3\u19b3\u10fb\u6c30\u3d30\u2130\u0906\u052b\u0e03" +
+ "\u021a\u0500\u0414\ufd05\u4444\ud347\u673c\u6da4\udb7c\u0733" +
+ "\ud7bf\ud263\uc6b2\u0414\udd17\u155e\u2d4c\u25cb\ua028\u1a23" +
+ "\ub8b0\uf6be\u925f\ude3a\u0202\u0400";
+
+}
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.java Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Wed Jul 05 18:03:08 2017 +0200
@@ -1,7 +1,7 @@
#! /bin/sh
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
--- a/jdk/test/sun/security/tools/jarsigner/ec.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/security/tools/jarsigner/ec.sh Wed Jul 05 18:03:08 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, 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,8 @@
$KT -alias a -dname CN=a -keyalg ec -genkey -validity 300 || exit 11
$KT -alias b -dname CN=b -keyalg ec -genkey -validity 300 || exit 12
-$KT -alias c -dname CN=c -keyalg ec -genkey -validity 300 || exit 13
+# Ensure that key length is sufficient for the intended hash (SHA512withECDSA)
+$KT -alias c -dname CN=c -keyalg ec -genkey -validity 300 -keysize 521 || exit 13
$KT -alias x -dname CN=x -keyalg ec -genkey -validity 300 || exit 14
$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 21
--- a/jdk/test/sun/tools/jcmd/jcmd-Defaults.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/tools/jcmd/jcmd-Defaults.sh Wed Jul 05 18:03:08 2017 +0200
@@ -28,6 +28,6 @@
JCMD="${TESTJAVA}/bin/jcmd"
-${JCMD} 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
+${JCMD} -J-XX:+UsePerfData 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
-${JCMD} -l 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
+${JCMD} -J-XX:+UsePerfData -l 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
--- a/jdk/test/sun/tools/jcmd/jcmd-f.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/tools/jcmd/jcmd-f.sh Wed Jul 05 18:03:08 2017 +0200
@@ -46,7 +46,7 @@
# -f <script>
rm -f jcmd.out 2>/dev/null
-${JCMD} $appJavaPid -f ${TESTSRC}/dcmd-script.txt | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
+${JCMD} -J-XX:+UsePerfData $appJavaPid -f ${TESTSRC}/dcmd-script.txt | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
echo jcmd.out
diff -w jcmd.out ${TESTSRC}/help_help.out
if [ $? != 0 ]; then
--- a/jdk/test/sun/tools/jcmd/jcmd-help-help.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/tools/jcmd/jcmd-help-help.sh Wed Jul 05 18:03:08 2017 +0200
@@ -46,7 +46,7 @@
# help help
rm -f jcmd.out 2>/dev/null
-${JCMD} $appJavaPid help help | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
+${JCMD} -J-XX:+UsePerfData $appJavaPid help help | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
echo jcmd.out
diff -w jcmd.out ${TESTSRC}/help_help.out
if [ $? != 0 ]; then
--- a/jdk/test/sun/tools/jcmd/jcmd-help.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/tools/jcmd/jcmd-help.sh Wed Jul 05 18:03:08 2017 +0200
@@ -29,7 +29,7 @@
JCMD="${TESTJAVA}/bin/jcmd"
rm -f jcmd.out 2>/dev/null
-${JCMD} -h > jcmd.out 2>&1
+${JCMD} -J-XX:+UsePerfData -h > jcmd.out 2>&1
diff -w jcmd.out ${TESTSRC}/usage.out
if [ $? != 0 ]
@@ -40,7 +40,7 @@
fi
rm -f jcmd.out 2>/dev/null
-${JCMD} -help > jcmd.out 2>&1
+${JCMD} -J-XX:+UsePerfData -help > jcmd.out 2>&1
diff -w jcmd.out ${TESTSRC}/usage.out
if [ $? != 0 ]
--- a/jdk/test/sun/tools/jcmd/jcmd-pid.sh Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/tools/jcmd/jcmd-pid.sh Wed Jul 05 18:03:08 2017 +0200
@@ -45,11 +45,11 @@
failed=0
# help command
-${JCMD} $appJavaPid help 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output1.awk
+${JCMD} -J-XX:+UsePerfData $appJavaPid help 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output1.awk
if [ $? != 0 ]; then failed=1; fi
# PerfCounter.list option
-${JCMD} $appJavaPid PerfCounter.print 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output2.awk
+${JCMD} -J-XX:+UsePerfData $appJavaPid PerfCounter.print 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output2.awk
if [ $? != 0 ]; then failed=1; fi
set -e
--- a/jdk/test/sun/tools/jcmd/jcmd_Output1.awk Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/sun/tools/jcmd/jcmd_Output1.awk Wed Jul 05 18:03:08 2017 +0200
@@ -1,26 +1,26 @@
#
BEGIN {
- totallines=0; matched=0
+ totallines=0; matched=0; current=0
}
# match on a main class name followed by arbitrary arguments
/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\.]*($| .*$)/ {
- matched++;
+ current=1;
}
# or match on a path name to a jar file followed by arbitraty arguments
# - note, jar files ending with ".jar" is only a convention, not a requirement.
#Theoretically, any valid file name could occur here.
/^[0-9]+ .*\.jar($| .*$)/ {
- matched++;
+ current=1;
}
# or match on the condition that the class name is not available
/^[0-9]+ -- process information unavailable$/ {
- matched++;
+ current=1;
}
- { totallines++; print $0 }
+ { totallines++; matched+=current; current=0; print $0 }
END {
if ((totallines > 0) && (matched == totallines)) {
--- a/jdk/test/tools/launcher/Arrrghs.java Thu Feb 16 13:01:32 2012 -0800
+++ b/jdk/test/tools/launcher/Arrrghs.java Wed Jul 05 18:03:08 2017 +0200
@@ -24,7 +24,7 @@
/**
* @test
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
- * 6894719 6968053 7067922
+ * 6894719 6968053
* @summary Argument parsing validation.
* @compile -XDignore.symbol.file Arrrghs.java
* @run main Arrrghs
@@ -373,21 +373,6 @@
System.out.println(tr);
}
- /*
- * a missing manifest entry 7067922, we ignore this test for locales
- * which are localized, thus the testing is limited to English locales.
- */
- static void test7067922() {
- if (!isEnglishLocale()) {
- return;
- }
- TestResult tr = null;
- createJar("cvf", "missingmainentry.jar", ".");
- tr = doExec(javaCmd, "-jar", "missingmainentry.jar");
- tr.contains("no main manifest attribute");
- System.out.println(tr);
- }
-
/**
* @param args the command line arguments
* @throws java.io.FileNotFoundException
@@ -400,7 +385,6 @@
runBasicErrorMessageTests();
runMainMethodTests();
test6894719();
- test7067922();
runDiagOptionTests();
if (testExitValue > 0) {
System.out.println("Total of " + testExitValue + " failed");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/MainClassAttributeTest.java Wed Jul 05 18:03:08 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, 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 7067922
+ * @author sogoel
+ * @summary Test negative scenarios for main class attribute
+ * @build MainClassAttributeTest
+ * @run main MainClassAttributeTest
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * This tests negative scenarios for Main class entry in a jar file.
+ * An error should be thrown for each of the test cases when such a
+ * jar is executed.
+ */
+
+public class MainClassAttributeTest extends TestHelper {
+
+ /*
+ * These tests compare messages which could be localized, therefore
+ * these tests compare messages only with English locales, and
+ * for all other locales, the exit values are checked.
+ */
+ static void runTest(File jarFile, String expectedErrorMessage) {
+ TestResult tr = doExec(TestHelper.javaCmd,
+ "-jar", jarFile.getAbsolutePath());
+ if (isEnglishLocale() && !tr.contains(expectedErrorMessage)) {
+ System.out.println(tr);
+ throw new RuntimeException("expected string not found");
+ }
+ if (tr.isOK()) {
+ System.out.println(tr);
+ throw new RuntimeException("test exit with status 0");
+ }
+ }
+
+ // Missing manifest entry
+ static void test1() throws IOException {
+ File jarFile = new File("missingmainentry.jar");
+ createJar("cvf", jarFile.getName(), ".");
+ runTest(jarFile, "no main manifest attribute");
+ }
+
+ // Entry point in manifest file has .class extension
+ static void test2() throws IOException {
+ File jarFile = new File("extensionmainentry.jar");
+ createJar("Foo.class", jarFile, new File("Foo"), (String[])null);
+ runTest(jarFile, "Error: Could not find or load main class");
+ }
+
+ // Entry point in manifest file is misspelled
+ static void test3() throws IOException {
+ File jarFile = new File("misspelledmainentry.jar");
+ createJar("FooMIS", jarFile, new File("Foo"), (String[])null);
+ runTest(jarFile, "Error: Could not find or load main class");
+ }
+
+ // Main-Class attribute is misspelled in manifest file
+ static void test4() throws IOException {
+ File jarFile = new File("misspelledMainAttribute.jar");
+ File manifestFile = new File("manifest.txt");
+ List<String> contents = new ArrayList<>();
+ contents.add("MainClassName: Foo");
+ createFile(manifestFile, contents);
+ createJar("-cmf", manifestFile.getName(), jarFile.getName());
+ runTest(jarFile, "no main manifest attribute");
+ }
+
+ public static void main(String[] args) throws IOException {
+ test1();
+ test2();
+ test3();
+ test4();
+ }
+}