--- a/.hgtags-top-repo Thu Dec 17 14:10:20 2009 -0800
+++ b/.hgtags-top-repo Wed Jul 05 17:04:56 2017 +0200
@@ -52,3 +52,4 @@
d1516b9f23954b29b8e76e6f4efc467c08c78133 jdk7-b75
c8b63075403d53a208104a8a6ea5072c1cb66aab jdk7-b76
1f17ca8353babb13f4908c1f87d11508232518c8 jdk7-b77
+ab4ae8f4514693a9fe17ca2fec0239d8f8450d2c jdk7-b78
--- a/hotspot/.hgtags Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/.hgtags Wed Jul 05 17:04:56 2017 +0200
@@ -52,3 +52,4 @@
d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75
9174bb32e934965288121f75394874eeb1fcb649 jdk7-b76
455105fc81d941482f8f8056afaa7aa0949c9300 jdk7-b77
+e703499b4b51e3af756ae77c3d5e8b3058a14e4e jdk7-b78
--- a/hotspot/make/hotspot_version Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/hotspot_version Wed Jul 05 17:04:56 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=17
HS_MINOR_VER=0
-HS_BUILD_NUMBER=05
+HS_BUILD_NUMBER=06
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- a/hotspot/make/linux/makefiles/debug.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/debug.make Wed Jul 05 17:04:56 2017 +0200
@@ -38,7 +38,7 @@
"Please use 'make jvmg' to build debug JVM. \n" \
"----------------------------------------------------------------------\n")
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
--- a/hotspot/make/linux/makefiles/fastdebug.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/fastdebug.make Wed Jul 05 17:04:56 2017 +0200
@@ -58,7 +58,7 @@
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = optimized
SYSDEFS += -DASSERT -DFASTDEBUG
PICFLAGS = DEFAULT
--- a/hotspot/make/linux/makefiles/jsig.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/jsig.make Wed Jul 05 17:04:56 2017 +0200
@@ -25,9 +25,12 @@
# Rules to build signal interposition library, used by vm.make
# libjsig[_g].so: signal interposition library
-JSIG = jsig$(G_SUFFIX)
+JSIG = jsig
LIBJSIG = lib$(JSIG).so
+JSIG_G = $(JSIG)$(G_SUFFIX)
+LIBJSIG_G = lib$(JSIG_G).so
+
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG)
@@ -50,6 +53,7 @@
@echo Making signal interposition lib...
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
$(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
+ $(QUIETLY) [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
install_jsig: $(LIBJSIG)
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
--- a/hotspot/make/linux/makefiles/jvmg.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/jvmg.make Wed Jul 05 17:04:56 2017 +0200
@@ -35,7 +35,7 @@
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
--- a/hotspot/make/linux/makefiles/launcher.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/launcher.make Wed Jul 05 17:04:56 2017 +0200
@@ -25,7 +25,9 @@
# Rules to build gamma launcher, used by vm.make
# gamma[_g]: launcher
-LAUNCHER = gamma$(G_SUFFIX)
+
+LAUNCHER = gamma
+LAUNCHER_G = $(LAUNCHER)$(G_SUFFIX)
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
LAUNCHERFLAGS = $(ARCHFLAG) \
@@ -70,4 +72,5 @@
$(LINK_LAUNCHER/PRE_HOOK) \
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
$(LINK_LAUNCHER/POST_HOOK) \
+ [ -f $(LAUNCHER_G) ] || { ln -s $@ $(LAUNCHER_G); }; \
}
--- a/hotspot/make/linux/makefiles/saproc.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/saproc.make Wed Jul 05 17:04:56 2017 +0200
@@ -25,9 +25,13 @@
# Rules to build serviceability agent library, used by vm.make
# libsaproc[_g].so: serviceability agent
-SAPROC = saproc$(G_SUFFIX)
+
+SAPROC = saproc
LIBSAPROC = lib$(SAPROC).so
+SAPROC_G = $(SAPROC)$(G_SUFFIX)
+LIBSAPROC_G = lib$(SAPROC_G).so
+
AGENT_DIR = $(GAMMADIR)/agent
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)
@@ -75,6 +79,7 @@
$(SA_DEBUG_CFLAGS) \
-o $@ \
-lthread_db
+ $(QUIETLY) [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
install_saproc: checkAndBuildSA
$(QUIETLY) if [ -e $(LIBSAPROC) ] ; then \
--- a/hotspot/make/linux/makefiles/vm.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/linux/makefiles/vm.make Wed Jul 05 17:04:56 2017 +0200
@@ -113,8 +113,9 @@
#----------------------------------------------------------------------
# JVM
-JVM = jvm$(G_SUFFIX)
-LIBJVM = lib$(JVM).so
+JVM = jvm
+LIBJVM = lib$(JVM).so
+LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
JVM_OBJ_FILES = $(Obj_Files)
@@ -201,6 +202,7 @@
$(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
$(LINK_LIB.CC/POST_HOOK) \
rm -f $@.1; ln -s $@ $@.1; \
+ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
if [ -x /usr/sbin/selinuxenabled ] ; then \
/usr/sbin/selinuxenabled; \
if [ $$? = 0 ] ; then \
--- a/hotspot/make/solaris/makefiles/debug.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/debug.make Wed Jul 05 17:04:56 2017 +0200
@@ -54,7 +54,7 @@
"Please use 'gnumake jvmg' to build debug JVM. \n" \
"-------------------------------------------------------------------------\n")
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
--- a/hotspot/make/solaris/makefiles/dtrace.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/dtrace.make Wed Jul 05 17:04:56 2017 +0200
@@ -24,8 +24,8 @@
# Rules to build jvm_db/dtrace, used by vm.make
-# we build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
-# but not for CORE configuration
+# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
+# but not for CORE or KERNEL configurations.
ifneq ("${TYPE}", "CORE")
ifneq ("${TYPE}", "KERNEL")
@@ -37,12 +37,13 @@
else
-
JVM_DB = libjvm_db
-LIBJVM_DB = libjvm$(G_SUFFIX)_db.so
+LIBJVM_DB = libjvm_db.so
+LIBJVM_DB_G = libjvm$(G_SUFFIX)_db.so
JVM_DTRACE = jvm_dtrace
-LIBJVM_DTRACE = libjvm$(G_SUFFIX)_dtrace.so
+LIBJVM_DTRACE = libjvm_dtrace.so
+LIBJVM_DTRACE_G = libjvm$(G_SUFFIX)_dtrace.so
JVMOFFS = JvmOffsets
JVMOFFS.o = $(JVMOFFS).o
@@ -77,7 +78,7 @@
LFLAGS_JVM_DTRACE += -D_REENTRANT $(PICFLAG)
else
LFLAGS_JVM_DB += -mt $(PICFLAG) -xnolib
-LFLAGS_JVM_DTRACE += -mt $(PICFLAG) -xnolib
+LFLAGS_JVM_DTRACE += -mt $(PICFLAG) -xnolib -ldl
endif
ISA = $(subst i386,i486,$(shell isainfo -n))
@@ -86,18 +87,24 @@
ifneq ("${ISA}","${BUILDARCH}")
XLIBJVM_DB = 64/$(LIBJVM_DB)
+XLIBJVM_DB_G = 64/$(LIBJVM_DB_G)
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
+XLIBJVM_DTRACE_G = 64/$(LIBJVM_DTRACE_G)
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
+ [ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); }
+
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+ [ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); }
+
endif # ifneq ("${ISA}","${BUILDARCH}")
ifdef USE_GCC
@@ -142,11 +149,13 @@
@echo Making $@
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
+ [ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); }
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+ [ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); }
$(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \
$(DTRACE_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d
--- a/hotspot/make/solaris/makefiles/fastdebug.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/fastdebug.make Wed Jul 05 17:04:56 2017 +0200
@@ -90,7 +90,6 @@
# for this method for now. (fix this when dtrace bug 6258412 is fixed)
OPT_CFLAGS/ciEnv.o = $(OPT_CFLAGS) -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
-
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
@@ -115,8 +114,7 @@
# and mustn't be otherwise.
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
-
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = optimized
SYSDEFS += -DASSERT -DFASTDEBUG -DCHECK_UNHANDLED_OOPS
PICFLAGS = DEFAULT
--- a/hotspot/make/solaris/makefiles/jsig.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/jsig.make Wed Jul 05 17:04:56 2017 +0200
@@ -25,8 +25,11 @@
# Rules to build signal interposition library, used by vm.make
# libjsig[_g].so: signal interposition library
-JSIG = jsig$(G_SUFFIX)
-LIBJSIG = lib$(JSIG).so
+JSIG = jsig
+LIBJSIG = lib$(JSIG).so
+
+JSIG_G = $(JSIG)$(G_SUFFIX)
+LIBJSIG_G = lib$(JSIG_G).so
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
@@ -46,6 +49,7 @@
@echo Making signal interposition lib...
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
$(LFLAGS_JSIG) -o $@ $< -ldl
+ [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
install_jsig: $(LIBJSIG)
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
--- a/hotspot/make/solaris/makefiles/jvmg.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/jvmg.make Wed Jul 05 17:04:56 2017 +0200
@@ -51,7 +51,7 @@
# and mustn't be otherwise.
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
--- a/hotspot/make/solaris/makefiles/launcher.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/launcher.make Wed Jul 05 17:04:56 2017 +0200
@@ -25,7 +25,8 @@
# Rules to build gamma launcher, used by vm.make
# gamma[_g]: launcher
-LAUNCHER = gamma$(G_SUFFIX)
+LAUNCHER = gamma
+LAUNCHER_G = $(LAUNCHER)$(G_SUFFIX)
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
LAUNCHERFLAGS = $(ARCHFLAG) \
@@ -88,5 +89,6 @@
$(LINK_LAUNCHER/PRE_HOOK) \
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
$(LINK_LAUNCHER/POST_HOOK) \
+ [ -f $(LAUNCHER_G) ] || { ln -s $@ $(LAUNCHER_G); }; \
;; \
esac
--- a/hotspot/make/solaris/makefiles/saproc.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/saproc.make Wed Jul 05 17:04:56 2017 +0200
@@ -25,9 +25,13 @@
# Rules to build serviceability agent library, used by vm.make
# libsaproc[_g].so: serviceability agent
-SAPROC = saproc$(G_SUFFIX)
+
+SAPROC = saproc
LIBSAPROC = lib$(SAPROC).so
+SAPROC_G = $(SAPROC)$(G_SUFFIX)
+LIBSAPROC_G = lib$(SAPROC_G).so
+
AGENT_DIR = $(GAMMADIR)/agent
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)/proc
@@ -69,6 +73,7 @@
$(SA_LFLAGS) \
-o $@ \
-ldl -ldemangle -lthread -lc
+ [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
install_saproc: checkAndBuildSA
$(QUIETLY) if [ -f $(LIBSAPROC) ] ; then \
--- a/hotspot/make/solaris/makefiles/sparcWorks.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make Wed Jul 05 17:04:56 2017 +0200
@@ -281,8 +281,6 @@
OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS)
endif
-CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
-
endif # sparc
ifeq ("${Platform_arch_model}", "x86_32")
@@ -293,13 +291,14 @@
# [phh] Is this still true for 6.1?
OPT_CFLAGS+=-xO3
-CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
-
endif # 32bit x86
# no more exceptions
CFLAGS/NOEX=-noex
+# Inline functions
+CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_${Platform_arch}/vm/solaris_${Platform_arch_model}.il
+
# Reduce code bloat by reverting back to 5.0 behavior for static initializers
CFLAGS += -Qoption ccfe -one_static_init
@@ -312,6 +311,15 @@
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
+# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
+MAPFLAG = -M FILENAME
+
+# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
+SONAMEFLAG = -h SONAME
+
+# Build shared library
+SHARED_FLAG = -G
+
# Would be better if these weren't needed, since we link with CC, but
# at present removing them causes run-time errors
LFLAGS += -library=Crun
--- a/hotspot/make/solaris/makefiles/vm.make Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/make/solaris/makefiles/vm.make Wed Jul 05 17:04:56 2017 +0200
@@ -108,11 +108,16 @@
# older libm before libCrun, just to make sure it's found and used first.
LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc
else
+ifeq ($(COMPILER_REV_NUMERIC), 502)
+# SC6.1 has it's own libm.so: specifying anything else provokes a name conflict.
+LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor
+else
LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor
-endif
+endif # 502
+endif # 505
else
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc
-endif
+endif # sparcWorks
# By default, link the *.o into the library, not the executable.
LINK_INTO$(LINK_INTO) = LIBJVM
@@ -126,8 +131,9 @@
#----------------------------------------------------------------------
# JVM
-JVM = jvm$(G_SUFFIX)
-LIBJVM = lib$(JVM).so
+JVM = jvm
+LIBJVM = lib$(JVM).so
+LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
JVM_OBJ_FILES = $(Obj_Files) $(DTRACE_OBJS)
@@ -173,11 +179,12 @@
-sbfast|-xsbfast) \
;; \
*) \
- echo Linking vm...; \
- $(LINK_LIB.CC/PRE_HOOK) \
- $(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
- $(LINK_LIB.CC/POST_HOOK) \
- rm -f $@.1; ln -s $@ $@.1; \
+ echo Linking vm...; \
+ $(LINK_LIB.CC/PRE_HOOK) \
+ $(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
+ $(LINK_LIB.CC/POST_HOOK) \
+ rm -f $@.1; ln -s $@ $@.1; \
+ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
;; \
esac
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -189,14 +189,17 @@
Register OSR_buf = osrBufferPointer()->as_register();
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
int monitor_offset = BytesPerWord * method()->max_locals() +
- (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
+ (2 * BytesPerWord) * (number_of_locks - 1);
+ // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
+ // the OSR buffer using 2 word entries: first the lock and then
+ // the oop.
for (int i = 0; i < number_of_locks; i++) {
- int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);
+ int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
#ifdef ASSERT
// verify the interpreter's monitor has a non-null object
{
Label L;
- __ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes(), O7);
+ __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ cmp(G0, O7);
__ br(Assembler::notEqual, false, Assembler::pt, L);
__ delayed()->nop();
@@ -205,9 +208,9 @@
}
#endif // ASSERT
// Copy the lock field into the compiled activation.
- __ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes(), O7);
+ __ ld_ptr(OSR_buf, slot_offset + 0, O7);
__ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
- __ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes(), O7);
+ __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ st_ptr(O7, frame_map()->address_for_monitor_object(i));
}
}
@@ -953,9 +956,11 @@
} else {
#ifdef _LP64
assert(base != to_reg->as_register_lo(), "can't handle this");
+ assert(O7 != to_reg->as_register_lo(), "can't handle this");
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
+ __ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last
__ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
- __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
+ __ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo());
#else
if (base == to_reg->as_register_lo()) {
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
@@ -976,8 +981,8 @@
FloatRegister reg = to_reg->as_double_reg();
// split unaligned loads
if (unaligned || PatchALot) {
- __ ldf(FloatRegisterImpl::S, base, offset + BytesPerWord, reg->successor());
- __ ldf(FloatRegisterImpl::S, base, offset, reg);
+ __ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor());
+ __ ldf(FloatRegisterImpl::S, base, offset, reg);
} else {
__ ldf(FloatRegisterImpl::D, base, offset, to_reg->as_double_reg());
}
@@ -2200,6 +2205,7 @@
Register len = O2;
__ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
+ LP64_ONLY(__ sra(src_pos, 0, src_pos);) //higher 32bits must be null
if (shift == 0) {
__ add(src_ptr, src_pos, src_ptr);
} else {
@@ -2208,6 +2214,7 @@
}
__ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
+ LP64_ONLY(__ sra(dst_pos, 0, dst_pos);) //higher 32bits must be null
if (shift == 0) {
__ add(dst_ptr, dst_pos, dst_ptr);
} else {
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -144,17 +144,17 @@
if (index->is_register()) {
// apply the shift and accumulate the displacement
if (shift > 0) {
- LIR_Opr tmp = new_register(T_INT);
+ LIR_Opr tmp = new_pointer_register();
__ shift_left(index, shift, tmp);
index = tmp;
}
if (disp != 0) {
- LIR_Opr tmp = new_register(T_INT);
+ LIR_Opr tmp = new_pointer_register();
if (Assembler::is_simm13(disp)) {
- __ add(tmp, LIR_OprFact::intConst(disp), tmp);
+ __ add(tmp, LIR_OprFact::intptrConst(disp), tmp);
index = tmp;
} else {
- __ move(LIR_OprFact::intConst(disp), tmp);
+ __ move(LIR_OprFact::intptrConst(disp), tmp);
__ add(tmp, index, tmp);
index = tmp;
}
@@ -162,8 +162,8 @@
}
} else if (disp != 0 && !Assembler::is_simm13(disp)) {
// index is illegal so replace it with the displacement loaded into a register
- index = new_register(T_INT);
- __ move(LIR_OprFact::intConst(disp), index);
+ index = new_pointer_register();
+ __ move(LIR_OprFact::intptrConst(disp), index);
disp = 0;
}
--- a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,10 +22,9 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the client compiler.
// (see c1_globals.hpp)
-//
+
#ifndef TIERED
define_pd_global(bool, BackgroundCompilation, true );
define_pd_global(bool, CICompileOSR, true );
@@ -48,27 +47,24 @@
define_pd_global(bool, UseTLAB, true );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(intx, FreqInlineSize, 325 );
-define_pd_global(intx, NewRatio, 8 ); // Design center runs on 1.3.1
define_pd_global(bool, ResizeTLAB, true );
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
-define_pd_global(uintx, PermSize, 12*M );
-define_pd_global(uintx, MaxPermSize, 64*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true);
+define_pd_global(uintx,PermSize, 12*M );
+define_pd_global(uintx,MaxPermSize, 64*M );
+define_pd_global(bool, NeverActAsServerClassMachine, true );
define_pd_global(intx, NewSizeThreadIncrease, 16*K );
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 1ULL*G);
define_pd_global(intx, InitialCodeCacheSize, 160*K);
-#endif // TIERED
+#endif // !TIERED
define_pd_global(bool, UseTypeProfile, false);
define_pd_global(bool, RoundFPResults, false);
-
-define_pd_global(bool, LIRFillDelaySlots, true);
+define_pd_global(bool, LIRFillDelaySlots, true );
define_pd_global(bool, OptimizeSinglePrecision, false);
-define_pd_global(bool, CSEArrayLength, true);
+define_pd_global(bool, CSEArrayLength, true );
define_pd_global(bool, TwoOperandLIRForm, false);
-
-define_pd_global(intx, SafepointPollOffset, 0);
+define_pd_global(intx, SafepointPollOffset, 0 );
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -59,7 +59,6 @@
define_pd_global(intx, FreqInlineSize, 175);
define_pd_global(intx, INTPRESSURE, 48); // large register set
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
-define_pd_global(intx, NewRatio, 2);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
// The default setting 16/16 seems to work best.
// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
@@ -83,25 +82,25 @@
// sequence of instructions to load a 64 bit pointer.
//
// InitialCodeCacheSize derived from specjbb2000 run.
-define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
-define_pd_global(intx, ReservedCodeCacheSize, 48*M);
-define_pd_global(intx, CodeCacheExpansionSize, 64*K);
+define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
+define_pd_global(intx, ReservedCodeCacheSize, 48*M);
+define_pd_global(intx, CodeCacheExpansionSize, 64*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 32*G);
+define_pd_global(uint64_t,MaxRAM, 128ULL*G);
#else
// InitialCodeCacheSize derived from specjbb2000 run.
-define_pd_global(intx, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
-define_pd_global(intx, ReservedCodeCacheSize, 32*M);
-define_pd_global(intx, CodeCacheExpansionSize, 32*K);
+define_pd_global(intx, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
+define_pd_global(intx, ReservedCodeCacheSize, 32*M);
+define_pd_global(intx, CodeCacheExpansionSize, 32*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 4ULL*G);
#endif
-define_pd_global(uintx,CodeCacheMinBlockLength, 4);
+define_pd_global(uintx,CodeCacheMinBlockLength, 4);
// Heap related flags
-define_pd_global(uintx, PermSize, ScaleForWordSize(16*M));
-define_pd_global(uintx, MaxPermSize, ScaleForWordSize(64*M));
+define_pd_global(uintx,PermSize, ScaleForWordSize(16*M));
+define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
// Ergonomics related flags
define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,10 +22,8 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
// For sparc we do not do call backs when a thread is in the interpreter, because the
// interpreter dispatch needs at least two instructions - first to load the dispatch address
@@ -41,26 +39,23 @@
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
-define_pd_global(intx, CodeEntryAlignment, 32);
-define_pd_global(uintx, TLABSize, 0);
-define_pd_global(uintx, NewSize, ScaleForWordSize((2048 * K) + (2 * (64 * K))));
-define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
-define_pd_global(intx, InlineSmallCode, 1500);
+define_pd_global(intx, CodeEntryAlignment, 32);
+define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
+define_pd_global(intx, InlineSmallCode, 1500);
#ifdef _LP64
// 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, ThreadStackSize, 1024);
+define_pd_global(intx, VMThreadStackSize, 1024);
#else
-define_pd_global(intx, ThreadStackSize, 512);
-define_pd_global(intx, VMThreadStackSize, 512);
+define_pd_global(intx, ThreadStackSize, 512);
+define_pd_global(intx, VMThreadStackSize, 512);
#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
+define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
define_pd_global(bool, RewriteBytecodes, true);
define_pd_global(bool, RewriteFrequentPairs, true);
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -150,8 +150,7 @@
}
-address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
- assert(!unbox, "NYI");//6815692//
+address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
address compiled_entry = __ pc();
Label cont;
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2251,6 +2251,7 @@
emit_byte(0x9D);
}
+#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::popl(Address dst) {
// NOTE: this will adjust stack by 8byte on 64bits
InstructionMark im(this);
@@ -2258,6 +2259,7 @@
emit_byte(0x8F);
emit_operand(rax, dst);
}
+#endif
void Assembler::prefetch_prefix(Address src) {
prefix(src);
@@ -2428,6 +2430,7 @@
emit_byte(0x9C);
}
+#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::pushl(Address src) {
// Note this will push 64bit on 64bit
InstructionMark im(this);
@@ -2435,6 +2438,7 @@
emit_byte(0xFF);
emit_operand(rsi, src);
}
+#endif
void Assembler::pxor(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
@@ -5591,7 +5595,12 @@
}
void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) {
- andpd(dst, as_Address(src));
+ if (reachable(src)) {
+ andpd(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ andpd(dst, Address(rscratch1, 0));
+ }
}
void MacroAssembler::andptr(Register dst, int32_t imm32) {
@@ -6078,11 +6087,21 @@
}
void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) {
- comisd(dst, as_Address(src));
+ if (reachable(src)) {
+ comisd(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ comisd(dst, Address(rscratch1, 0));
+ }
}
void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) {
- comiss(dst, as_Address(src));
+ if (reachable(src)) {
+ comiss(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ comiss(dst, Address(rscratch1, 0));
+ }
}
@@ -7647,7 +7666,7 @@
#ifdef ASSERT
Label L;
- testl(tmp, tmp);
+ testptr(tmp, tmp);
jccb(Assembler::notZero, L);
hlt();
bind(L);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -1244,7 +1244,9 @@
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
void pcmpestri(XMMRegister xmm1, Address src, int imm8);
+#ifndef _LP64 // no 32bit push/pop on amd64
void popl(Address dst);
+#endif
#ifdef _LP64
void popq(Address dst);
@@ -1285,7 +1287,9 @@
// Interleave Low Bytes
void punpcklbw(XMMRegister dst, XMMRegister src);
+#ifndef _LP64 // no 32bit push/pop on amd64
void pushl(Address src);
+#endif
void pushq(Address src);
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -301,22 +301,25 @@
Register OSR_buf = osrBufferPointer()->as_pointer_register();
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
int monitor_offset = BytesPerWord * method()->max_locals() +
- (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
+ (2 * BytesPerWord) * (number_of_locks - 1);
+ // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
+ // the OSR buffer using 2 word entries: first the lock and then
+ // the oop.
for (int i = 0; i < number_of_locks; i++) {
- int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);
+ int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
#ifdef ASSERT
// verify the interpreter's monitor has a non-null object
{
Label L;
- __ cmpptr(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);
+ __ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD);
__ jcc(Assembler::notZero, L);
__ stop("locked object is NULL");
__ bind(L);
}
#endif
- __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes()));
+ __ movptr(rbx, Address(OSR_buf, slot_offset + 0));
__ movptr(frame_map()->address_for_monitor_lock(i), rbx);
- __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()));
+ __ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord));
__ movptr(frame_map()->address_for_monitor_object(i), rbx);
}
}
@@ -785,7 +788,13 @@
ShouldNotReachHere();
__ movoop(as_Address(addr, noreg), c->as_jobject());
} else {
+#ifdef _LP64
+ __ movoop(rscratch1, c->as_jobject());
+ null_check_here = code_offset();
+ __ movptr(as_Address_lo(addr), rscratch1);
+#else
__ movoop(as_Address(addr), c->as_jobject());
+#endif
}
}
break;
@@ -1118,8 +1127,14 @@
__ pushptr(frame_map()->address_for_slot(src ->single_stack_ix()));
__ popptr (frame_map()->address_for_slot(dest->single_stack_ix()));
} else {
+#ifndef _LP64
__ pushl(frame_map()->address_for_slot(src ->single_stack_ix()));
__ popl (frame_map()->address_for_slot(dest->single_stack_ix()));
+#else
+ //no pushl on 64bits
+ __ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix()));
+ __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1);
+#endif
}
} else if (src->is_double_stack()) {
@@ -3136,8 +3151,10 @@
#ifdef _LP64
assert_different_registers(c_rarg0, dst, dst_pos, length);
+ __ movl2ptr(src_pos, src_pos); //higher 32bits must be null
__ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
assert_different_registers(c_rarg1, length);
+ __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null
__ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
__ mov(c_rarg2, length);
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -755,8 +755,19 @@
}
LIR_Opr addr = new_pointer_register();
- __ move(obj.result(), addr);
- __ add(addr, offset.result(), addr);
+ LIR_Address* a;
+ if(offset.result()->is_constant()) {
+ a = new LIR_Address(obj.result(),
+ NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()),
+ as_BasicType(type));
+ } else {
+ a = new LIR_Address(obj.result(),
+ offset.result(),
+ LIR_Address::times_1,
+ 0,
+ as_BasicType(type));
+ }
+ __ leal(LIR_OprFact::address(a), addr);
if (type == objectType) { // Write-barrier needed for Object fields.
// Do the pre-write barrier, if any.
--- a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,10 +22,8 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the client compiler.
// (see c1_globals.hpp)
-//
#ifndef TIERED
define_pd_global(bool, BackgroundCompilation, true );
@@ -48,27 +46,24 @@
define_pd_global(intx, OnStackReplacePercentage, 933 );
define_pd_global(intx, FreqInlineSize, 325 );
-define_pd_global(intx, NewRatio, 12 );
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
define_pd_global(intx, InitialCodeCacheSize, 160*K);
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
-define_pd_global(uintx, PermSize, 12*M );
-define_pd_global(uintx, MaxPermSize, 64*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true);
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uintx,PermSize, 12*M );
+define_pd_global(uintx,MaxPermSize, 64*M );
+define_pd_global(bool, NeverActAsServerClassMachine, true );
+define_pd_global(uint64_t,MaxRAM, 1ULL*G);
define_pd_global(bool, CICompileOSR, true );
-#endif // TIERED
+#endif // !TIERED
define_pd_global(bool, UseTypeProfile, false);
define_pd_global(bool, RoundFPResults, true );
-
define_pd_global(bool, LIRFillDelaySlots, false);
-define_pd_global(bool, OptimizeSinglePrecision, true);
+define_pd_global(bool, OptimizeSinglePrecision, true );
define_pd_global(bool, CSEArrayLength, false);
-define_pd_global(bool, TwoOperandLIRForm, true);
+define_pd_global(bool, TwoOperandLIRForm, true );
-
-define_pd_global(intx, SafepointPollOffset, 256);
+define_pd_global(intx, SafepointPollOffset, 256 );
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,7 +22,6 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the server compiler.
// (see c2_globals.hpp). Alpha-sorted.
@@ -46,8 +45,8 @@
define_pd_global(intx, CompileThreshold, 10000);
#endif // TIERED
define_pd_global(intx, Tier2CompileThreshold, 10000);
-define_pd_global(intx, Tier3CompileThreshold, 20000 );
-define_pd_global(intx, Tier4CompileThreshold, 40000 );
+define_pd_global(intx, Tier3CompileThreshold, 20000);
+define_pd_global(intx, Tier4CompileThreshold, 40000);
define_pd_global(intx, BackEdgeThreshold, 100000);
define_pd_global(intx, Tier2BackEdgeThreshold, 100000);
@@ -61,7 +60,6 @@
#ifdef AMD64
define_pd_global(intx, INTPRESSURE, 13);
define_pd_global(intx, InteriorEntryAlignment, 16);
-define_pd_global(intx, NewRatio, 2);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
define_pd_global(intx, LoopUnrollLimit, 60);
// InitialCodeCacheSize derived from specjbb2000 run.
@@ -69,19 +67,18 @@
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 32*G);
+define_pd_global(uint64_t,MaxRAM, 128ULL*G);
#else
define_pd_global(intx, INTPRESSURE, 6);
define_pd_global(intx, InteriorEntryAlignment, 4);
-define_pd_global(intx, NewRatio, 8); // Design center runs on 1.3.1
define_pd_global(intx, NewSizeThreadIncrease, 4*K);
-define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
+define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
// InitialCodeCacheSize derived from specjbb2000 run.
define_pd_global(intx, InitialCodeCacheSize, 2304*K); // Integral multiple of CodeCacheExpansionSize
define_pd_global(intx, CodeCacheExpansionSize, 32*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 4ULL*G);
#endif // AMD64
define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, RegisterCostAreaRatio, 16000);
@@ -97,8 +94,8 @@
define_pd_global(uintx,CodeCacheMinBlockLength, 4);
// Heap related flags
-define_pd_global(uintx, PermSize, ScaleForWordSize(16*M));
-define_pd_global(uintx, MaxPermSize, ScaleForWordSize(64*M));
+define_pd_global(uintx,PermSize, ScaleForWordSize(16*M));
+define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
// Ergonomics related flags
define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,17 +22,16 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
-define_pd_global(bool, ConvertSleepToYield, true);
-define_pd_global(bool, ShareVtableStubs, true);
-define_pd_global(bool, CountInterpCalls, true);
+define_pd_global(bool, ConvertSleepToYield, true);
+define_pd_global(bool, ShareVtableStubs, true);
+define_pd_global(bool, CountInterpCalls, true);
+define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
-define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
-define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
+define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
+define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
// See 4827828 for this change. There is no globals_core_i486.hpp. I can't
// assign a different value for C2 without touching a number of files. Use
@@ -42,29 +41,24 @@
// the uep and the vep doesn't get real alignment but just slops on by
// only assured that the entry instruction meets the 5 byte size requirement.
#ifdef COMPILER2
-define_pd_global(intx, CodeEntryAlignment, 32);
+define_pd_global(intx, CodeEntryAlignment, 32);
#else
-define_pd_global(intx, CodeEntryAlignment, 16);
+define_pd_global(intx, CodeEntryAlignment, 16);
#endif // COMPILER2
+define_pd_global(intx, InlineFrequencyCount, 100);
+define_pd_global(intx, InlineSmallCode, 1000);
-define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
-
-define_pd_global(uintx, TLABSize, 0);
+define_pd_global(intx, StackYellowPages, 2);
+define_pd_global(intx, StackRedPages, 1);
#ifdef AMD64
-define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K));
// 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));
#else
-define_pd_global(uintx, NewSize, 1024 * K);
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
#endif // AMD64
-define_pd_global(intx, InlineFrequencyCount, 100);
-define_pd_global(intx, InlineSmallCode, 1000);
-define_pd_global(intx, PreInflateSpin, 10);
-define_pd_global(intx, StackYellowPages, 2);
-define_pd_global(intx, StackRedPages, 1);
+define_pd_global(intx, PreInflateSpin, 10);
define_pd_global(bool, RewriteBytecodes, true);
define_pd_global(bool, RewriteFrequentPairs, true);
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -196,6 +196,9 @@
} else {
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
movl(reg, Address(rsi, bcp_offset));
+ // Check if the secondary index definition is still ~x, otherwise
+ // we have to change the following assembler code to calculate the
+ // plain index.
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
notl(reg); // convert to plain index
}
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -185,12 +185,30 @@
}
+void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
+ int bcp_offset,
+ bool giant_index) {
+ assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+ if (!giant_index) {
+ load_unsigned_short(index, Address(r13, bcp_offset));
+ } else {
+ assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
+ movl(index, Address(r13, bcp_offset));
+ // Check if the secondary index definition is still ~x, otherwise
+ // we have to change the following assembler code to calculate the
+ // plain index.
+ assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
+ notl(index); // convert to plain index
+ }
+}
+
+
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
Register index,
- int bcp_offset) {
- assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+ int bcp_offset,
+ bool giant_index) {
assert(cache != index, "must use different registers");
- load_unsigned_short(index, Address(r13, bcp_offset));
+ get_cache_index_at_bcp(index, bcp_offset, giant_index);
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
// convert from field index to ConstantPoolCacheEntry index
@@ -200,10 +218,10 @@
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
Register tmp,
- int bcp_offset) {
- assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+ int bcp_offset,
+ bool giant_index) {
assert(cache != tmp, "must use different register");
- load_unsigned_short(tmp, Address(r13, bcp_offset));
+ get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
// convert from field index to ConstantPoolCacheEntry index
// and from word offset to byte offset
@@ -1236,7 +1254,8 @@
void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
Register mdp,
- Register reg2) {
+ Register reg2,
+ bool receiver_can_be_null) {
if (ProfileInterpreter) {
Label profile_continue;
@@ -1246,8 +1265,15 @@
// We are making a call. Increment the count.
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ Label skip_receiver_profile;
+ if (receiver_can_be_null) {
+ testptr(receiver, receiver);
+ jcc(Assembler::zero, skip_receiver_profile);
+ }
+
// Record the receiver type.
record_klass_in_profile(receiver, mdp, reg2);
+ bind(skip_receiver_profile);
// The method data pointer needs to be updated to reflect the new target.
update_mdp_by_constant(mdp,
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -95,9 +95,10 @@
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
void get_cache_and_index_at_bcp(Register cache, Register index,
- int bcp_offset);
+ int bcp_offset, bool giant_index = false);
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
- int bcp_offset);
+ int bcp_offset, bool giant_index = false);
+ void get_cache_index_at_bcp(Register index, int bcp_offset, bool giant_index = false);
void pop_ptr(Register r = rax);
@@ -236,7 +237,8 @@
void profile_call(Register mdp);
void profile_final_call(Register mdp);
void profile_virtual_call(Register receiver, Register mdp,
- Register scratch2);
+ Register scratch2,
+ bool receiver_can_be_null = false);
void profile_ret(Register return_bci, Register mdp);
void profile_null_seen(Register mdp);
void profile_typecheck(Register mdp, Register klass, Register scratch);
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -277,12 +277,11 @@
address entry_point = __ pc();
// abstract method entry
- // remove return address. Not really needed, since exception
- // handling throws away expression stack
- __ pop(rbx);
- // adjust stack to what a normal return would do
- __ mov(rsp, r13);
+ // pop return address, reset last_sp to NULL
+ __ empty_expression_stack();
+ __ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
+ __ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
// throw exception
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
@@ -300,7 +299,10 @@
if (!EnableMethodHandles) {
return generate_abstract_entry();
}
- return generate_abstract_entry(); //6815692//
+
+ address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);
+
+ return entry_point;
}
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -448,7 +448,7 @@
rbx_index, Address::times_ptr,
base + vtableEntry::method_offset_in_bytes());
Register rbx_method = rbx_temp;
- __ movl(rbx_method, vtable_entry_addr);
+ __ movptr(rbx_method, vtable_entry_addr);
__ verify_oop(rbx_method);
__ jmp(rbx_method_fie);
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2935,6 +2935,16 @@
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
+
+ // generic method handle stubs
+ if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
+ for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
+ ek < MethodHandles::_EK_LIMIT;
+ ek = MethodHandles::EntryKind(1 + (int)ek)) {
+ StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
+ MethodHandles::generate_method_handle_stub(_masm, ek);
+ }
+ }
}
public:
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -155,15 +155,8 @@
}
-address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
+address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
TosState incoming_state = state;
- if (EnableInvokeDynamic) {
- if (unbox) {
- incoming_state = atos;
- }
- } else {
- assert(!unbox, "old behavior");
- }
Label interpreter_entry;
address compiled_entry = __ pc();
@@ -216,46 +209,6 @@
__ restore_bcp();
__ restore_locals();
- Label L_fail;
-
- if (unbox && state != atos) {
- // cast and unbox
- BasicType type = as_BasicType(state);
- if (type == T_BYTE) type = T_BOOLEAN; // FIXME
- KlassHandle boxk = SystemDictionaryHandles::box_klass(type);
- __ mov32(rbx, ExternalAddress((address) boxk.raw_value()));
- __ testl(rax, rax);
- Label L_got_value, L_get_value;
- // convert nulls to zeroes (avoid NPEs here)
- if (!(type == T_FLOAT || type == T_DOUBLE)) {
- // if rax already contains zero bits, forge ahead
- __ jcc(Assembler::zero, L_got_value);
- } else {
- __ jcc(Assembler::notZero, L_get_value);
- __ fldz();
- __ jmp(L_got_value);
- }
- __ bind(L_get_value);
- __ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes()));
- __ jcc(Assembler::notEqual, L_fail);
- int offset = java_lang_boxing_object::value_offset_in_bytes(type);
- // Cf. TemplateTable::getfield_or_static
- switch (type) {
- case T_BYTE: // fall through:
- case T_BOOLEAN: __ load_signed_byte(rax, Address(rax, offset)); break;
- case T_CHAR: __ load_unsigned_short(rax, Address(rax, offset)); break;
- case T_SHORT: __ load_signed_short(rax, Address(rax, offset)); break;
- case T_INT: __ movl(rax, Address(rax, offset)); break;
- case T_FLOAT: __ fld_s(Address(rax, offset)); break;
- case T_DOUBLE: __ fld_d(Address(rax, offset)); break;
- // Access to java.lang.Double.value does not need to be atomic:
- case T_LONG: { __ movl(rdx, Address(rax, offset + 4));
- __ movl(rax, Address(rax, offset + 0)); } break;
- default: ShouldNotReachHere();
- }
- __ bind(L_got_value);
- }
-
Label L_got_cache, L_giant_index;
if (EnableInvokeDynamic) {
__ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
@@ -263,32 +216,6 @@
}
__ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
__ bind(L_got_cache);
- if (unbox && state == atos) {
- // insert a casting conversion, to keep verifier sane
- Label L_ok, L_ok_pops;
- __ testl(rax, rax);
- __ jcc(Assembler::zero, L_ok);
- __ push(rax); // save the object to check
- __ push(rbx); // save CP cache reference
- __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes()));
- __ movl(rbx, Address(rbx, rcx,
- Address::times_4, constantPoolCacheOopDesc::base_offset() +
- ConstantPoolCacheEntry::f1_offset()));
- __ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));
- __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx)));
- __ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx)));
- __ check_klass_subtype(rdx, rax, rbx, L_ok_pops);
- __ pop(rcx); // pop and discard CP cache
- __ mov(rbx, rax); // target supertype into rbx for L_fail
- __ pop(rax); // failed object into rax for L_fail
- __ jmp(L_fail);
-
- __ bind(L_ok_pops);
- // restore pushed temp regs:
- __ pop(rbx);
- __ pop(rax);
- __ bind(L_ok);
- }
__ movl(rbx, Address(rbx, rcx,
Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::flags_offset()));
@@ -301,14 +228,6 @@
__ bind(L_giant_index);
__ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
__ jmp(L_got_cache);
-
- if (unbox) {
- __ bind(L_fail);
- __ push(rbx); // missed klass (required)
- __ push(rax); // bad object (actual)
- __ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry));
- __ call(rdx);
- }
}
return entry;
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -100,21 +100,26 @@
return entry;
}
-// Arguments are: required type in rarg1, failing object (or NULL) in rarg2
+// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
address entry = __ pc();
__ pop(c_rarg2); // failing object is at TOS
__ pop(c_rarg1); // required type is at TOS+8
- // expression stack must be empty before entering the VM if an
- // exception happened
+ __ verify_oop(c_rarg1);
+ __ verify_oop(c_rarg2);
+
+ // Various method handle types use interpreter registers as temps.
+ __ restore_bcp();
+ __ restore_locals();
+
+ // Expression stack must be empty before entering the VM for an exception.
__ empty_expression_stack();
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
- InterpreterRuntime::
- throw_WrongMethodTypeException),
+ InterpreterRuntime::throw_WrongMethodTypeException),
// pass required type, failing object (or NULL)
c_rarg1, c_rarg2);
return entry;
@@ -166,8 +171,7 @@
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
- int step, bool unbox) {
- assert(!unbox, "NYI");//6815692//
+ int step) {
// amd64 doesn't need to do anything special about compiled returns
// to the interpreter so the code that exists on x86 to place a sentinel
@@ -183,15 +187,29 @@
__ restore_bcp();
__ restore_locals();
- __ get_cache_and_index_at_bcp(rbx, rcx, 1);
+ Label L_got_cache, L_giant_index;
+ if (EnableInvokeDynamic) {
+ __ cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
+ __ jcc(Assembler::equal, L_giant_index);
+ }
+ __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
+ __ bind(L_got_cache);
__ movl(rbx, Address(rbx, rcx,
- Address::times_8,
+ Address::times_ptr,
in_bytes(constantPoolCacheOopDesc::base_offset()) +
3 * wordSize));
__ andl(rbx, 0xFF);
if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
__ lea(rsp, Address(rsp, rbx, Address::times_8));
__ dispatch_next(state, step);
+
+ // out of the main line of code...
+ if (EnableInvokeDynamic) {
+ __ bind(L_giant_index);
+ __ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
+ __ jmp(L_got_cache);
+ }
+
return entry;
}
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2890,9 +2890,6 @@
void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
- bool is_invdyn_bootstrap = (byte_no < 0);
- if (is_invdyn_bootstrap) byte_no = -byte_no;
-
// determine flags
Bytecodes::Code code = bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
@@ -2907,8 +2904,6 @@
const Register flags = rdx;
assert_different_registers(method, index, recv, flags);
- assert(!is_invdyn_bootstrap || is_invokedynamic, "byte_no<0 hack only for invdyn");
-
// save 'interpreter return address'
__ save_bcp();
@@ -2944,9 +2939,7 @@
// load return address
{
address table_addr;
- if (is_invdyn_bootstrap)
- table_addr = (address)Interpreter::return_5_unbox_addrs_by_index_table();
- else if (is_invokeinterface || is_invokedynamic)
+ if (is_invokeinterface || is_invokedynamic)
table_addr = (address)Interpreter::return_5_addrs_by_index_table();
else
table_addr = (address)Interpreter::return_3_addrs_by_index_table();
@@ -3153,54 +3146,10 @@
__ profile_call(rsi);
}
- Label handle_unlinked_site;
- __ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
- __ testptr(rcx, rcx);
- __ jcc(Assembler::zero, handle_unlinked_site);
-
+ __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ null_check(rcx);
__ prepare_to_jump_from_interpreted();
__ jump_to_method_handle_entry(rcx, rdx);
-
- // Initial calls come here...
- __ bind(handle_unlinked_site);
- __ pop(rcx); // remove return address pushed by prepare_invoke
-
- // box stacked arguments into an array for the bootstrap method
- address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);
- __ restore_bcp(); // rsi must be correct for call_VM
- __ call_VM(rax, entry, rax);
- __ movl(rdi, rax); // protect bootstrap MH from prepare_invoke
-
- // recompute return address
- __ restore_bcp(); // rsi must be correct for prepare_invoke
- prepare_invoke(rax, rbx, -byte_no); // smashes rcx, rdx
- // rax: CallSite object (f1)
- // rbx: unused (f2)
- // rdi: bootstrap MH
- // rdx: flags
-
- // now load up the arglist, which has been neatly boxed
- __ get_thread(rcx);
- __ movptr(rdx, Address(rcx, JavaThread::vm_result_2_offset()));
- __ movptr(Address(rcx, JavaThread::vm_result_2_offset()), NULL_WORD);
- __ verify_oop(rdx);
- // rdx = arglist
-
- // save SP now, before we add the bootstrap call to the stack
- // We must preserve a fiction that the original arguments are outgoing,
- // because the return sequence will reset the stack to this point
- // and then pop all those arguments. It seems error-prone to use
- // a different argument list size just for bootstrapping.
- __ prepare_to_jump_from_interpreted();
-
- // Now let's play adapter, pushing the real arguments on the stack.
- __ pop(rbx); // return PC
- __ push(rdi); // boot MH
- __ push(rax); // call site
- __ push(rdx); // arglist
- __ push(rbx); // return PC, again
- __ mov(rcx, rdi);
- __ jump_to_method_handle_entry(rcx, rdx);
}
//----------------------------------------------------------------------------------------------------
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -203,18 +203,15 @@
__ jcc(Assembler::notEqual, fast_patch);
__ get_method(scratch);
// Let breakpoint table handling rewrite to quicker bytecode
- __ call_VM(noreg,
- CAST_FROM_FN_PTR(address,
- InterpreterRuntime::set_original_bytecode_at),
- scratch, r13, bc);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc);
#ifndef ASSERT
__ jmpb(patch_done);
+#else
+ __ jmp(patch_done);
+#endif
__ bind(fast_patch);
}
-#else
- __ jmp(patch_done);
- __ bind(fast_patch);
- }
+#ifdef ASSERT
Label okay;
__ load_unsigned_byte(scratch, at_bcp(0));
__ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
@@ -2054,26 +2051,28 @@
}
}
-void TemplateTable::resolve_cache_and_index(int byte_no,
- Register Rcache,
- Register index) {
+void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
+ bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
const Register temp = rbx;
assert_different_registers(Rcache, index, temp);
const int shift_count = (1 + byte_no) * BitsPerByte;
Label resolved;
- __ get_cache_and_index_at_bcp(Rcache, index, 1);
- __ movl(temp, Address(Rcache,
- index, Address::times_8,
- constantPoolCacheOopDesc::base_offset() +
- ConstantPoolCacheEntry::indices_offset()));
- __ shrl(temp, shift_count);
- // have we resolved this bytecode?
- __ andl(temp, 0xFF);
- __ cmpl(temp, (int) bytecode());
- __ jcc(Assembler::equal, resolved);
+ __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
+ if (is_invokedynamic) {
+ // we are resolved if the f1 field contains a non-null CallSite object
+ __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
+ __ jcc(Assembler::notEqual, resolved);
+ } else {
+ __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
+ __ shrl(temp, shift_count);
+ // have we resolved this bytecode?
+ __ andl(temp, 0xFF);
+ __ cmpl(temp, (int) bytecode());
+ __ jcc(Assembler::equal, resolved);
+ }
// resolve first time through
address entry;
@@ -2090,6 +2089,9 @@
case Bytecodes::_invokeinterface:
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
break;
+ case Bytecodes::_invokedynamic:
+ entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
+ break;
default:
ShouldNotReachHere();
break;
@@ -2098,7 +2100,7 @@
__ call_VM(noreg, entry, temp);
// Update registers with resolved info
- __ get_cache_and_index_at_bcp(Rcache, index, 1);
+ __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
__ bind(resolved);
}
@@ -2832,15 +2834,14 @@
ShouldNotReachHere();
}
-void TemplateTable::prepare_invoke(Register method,
- Register index,
- int byte_no,
- Bytecodes::Code code) {
+void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
// determine flags
+ Bytecodes::Code code = bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
+ const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
const bool is_invokespecial = code == Bytecodes::_invokespecial;
- const bool load_receiver = code != Bytecodes::_invokestatic;
+ const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
const bool receiver_null_check = is_invokespecial;
const bool save_flags = is_invokeinterface || is_invokevirtual;
// setup registers & access constant pool cache
@@ -2858,9 +2859,13 @@
__ movl(recv, flags);
__ andl(recv, 0xFF);
if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
- __ movptr(recv, Address(rsp, recv, Address::times_8,
- -Interpreter::expr_offset_in_bytes(1)));
- __ verify_oop(recv);
+ Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
+ if (is_invokedynamic) {
+ __ lea(recv, recv_addr);
+ } else {
+ __ movptr(recv, recv_addr);
+ __ verify_oop(recv);
+ }
}
// do null check if needed
@@ -2878,10 +2883,14 @@
ConstantPoolCacheEntry::verify_tosBits();
// load return address
{
- ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table());
- ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table());
- __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3));
- __ movptr(flags, Address(rscratch1, flags, Address::times_8));
+ address table_addr;
+ if (is_invokeinterface || is_invokedynamic)
+ table_addr = (address)Interpreter::return_5_addrs_by_index_table();
+ else
+ table_addr = (address)Interpreter::return_3_addrs_by_index_table();
+ ExternalAddress table(table_addr);
+ __ lea(rscratch1, table);
+ __ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
}
// push return address
@@ -2947,7 +2956,7 @@
void TemplateTable::invokevirtual(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
+ prepare_invoke(rbx, noreg, byte_no);
// rbx: index
// rcx: receiver
@@ -2959,7 +2968,7 @@
void TemplateTable::invokespecial(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
+ prepare_invoke(rbx, noreg, byte_no);
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
@@ -2969,7 +2978,7 @@
void TemplateTable::invokestatic(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
+ prepare_invoke(rbx, noreg, byte_no);
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
@@ -2983,7 +2992,7 @@
void TemplateTable::invokeinterface(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rax, rbx, byte_no, bytecode());
+ prepare_invoke(rax, rbx, byte_no);
// rax: Interface
// rbx: index
@@ -3072,7 +3081,24 @@
return;
}
- __ stop("invokedynamic NYI");//6815692//
+ prepare_invoke(rax, rbx, byte_no);
+
+ // rax: CallSite object (f1)
+ // rbx: unused (f2)
+ // rcx: receiver address
+ // rdx: flags (unused)
+
+ if (ProfileInterpreter) {
+ Label L;
+ // %%% should make a type profile for any invokedynamic that takes a ref argument
+ // profile this call
+ __ profile_call(r13);
+ }
+
+ __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ null_check(rcx);
+ __ prepare_to_jump_from_interpreted();
+ __ jump_to_method_handle_entry(rcx, rdx);
}
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,8 +22,7 @@
*
*/
- static void prepare_invoke(Register method, Register index, int byte_no,
- Bytecodes::Code code);
+ static void prepare_invoke(Register method, Register index, int byte_no);
static void invokevirtual_helper(Register index, Register recv,
Register flags);
static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -255,6 +255,8 @@
if (!VM_Version::supports_sse2()) {
vm_exit_during_initialization("Unknown x64 processor: SSE2 not supported");
}
+ // in 64 bit the use of SSE2 is the minimum
+ if (UseSSE < 2) UseSSE = 2;
#endif
// If the OS doesn't support SSE, we can't use this feature even if the HW does
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -204,6 +204,20 @@
goto unwind_and_return;
}
+ // Update the invocation counter
+ if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
+ thread->set_do_not_unlock();
+ InvocationCounter *counter = method->invocation_counter();
+ counter->increment();
+ if (counter->reached_InvocationLimit()) {
+ CALL_VM_NOCHECK(
+ InterpreterRuntime::frequency_counter_overflow(thread, NULL));
+ if (HAS_PENDING_EXCEPTION)
+ goto unwind_and_return;
+ }
+ thread->clr_do_not_unlock();
+ }
+
// Lock if necessary
BasicObjectLock *monitor;
monitor = NULL;
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -36,11 +36,8 @@
return zeroframe()->is_interpreter_frame();
}
-bool frame::is_fake_stub_frame() const {
- return zeroframe()->is_fake_stub_frame();
-}
-
frame frame::sender_for_entry_frame(RegisterMap *map) const {
+ assert(zeroframe()->is_entry_frame(), "wrong type of frame");
assert(map != NULL, "map must be set");
assert(!entry_frame_is_first(), "next Java fp must be non zero");
assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
@@ -50,15 +47,10 @@
return frame(sender_sp(), sp() + 1);
}
-frame frame::sender_for_interpreter_frame(RegisterMap *map) const {
- return frame(sender_sp(), sp() + 1);
-}
-
-frame frame::sender_for_compiled_frame(RegisterMap *map) const {
- return frame(sender_sp(), sp() + 1);
-}
-
-frame frame::sender_for_fake_stub_frame(RegisterMap *map) const {
+frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
+ assert(zeroframe()->is_interpreter_frame() ||
+ zeroframe()->is_shark_frame() ||
+ zeroframe()->is_fake_stub_frame(), "wrong type of frame");
return frame(sender_sp(), sp() + 1);
}
@@ -69,17 +61,8 @@
if (is_entry_frame())
return sender_for_entry_frame(map);
-
- if (is_interpreted_frame())
- return sender_for_interpreter_frame(map);
-
- if (is_compiled_frame())
- return sender_for_compiled_frame(map);
-
- if (is_fake_stub_frame())
- return sender_for_fake_stub_frame(map);
-
- ShouldNotReachHere();
+ else
+ return sender_for_nonentry_frame(map);
}
#ifdef CC_INTERP
--- a/hotspot/src/cpu/zero/vm/frame_zero.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -65,10 +65,7 @@
}
public:
- bool is_fake_stub_frame() const;
-
- public:
- frame sender_for_fake_stub_frame(RegisterMap* map) const;
+ frame sender_for_nonentry_frame(RegisterMap* map) const;
public:
void zero_print_on_error(int index,
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -23,10 +23,8 @@
*
*/
-//
// Set the default values for platform dependent flags used by the
// runtime system. See globals.hpp for details of what they do.
-//
define_pd_global(bool, ConvertSleepToYield, true);
define_pd_global(bool, ShareVtableStubs, true);
@@ -37,14 +35,7 @@
define_pd_global(bool, UncommonNullCast, true);
define_pd_global(intx, CodeEntryAlignment, 32);
-define_pd_global(uintx, TLABSize, 0);
-#ifdef _LP64
-define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K));
-#else
-define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K));
-#endif // _LP64
define_pd_global(intx, InlineFrequencyCount, 100);
-define_pd_global(intx, InlineSmallCode, 1000);
define_pd_global(intx, PreInflateSpin, 10);
define_pd_global(intx, StackYellowPages, 2);
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1,6 +1,6 @@
/*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
* 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,14 @@
BasicType *in_sig_bt,
VMRegPair *in_regs,
BasicType ret_type) {
+#ifdef SHARK
+ return SharkCompiler::compiler()->generate_native_wrapper(masm,
+ method,
+ in_sig_bt,
+ ret_type);
+#else
ShouldNotCallThis();
+#endif // SHARK
}
int Deoptimization::last_frame_adjust(int callee_parameters,
--- a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -1,6 +1,6 @@
/*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright 2008 Red Hat, Inc.
+ * Copyright 2008, 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
// | ... |
class SharkFrame : public ZeroFrame {
- friend class SharkFunction;
+ friend class SharkStack;
private:
SharkFrame() : ZeroFrame() {
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -223,8 +223,8 @@
"environment on Linux when /proc filesystem is not mounted.";
void os::Linux::initialize_system_info() {
- _processor_count = sysconf(_SC_NPROCESSORS_CONF);
- if (_processor_count == 1) {
+ set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
+ if (processor_count() == 1) {
pid_t pid = os::Linux::gettid();
char fname[32];
jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
@@ -236,7 +236,7 @@
}
}
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
- assert(_processor_count > 0, "linux error");
+ assert(processor_count() > 0, "linux error");
}
void os::init_system_properties_values() {
@@ -4683,6 +4683,7 @@
// Return immediately if a permit is available.
if (_counter > 0) {
_counter = 0 ;
+ OrderAccess::fence();
return ;
}
@@ -4725,6 +4726,7 @@
_counter = 0;
status = pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ OrderAccess::fence();
return;
}
@@ -4765,6 +4767,7 @@
jt->java_suspend_self();
}
+ OrderAccess::fence();
}
void Parker::unpark() {
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c Wed Jul 05 17:04:56 2017 +0200
@@ -937,54 +937,56 @@
return err;
}
-static int
-scopeDesc_chain(Nmethod_t *N)
-{
+static int scopeDesc_chain(Nmethod_t *N) {
int32_t decode_offset = 0;
int32_t err;
- if (debug > 2)
- fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
+ }
err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
&decode_offset, SZ32);
CHECK_FAIL(err);
while (decode_offset > 0) {
- if (debug > 2)
- fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
+ Vframe_t *vf = &N->vframes[N->vf_cnt];
- Vframe_t *vf = &N->vframes[N->vf_cnt];
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
+ }
+
+ err = scope_desc_at(N, decode_offset, vf);
+ CHECK_FAIL(err);
- err = scope_desc_at(N, decode_offset, vf);
- CHECK_FAIL(err);
+ if (vf->methodIdx > N->oops_len) {
+ fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
+ return -1;
+ }
+ err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
+ &vf->methodOop);
+ CHECK_FAIL(err);
- if (vf->methodIdx > N->oops_len) {
- fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
- return -1;
- }
- err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
- &vf->methodOop);
+ if (vf->methodOop) {
+ N->vf_cnt++;
+ err = line_number_from_bci(N->J, vf);
CHECK_FAIL(err);
-
- if (vf->methodOop) {
- N->vf_cnt++;
- err = line_number_from_bci(N->J, vf);
- CHECK_FAIL(err);
- if (debug > 2) {
- fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
- vf->methodOop, vf->line);
- }
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
+ vf->methodOop, vf->line);
}
- decode_offset = vf->sender_decode_offset;
+ }
+ decode_offset = vf->sender_decode_offset;
}
- if (debug > 2)
- fprintf(stderr, "\t scopeDesc_chain: END \n\n");
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: END \n\n");
+ }
return PS_OK;
fail:
- if (debug)
- fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
+ if (debug) {
+ fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
+ }
return err;
}
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -457,7 +457,7 @@
void os::Solaris::initialize_system_info() {
- _processor_count = sysconf(_SC_NPROCESSORS_CONF);
+ set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
_processors_online = sysconf (_SC_NPROCESSORS_ONLN);
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
}
@@ -5803,6 +5803,7 @@
// Return immediately if a permit is available.
if (_counter > 0) {
_counter = 0 ;
+ OrderAccess::fence();
return ;
}
@@ -5846,6 +5847,7 @@
_counter = 0;
status = os::Solaris::mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ OrderAccess::fence();
return;
}
@@ -5892,6 +5894,7 @@
jt->java_suspend_self();
}
+ OrderAccess::fence();
}
void Parker::unpark() {
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -3150,7 +3150,7 @@
_vm_allocation_granularity = si.dwAllocationGranularity;
_processor_type = si.dwProcessorType;
_processor_level = si.wProcessorLevel;
- _processor_count = si.dwNumberOfProcessors;
+ set_processor_count(si.dwNumberOfProcessors);
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(ms);
--- a/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,10 +22,9 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
+
define_pd_global(bool, DontYieldALot, false);
#ifdef AMD64
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
@@ -39,11 +38,10 @@
#endif // AMD64
define_pd_global(intx, CompilerThreadStackSize, 0);
-define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
+define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
// Only used on 64 bit platforms
-define_pd_global(uintx, HeapBaseMinAddress, 2*G);
+define_pd_global(uintx,HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
--- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,31 +22,25 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
+
define_pd_global(bool, DontYieldALot, true); // Determined in the design center
#ifdef AMD64
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
define_pd_global(intx, VMThreadStackSize, 1024);
-define_pd_global(intx, SurvivorRatio, 6);
-define_pd_global(uintx, JVMInvokeMethodSlack, 8*K);
+define_pd_global(uintx,JVMInvokeMethodSlack, 8*K);
#else
-// UseStackBanging is not pd
-// define_pd_global(bool, UseStackBanging, true);
-
// ThreadStackSize 320 allows TaggedStackInterpreter and a couple of test cases
// to run while keeping the number of threads that can be created high.
define_pd_global(intx, ThreadStackSize, 320);
define_pd_global(intx, VMThreadStackSize, 512);
-define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(uintx, JVMInvokeMethodSlack, 10*K);
+define_pd_global(uintx,JVMInvokeMethodSlack, 10*K);
#endif // AMD64
define_pd_global(intx, CompilerThreadStackSize, 0);
// Only used on 64 bit platforms
-define_pd_global(uintx, HeapBaseMinAddress, 256*M);
+define_pd_global(uintx,HeapBaseMinAddress, 256*M);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
--- a/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -22,10 +22,9 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
+
define_pd_global(bool, DontYieldALot, false);
// Default stack size on Windows is determined by the executable (java.exe
@@ -35,8 +34,6 @@
define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default
-define_pd_global(intx, SurvivorRatio, 8);
-
#ifdef ASSERT
define_pd_global(intx, CompilerThreadStackSize, 1024);
#else
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -365,7 +365,7 @@
if (_next_loop_index < 31) _next_loop_index++;
} else {
// block already marked as loop header
- assert(is_power_of_2(_loop_map.at(block->block_id())), "exactly one bit must be set");
+ assert(is_power_of_2((unsigned int)_loop_map.at(block->block_id())), "exactly one bit must be set");
}
}
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1855,12 +1855,26 @@
addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
} else {
#ifdef X86
+#ifdef _LP64
+ if (!index_op->is_illegal() && index_op->type() == T_INT) {
+ LIR_Opr tmp = new_pointer_register();
+ __ convert(Bytecodes::_i2l, index_op, tmp);
+ index_op = tmp;
+ }
+#endif
addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
#else
if (index_op->is_illegal() || log2_scale == 0) {
+#ifdef _LP64
+ if (!index_op->is_illegal() && index_op->type() == T_INT) {
+ LIR_Opr tmp = new_pointer_register();
+ __ convert(Bytecodes::_i2l, index_op, tmp);
+ index_op = tmp;
+ }
+#endif
addr = new LIR_Address(base_op, index_op, dst_type);
} else {
- LIR_Opr tmp = new_register(T_INT);
+ LIR_Opr tmp = new_pointer_register();
__ shift_left(index_op, log2_scale, tmp);
addr = new LIR_Address(base_op, tmp, dst_type);
}
@@ -1915,10 +1929,25 @@
LIR_Opr index_op = idx.result();
if (log2_scale != 0) {
// temporary fix (platform dependent code without shift on Intel would be better)
- index_op = new_register(T_INT);
- __ move(idx.result(), index_op);
+ index_op = new_pointer_register();
+#ifdef _LP64
+ if(idx.result()->type() == T_INT) {
+ __ convert(Bytecodes::_i2l, idx.result(), index_op);
+ } else {
+#endif
+ __ move(idx.result(), index_op);
+#ifdef _LP64
+ }
+#endif
__ shift_left(index_op, log2_scale, index_op);
}
+#ifdef _LP64
+ else if(!index_op->is_illegal() && index_op->type() == T_INT) {
+ LIR_Opr tmp = new_pointer_register();
+ __ convert(Bytecodes::_i2l, index_op, tmp);
+ index_op = tmp;
+ }
+#endif
LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
__ move(value.result(), addr);
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2464,6 +2464,10 @@
case T_LONG: // fall through
case T_DOUBLE: {
+#ifdef _LP64
+ 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) {
scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
@@ -2471,7 +2475,7 @@
scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
}
-
+#endif
return 2;
}
@@ -2503,17 +2507,18 @@
} else if (opr->is_single_cpu()) {
bool is_oop = opr->is_oop_register();
int cache_idx = opr->cpu_regnr() * 2 + (is_oop ? 1 : 0);
+ Location::Type int_loc_type = NOT_LP64(Location::normal) LP64_ONLY(Location::int_in_long);
ScopeValue* sv = _scope_value_cache.at(cache_idx);
if (sv == NULL) {
- Location::Type loc_type = is_oop ? Location::oop : Location::normal;
+ Location::Type loc_type = is_oop ? Location::oop : int_loc_type;
VMReg rname = frame_map()->regname(opr);
sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
_scope_value_cache.at_put(cache_idx, sv);
}
// check if cached value is correct
- DEBUG_ONLY(assert_equal(sv, new LocationValue(Location::new_reg_loc(is_oop ? Location::oop : Location::normal, frame_map()->regname(opr)))));
+ DEBUG_ONLY(assert_equal(sv, new LocationValue(Location::new_reg_loc(is_oop ? Location::oop : int_loc_type, frame_map()->regname(opr)))));
scope_values->append(sv);
return 1;
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -61,9 +61,11 @@
BCEscapeAnalyzer* _parent;
int _level;
+ public:
class ArgumentMap;
class StateInfo;
+ private:
// helper functions
bool is_argument(int i) { return i >= 0 && i < _arg_size; }
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -46,6 +46,9 @@
ciInstanceKlass* ciEnv::_Thread;
ciInstanceKlass* ciEnv::_OutOfMemoryError;
ciInstanceKlass* ciEnv::_String;
+ciInstanceKlass* ciEnv::_StringBuffer;
+ciInstanceKlass* ciEnv::_StringBuilder;
+ciInstanceKlass* ciEnv::_Integer;
ciSymbol* ciEnv::_unloaded_cisymbol = NULL;
ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL;
@@ -110,6 +113,8 @@
_ArrayIndexOutOfBoundsException_instance = NULL;
_ArrayStoreException_instance = NULL;
_ClassCastException_instance = NULL;
+ _the_null_string = NULL;
+ _the_min_jint_string = NULL;
}
ciEnv::ciEnv(Arena* arena) {
@@ -163,6 +168,8 @@
_ArrayIndexOutOfBoundsException_instance = NULL;
_ArrayStoreException_instance = NULL;
_ClassCastException_instance = NULL;
+ _the_null_string = NULL;
+ _the_min_jint_string = NULL;
}
ciEnv::~ciEnv() {
@@ -248,6 +255,22 @@
return _ClassCastException_instance;
}
+ciInstance* ciEnv::the_null_string() {
+ if (_the_null_string == NULL) {
+ VM_ENTRY_MARK;
+ _the_null_string = get_object(Universe::the_null_string())->as_instance();
+ }
+ return _the_null_string;
+}
+
+ciInstance* ciEnv::the_min_jint_string() {
+ if (_the_min_jint_string == NULL) {
+ VM_ENTRY_MARK;
+ _the_min_jint_string = get_object(Universe::the_min_jint_string())->as_instance();
+ }
+ return _the_min_jint_string;
+}
+
// ------------------------------------------------------------------
// ciEnv::get_method_from_handle
ciMethod* ciEnv::get_method_from_handle(jobject method) {
@@ -690,10 +713,8 @@
ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
// Get the method's name and signature.
- int nt_index = cpool->name_and_type_ref_index_at(index);
- int sig_index = cpool->signature_ref_index_at(nt_index);
symbolOop name_sym = cpool->name_ref_at(index);
- symbolOop sig_sym = cpool->symbol_at(sig_index);
+ symbolOop sig_sym = cpool->signature_ref_at(index);
if (holder_is_accessible) { // Our declared holder is loaded.
instanceKlass* lookup = declared_holder->get_instanceKlass();
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -82,6 +82,9 @@
static ciInstanceKlass* _Thread;
static ciInstanceKlass* _OutOfMemoryError;
static ciInstanceKlass* _String;
+ static ciInstanceKlass* _StringBuffer;
+ static ciInstanceKlass* _StringBuilder;
+ static ciInstanceKlass* _Integer;
static ciSymbol* _unloaded_cisymbol;
static ciInstanceKlass* _unloaded_ciinstance_klass;
@@ -97,6 +100,9 @@
ciInstance* _ArrayStoreException_instance;
ciInstance* _ClassCastException_instance;
+ ciInstance* _the_null_string; // The Java string "null"
+ ciInstance* _the_min_jint_string; // The Java string "-2147483648"
+
// Look up a klass by name from a particular class loader (the accessor's).
// If require_local, result must be defined in that class loader, or NULL.
// If !require_local, a result from remote class loader may be reported,
@@ -310,6 +316,15 @@
ciInstanceKlass* String_klass() {
return _String;
}
+ ciInstanceKlass* StringBuilder_klass() {
+ return _StringBuilder;
+ }
+ ciInstanceKlass* StringBuffer_klass() {
+ return _StringBuffer;
+ }
+ ciInstanceKlass* Integer_klass() {
+ return _Integer;
+ }
ciInstance* NullPointerException_instance() {
assert(_NullPointerException_instance != NULL, "initialization problem");
return _NullPointerException_instance;
@@ -324,6 +339,9 @@
ciInstance* ArrayStoreException_instance();
ciInstance* ClassCastException_instance();
+ ciInstance* the_null_string();
+ ciInstance* the_min_jint_string();
+
static ciSymbol* unloaded_cisymbol() {
return _unloaded_cisymbol;
}
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -341,6 +341,20 @@
}
// ------------------------------------------------------------------
+// ciInstanceKlass::get_field_by_name
+ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
+ VM_ENTRY_MARK;
+ instanceKlass* k = get_instanceKlass();
+ fieldDescriptor fd;
+ klassOop def = k->find_field(name->get_symbolOop(), signature->get_symbolOop(), is_static, &fd);
+ if (def == NULL) {
+ return NULL;
+ }
+ ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
+ return field;
+}
+
+// ------------------------------------------------------------------
// ciInstanceKlass::non_static_fields.
class NonStaticFieldFiller: public FieldClosure {
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -148,6 +148,7 @@
ciInstanceKlass* get_canonical_holder(int offset);
ciField* get_field_by_offset(int field_offset, bool is_static);
+ ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static);
GrowableArray<ciField*>* non_static_fields();
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -168,6 +168,15 @@
ciEnv::_String =
get(SystemDictionary::string_klass())
->as_instance_klass();
+ ciEnv::_StringBuffer =
+ get(SystemDictionary::stringBuffer_klass())
+ ->as_instance_klass();
+ ciEnv::_StringBuilder =
+ get(SystemDictionary::StringBuilder_klass())
+ ->as_instance_klass();
+ ciEnv::_Integer =
+ get(SystemDictionary::int_klass())
+ ->as_instance_klass();
for (int len = -1; len != _ci_objects->length(); ) {
len = _ci_objects->length();
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2511,23 +2511,12 @@
fac_ptr->nonstatic_byte_count -= 1;
(*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
word_sig_index);
- if (wordSize == jintSize) {
- fac_ptr->nonstatic_word_count += 1;
- } else {
- fac_ptr->nonstatic_double_count += 1;
- }
-
- FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i+4);
+ fac_ptr->nonstatic_word_count += 1;
+
+ FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset);
assert(atype == NONSTATIC_BYTE, "");
FieldAllocationType new_atype = NONSTATIC_WORD;
- if (wordSize > jintSize) {
- if (Universe::field_type_should_be_aligned(T_LONG)) {
- atype = NONSTATIC_ALIGNED_DOUBLE;
- } else {
- atype = NONSTATIC_DOUBLE;
- }
- }
- (*fields_ptr)->ushort_at_put(i+4, new_atype);
+ (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype);
found_vmentry = true;
break;
@@ -3085,7 +3074,7 @@
int len = fields->length();
for (int i = 0; i < len; i += instanceKlass::next_offset) {
int real_offset;
- FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i+4);
+ FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
switch (atype) {
case STATIC_OOP:
real_offset = next_static_oop_offset;
@@ -3173,8 +3162,8 @@
default:
ShouldNotReachHere();
}
- fields->short_at_put(i+4, extract_low_short_from_int(real_offset) );
- fields->short_at_put(i+5, extract_high_short_from_int(real_offset) );
+ fields->short_at_put(i + instanceKlass::low_offset, extract_low_short_from_int(real_offset));
+ fields->short_at_put(i + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
}
// Size of instances
@@ -3766,8 +3755,9 @@
}
bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
- u2 max_version = JDK_Version::is_gte_jdk17x_version() ?
- JAVA_MAX_SUPPORTED_VERSION : JAVA_6_VERSION;
+ u2 max_version =
+ JDK_Version::is_gte_jdk17x_version() ? JAVA_MAX_SUPPORTED_VERSION :
+ (JDK_Version::is_gte_jdk16x_version() ? JAVA_6_VERSION : JAVA_1_5_VERSION);
return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
(major <= max_version) &&
((major != max_version) ||
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1124,8 +1124,7 @@
if (_dirty && _methods != NULL) {
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
- bs->write_ref_array(MemRegion((HeapWord*)_methods->base(),
- _methods->array_size()));
+ bs->write_ref_array((HeapWord*)_methods->base(), _methods->length());
_dirty = false;
}
}
@@ -2430,15 +2429,15 @@
}
-// Support for sun_dyn_CallSiteImpl
-
-int sun_dyn_CallSiteImpl::_type_offset;
-int sun_dyn_CallSiteImpl::_target_offset;
-int sun_dyn_CallSiteImpl::_vmmethod_offset;
-
-void sun_dyn_CallSiteImpl::compute_offsets() {
+// Support for java_dyn_CallSite
+
+int java_dyn_CallSite::_type_offset;
+int java_dyn_CallSite::_target_offset;
+int java_dyn_CallSite::_vmmethod_offset;
+
+void java_dyn_CallSite::compute_offsets() {
if (!EnableInvokeDynamic) return;
- klassOop k = SystemDictionary::CallSiteImpl_klass();
+ klassOop k = SystemDictionary::CallSite_klass();
if (k != NULL) {
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), true);
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_dyn_MethodHandle_signature(), true);
@@ -2446,23 +2445,23 @@
}
}
-oop sun_dyn_CallSiteImpl::type(oop site) {
+oop java_dyn_CallSite::type(oop site) {
return site->obj_field(_type_offset);
}
-oop sun_dyn_CallSiteImpl::target(oop site) {
+oop java_dyn_CallSite::target(oop site) {
return site->obj_field(_target_offset);
}
-void sun_dyn_CallSiteImpl::set_target(oop site, oop target) {
+void java_dyn_CallSite::set_target(oop site, oop target) {
site->obj_field_put(_target_offset, target);
}
-oop sun_dyn_CallSiteImpl::vmmethod(oop site) {
+oop java_dyn_CallSite::vmmethod(oop site) {
return site->obj_field(_vmmethod_offset);
}
-void sun_dyn_CallSiteImpl::set_vmmethod(oop site, oop ref) {
+void java_dyn_CallSite::set_vmmethod(oop site, oop ref) {
site->obj_field_put(_vmmethod_offset, ref);
}
@@ -2811,7 +2810,7 @@
java_dyn_MethodTypeForm::compute_offsets();
}
if (EnableInvokeDynamic) {
- sun_dyn_CallSiteImpl::compute_offsets();
+ java_dyn_CallSite::compute_offsets();
}
java_security_AccessControlContext::compute_offsets();
// Initialize reflection classes. The layouts of these classes
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -1061,9 +1061,9 @@
};
-// Interface to sun.dyn.CallSiteImpl objects
+// Interface to java.dyn.CallSite objects
-class sun_dyn_CallSiteImpl: AllStatic {
+class java_dyn_CallSite: AllStatic {
friend class JavaClasses;
private:
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -99,6 +99,15 @@
return java_lang_Class::parallelCapable(class_loader());
}
// ----------------------------------------------------------------------------
+// ParallelDefineClass flag does not apply to bootclass loader
+bool SystemDictionary::is_parallelDefine(Handle class_loader) {
+ if (class_loader.is_null()) return false;
+ if (AllowParallelDefineClass && java_lang_Class::parallelCapable(class_loader())) {
+ return true;
+ }
+ return false;
+}
+// ----------------------------------------------------------------------------
// Resolving of classes
// Forwards to resolve_or_null
@@ -724,13 +733,13 @@
// Do actual loading
k = load_instance_class(name, class_loader, THREAD);
- // For UnsyncloadClass and AllowParallelDefineClass only:
+ // For UnsyncloadClass only
// If they got a linkageError, check if a parallel class load succeeded.
// If it did, then for bytecode resolution the specification requires
// that we return the same result we did for the other thread, i.e. the
// successfully loaded instanceKlass
// Should not get here for classloaders that support parallelism
- // with the new cleaner mechanism
+ // with the new cleaner mechanism, even with AllowParallelDefineClass
// Bootstrap goes through here to allow for an extra guarantee check
if (UnsyncloadClass || (class_loader.is_null())) {
if (k.is_null() && HAS_PENDING_EXCEPTION
@@ -1483,14 +1492,17 @@
}
// Support parallel classloading
-// Initial implementation for bootstrap classloader
-// For custom class loaders that support parallel classloading,
+// All parallel class loaders, including bootstrap classloader
+// lock a placeholder entry for this class/class_loader pair
+// to allow parallel defines of different classes for this class loader
// With AllowParallelDefine flag==true, in case they do not synchronize around
// FindLoadedClass/DefineClass, calls, we check for parallel
// loading for them, wait if a defineClass is in progress
// and return the initial requestor's results
+// This flag does not apply to the bootstrap classloader.
// With AllowParallelDefine flag==false, call through to define_instance_class
// which will throw LinkageError: duplicate class definition.
+// False is the requested default.
// For better performance, the class loaders should synchronize
// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they
// potentially waste time reading and parsing the bytestream.
@@ -1511,9 +1523,11 @@
{
MutexLocker mu(SystemDictionary_lock, THREAD);
// First check if class already defined
- klassOop check = find_class(d_index, d_hash, name_h, class_loader);
- if (check != NULL) {
- return(instanceKlassHandle(THREAD, check));
+ if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
+ klassOop check = find_class(d_index, d_hash, name_h, class_loader);
+ if (check != NULL) {
+ return(instanceKlassHandle(THREAD, check));
+ }
}
// Acquire define token for this class/classloader
@@ -1529,7 +1543,7 @@
// Only special cases allow parallel defines and can use other thread's results
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
- if ((UnsyncloadClass || AllowParallelDefineClass) && (probe->instanceKlass() != NULL)) {
+ if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instanceKlass() != NULL)) {
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD);
SystemDictionary_lock->notify_all();
@@ -1973,7 +1987,7 @@
WKID indy_group_end = WK_KLASS_ENUM_NAME(Dynamic_klass);
initialize_wk_klasses_until(indy_group_start, scan, CHECK);
if (EnableInvokeDynamic) {
- initialize_wk_klasses_through(indy_group_start, scan, CHECK);
+ initialize_wk_klasses_through(indy_group_end, scan, CHECK);
}
if (_well_known_klasses[indy_group_start] == NULL) {
// Skip the rest of the dynamic typing classes, if Linkage is not loaded.
@@ -2404,7 +2418,7 @@
methodHandle mh_invdyn,
TRAPS) {
Handle empty;
- // call sun.dyn.CallSiteImpl::makeSite(caller, name, mtype, cmid, cbci)
+ // call java.dyn.CallSite::makeSite(caller, name, mtype, cmid, cbci)
oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle!
JavaCallArguments args(Handle(THREAD, caller->java_mirror()));
args.push_oop(name_str_oop);
@@ -2413,17 +2427,19 @@
args.push_int(caller_bci);
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
- SystemDictionary::CallSiteImpl_klass(),
+ SystemDictionary::CallSite_klass(),
vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(),
&args, CHECK_(empty));
oop call_site_oop = (oop) result.get_jobject();
assert(call_site_oop->is_oop()
- /*&& sun_dyn_CallSiteImpl::is_instance(call_site_oop)*/, "must be sane");
- sun_dyn_CallSiteImpl::set_vmmethod(call_site_oop, mh_invdyn());
+ /*&& java_dyn_CallSite::is_instance(call_site_oop)*/, "must be sane");
+ java_dyn_CallSite::set_vmmethod(call_site_oop, mh_invdyn());
if (TraceMethodHandles) {
+#ifndef PRODUCT
tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
call_site_oop->print();
tty->cr();
+#endif //PRODUCT
}
return call_site_oop;
}
@@ -2436,9 +2452,17 @@
instanceKlassHandle ik(THREAD, caller());
- if (ik->bootstrap_method() != NULL) {
- return Handle(THREAD, ik->bootstrap_method());
+ oop boot_method_oop = ik->bootstrap_method();
+ if (boot_method_oop != NULL) {
+ if (TraceMethodHandles) {
+ tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop);
+ }
+ NOT_PRODUCT(if (!boot_method_oop->is_oop()) { tty->print_cr("*** boot MH of "PTR_FORMAT" = "PTR_FORMAT, ik(), boot_method_oop); ik()->print(); });
+ assert(boot_method_oop->is_oop()
+ && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
+ return Handle(THREAD, boot_method_oop);
}
+ boot_method_oop = NULL; // GC safety
// call java.dyn.Linkage::findBootstrapMethod(caller, sbk)
JavaCallArguments args(Handle(THREAD, ik->java_mirror()));
@@ -2452,9 +2476,18 @@
vmSymbols::findBootstrapMethod_name(),
vmSymbols::findBootstrapMethod_signature(),
&args, CHECK_(empty));
- oop boot_method_oop = (oop) result.get_jobject();
+ boot_method_oop = (oop) result.get_jobject();
if (boot_method_oop != NULL) {
+ if (TraceMethodHandles) {
+#ifndef PRODUCT
+ tty->print_cr("--------");
+ tty->print_cr("bootstrap method for "PTR_FORMAT" computed as "PTR_FORMAT":", ik(), boot_method_oop);
+ ik()->print();
+ boot_method_oop->print();
+ tty->print_cr("========");
+#endif //PRODUCT
+ }
assert(boot_method_oop->is_oop()
&& java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
// probably no race conditions, but let's be careful:
@@ -2463,6 +2496,14 @@
else
boot_method_oop = ik->bootstrap_method();
} else {
+ if (TraceMethodHandles) {
+#ifndef PRODUCT
+ tty->print_cr("--------");
+ tty->print_cr("bootstrap method for "PTR_FORMAT" computed as NULL:", ik());
+ ik()->print();
+ tty->print_cr("========");
+#endif //PRODUCT
+ }
boot_method_oop = ik->bootstrap_method();
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -144,13 +144,13 @@
template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
template(Linkage_klass, java_dyn_Linkage, Opt) \
template(CallSite_klass, java_dyn_CallSite, Opt) \
- template(CallSiteImpl_klass, sun_dyn_CallSiteImpl, Opt) \
template(Dynamic_klass, java_dyn_Dynamic, Opt) \
/* Note: MethodHandle must be first, and Dynamic last in group */ \
\
template(vector_klass, java_util_Vector, Pre) \
template(hashtable_klass, java_util_Hashtable, Pre) \
template(stringBuffer_klass, java_lang_StringBuffer, Pre) \
+ template(StringBuilder_klass, java_lang_StringBuilder, Pre) \
\
/* It's NULL in non-1.4 JDKs. */ \
template(stackTraceElement_klass, java_lang_StackTraceElement, Opt) \
@@ -578,6 +578,7 @@
static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
static void check_loader_lock_contention(Handle loader_lock, TRAPS);
static bool is_parallelCapable(Handle class_loader);
+ static bool is_parallelDefine(Handle class_loader);
static klassOop find_shared_class(symbolHandle class_name);
--- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1903,17 +1903,8 @@
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
// Get method name and signature
- symbolHandle method_name;
- symbolHandle method_sig;
- if (opcode == Bytecodes::_invokedynamic) {
- int name_index = cp->name_ref_index_at(index);
- int sig_index = cp->signature_ref_index_at(index);
- method_name = symbolHandle(THREAD, cp->symbol_at(name_index));
- method_sig = symbolHandle(THREAD, cp->symbol_at(sig_index));
- } else {
- method_name = symbolHandle(THREAD, cp->name_ref_at(index));
- method_sig = symbolHandle(THREAD, cp->signature_ref_at(index));
- }
+ symbolHandle method_name(THREAD, cp->name_ref_at(index));
+ symbolHandle method_sig(THREAD, cp->signature_ref_at(index));
if (!SignatureVerifier::is_valid_method_signature(method_sig)) {
class_format_error(
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -303,6 +303,11 @@
const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
return (flags & (req | neg)) == req;
}
+inline bool match_F_Y(jshort flags) {
+ const int req = JVM_ACC_SYNCHRONIZED;
+ const int neg = JVM_ACC_STATIC;
+ return (flags & (req | neg)) == req;
+}
inline bool match_F_RN(jshort flags) {
const int req = JVM_ACC_NATIVE;
const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
@@ -361,6 +366,7 @@
const char* sname = vmSymbols::name_for(signature_for(id));
const char* fname = "";
switch (flags_for(id)) {
+ case F_Y: fname = "synchronized "; break;
case F_RN: fname = "native "; break;
case F_SN: fname = "native static "; break;
case F_S: fname = "static "; break;
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -84,6 +84,7 @@
template(java_lang_reflect_Field, "java/lang/reflect/Field") \
template(java_lang_reflect_Array, "java/lang/reflect/Array") \
template(java_lang_StringBuffer, "java/lang/StringBuffer") \
+ template(java_lang_StringBuilder, "java/lang/StringBuilder") \
template(java_lang_CharSequence, "java/lang/CharSequence") \
template(java_security_AccessControlContext, "java/security/AccessControlContext") \
template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \
@@ -104,6 +105,7 @@
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
+ template(setBootClassLoaderHook_name, "setBootClassLoaderHook") \
\
/* class file format tags */ \
template(tag_source_file, "SourceFile") \
@@ -233,10 +235,9 @@
template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
- template(sun_dyn_CallSiteImpl, "sun/dyn/CallSiteImpl") \
template(makeImpl_name, "makeImpl") /*MethodType::makeImpl*/ \
template(makeImpl_signature, "(Ljava/lang/Class;[Ljava/lang/Class;ZZ)Ljava/dyn/MethodType;") \
- template(makeSite_name, "makeSite") /*CallSiteImpl::makeImpl*/ \
+ template(makeSite_name, "makeSite") /*CallSite::makeSite*/ \
template(makeSite_signature, "(Ljava/lang/Class;Ljava/lang/String;Ljava/dyn/MethodType;II)Ljava/dyn/CallSite;") \
template(findBootstrapMethod_name, "findBootstrapMethod") \
template(findBootstrapMethod_signature, "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/dyn/MethodHandle;") \
@@ -335,6 +336,7 @@
template(ptypes_name, "ptypes") \
template(form_name, "form") \
template(erasedType_name, "erasedType") \
+ template(append_name, "append") \
\
/* non-intrinsic name/signature pairs: */ \
template(register_method_name, "register") \
@@ -416,6 +418,13 @@
template(string_signature, "Ljava/lang/String;") \
template(reference_signature, "Ljava/lang/ref/Reference;") \
template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \
+ template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \
+ template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \
+ template(char_StringBuilder_signature, "(C)Ljava/lang/StringBuilder;") \
+ template(String_StringBuffer_signature, "(Ljava/lang/String;)Ljava/lang/StringBuffer;") \
+ template(int_StringBuffer_signature, "(I)Ljava/lang/StringBuffer;") \
+ template(char_StringBuffer_signature, "(C)Ljava/lang/StringBuffer;") \
+ template(int_String_signature, "(I)Ljava/lang/String;") \
/* signature symbols needed by intrinsics */ \
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \
\
@@ -815,10 +824,34 @@
/*the compiler does have special inlining code for these; bytecode inline is just fine */ \
\
do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
- \
- do_intrinsic(_Object_init, java_lang_Object, object_initializer_name, void_method_signature, F_R) \
- /* (symbol object_initializer_name defined above) */ \
- \
+ \
+ do_intrinsic(_StringBuilder_void, java_lang_StringBuilder, object_initializer_name, void_method_signature, F_R) \
+ do_intrinsic(_StringBuilder_int, java_lang_StringBuilder, object_initializer_name, int_void_signature, F_R) \
+ do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature, F_R) \
+ \
+ do_intrinsic(_StringBuilder_append_char, java_lang_StringBuilder, append_name, char_StringBuilder_signature, F_R) \
+ do_intrinsic(_StringBuilder_append_int, java_lang_StringBuilder, append_name, int_StringBuilder_signature, F_R) \
+ do_intrinsic(_StringBuilder_append_String, java_lang_StringBuilder, append_name, String_StringBuilder_signature, F_R) \
+ \
+ do_intrinsic(_StringBuilder_toString, java_lang_StringBuilder, toString_name, void_string_signature, F_R) \
+ \
+ do_intrinsic(_StringBuffer_void, java_lang_StringBuffer, object_initializer_name, void_method_signature, F_R) \
+ do_intrinsic(_StringBuffer_int, java_lang_StringBuffer, object_initializer_name, int_void_signature, F_R) \
+ do_intrinsic(_StringBuffer_String, java_lang_StringBuffer, object_initializer_name, string_void_signature, F_R) \
+ \
+ do_intrinsic(_StringBuffer_append_char, java_lang_StringBuffer, append_name, char_StringBuffer_signature, F_Y) \
+ do_intrinsic(_StringBuffer_append_int, java_lang_StringBuffer, append_name, int_StringBuffer_signature, F_Y) \
+ do_intrinsic(_StringBuffer_append_String, java_lang_StringBuffer, append_name, String_StringBuffer_signature, F_Y) \
+ \
+ do_intrinsic(_StringBuffer_toString, java_lang_StringBuffer, toString_name, void_string_signature, F_Y) \
+ \
+ do_intrinsic(_Integer_toString, java_lang_Integer, toString_name, int_String_signature, F_S) \
+ \
+ do_intrinsic(_String_String, java_lang_String, object_initializer_name, string_void_signature, F_R) \
+ \
+ do_intrinsic(_Object_init, java_lang_Object, object_initializer_name, void_method_signature, F_R) \
+ /* (symbol object_initializer_name defined above) */ \
+ \
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
/* (symbols invoke_name and invoke_signature defined above) */ \
\
@@ -946,11 +979,12 @@
enum Flags {
// AccessFlags syndromes relevant to intrinsics.
F_none = 0,
- F_R, // !static !synchronized (R="regular")
- F_S, // static !synchronized
- F_RN, // !static native !synchronized
- F_SN, // static native !synchronized
- F_RNY // !static native synchronized
+ F_R, // !static ?native !synchronized (R="regular")
+ F_S, // static ?native !synchronized
+ F_Y, // !static ?native synchronized
+ F_RN, // !static native !synchronized
+ F_SN, // static native !synchronized
+ F_RNY // !static native synchronized
};
public:
--- a/hotspot/src/share/vm/code/dependencies.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/code/dependencies.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1528,19 +1528,23 @@
int nsup = 0, nint = 0;
for (ContextStream str(*this); str.next(); ) {
klassOop k = str.klass();
- switch (str._change_type) {
+ switch (str.change_type()) {
case Change_new_type:
tty->print_cr(" dependee = %s", instanceKlass::cast(k)->external_name());
break;
case Change_new_sub:
- if (!WizardMode)
- ++nsup;
- else tty->print_cr(" context super = %s", instanceKlass::cast(k)->external_name());
+ if (!WizardMode) {
+ ++nsup;
+ } else {
+ tty->print_cr(" context super = %s", instanceKlass::cast(k)->external_name());
+ }
break;
case Change_new_impl:
- if (!WizardMode)
- ++nint;
- else tty->print_cr(" context interface = %s", instanceKlass::cast(k)->external_name());
+ if (!WizardMode) {
+ ++nint;
+ } else {
+ tty->print_cr(" context interface = %s", instanceKlass::cast(k)->external_name());
+ }
break;
}
}
--- a/hotspot/src/share/vm/code/dependencies.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/code/dependencies.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -470,7 +470,7 @@
// super types can be context types for a relevant dependency, which the
// new type could invalidate.
class DepChange : public StackObj {
- private:
+ public:
enum ChangeType {
NO_CHANGE = 0, // an uninvolved klass
Change_new_type, // a newly loaded type
@@ -480,6 +480,7 @@
Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream
};
+ private:
// each change set is rooted in exactly one new type (at present):
KlassHandle _new_type;
@@ -510,15 +511,15 @@
// }
class ContextStream : public StackObj {
private:
- DepChange& _changes;
+ DepChange& _changes;
friend class DepChange;
// iteration variables:
- ChangeType _change_type;
- klassOop _klass;
- objArrayOop _ti_base; // i.e., transitive_interfaces
- int _ti_index;
- int _ti_limit;
+ ChangeType _change_type;
+ klassOop _klass;
+ objArrayOop _ti_base; // i.e., transitive_interfaces
+ int _ti_index;
+ int _ti_limit;
// start at the beginning:
void start() {
@@ -530,11 +531,11 @@
_ti_limit = 0;
}
+ public:
ContextStream(DepChange& changes)
: _changes(changes)
{ start(); }
- public:
ContextStream(DepChange& changes, No_Safepoint_Verifier& nsv)
: _changes(changes)
// the nsv argument makes it safe to hold oops like _klass
@@ -542,6 +543,7 @@
bool next();
+ ChangeType change_type() { return _change_type; }
klassOop klass() { return _klass; }
};
friend class DepChange::ContextStream;
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -414,9 +414,8 @@
}
const char* nmethod::compile_kind() const {
- if (method() == NULL) return "unloaded";
- if (is_native_method()) return "c2n";
if (is_osr_method()) return "osr";
+ if (method() != NULL && is_native_method()) return "c2n";
return NULL;
}
@@ -1127,6 +1126,9 @@
}
flags.state = unloaded;
+ // Log the unloading.
+ log_state_change();
+
// The methodOop is gone at this point
assert(_method == NULL, "Tautology");
@@ -1137,8 +1139,6 @@
void nmethod::invalidate_osr_method() {
assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
- if (_entry_bci != InvalidOSREntryBci)
- inc_decompile_count();
// Remove from list of active nmethods
if (method() != NULL)
instanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
@@ -1146,59 +1146,63 @@
_entry_bci = InvalidOSREntryBci;
}
-void nmethod::log_state_change(int state) const {
+void nmethod::log_state_change() const {
if (LogCompilation) {
if (xtty != NULL) {
ttyLocker ttyl; // keep the following output all in one block
- xtty->begin_elem("make_not_entrant %sthread='" UINTX_FORMAT "'",
- (state == zombie ? "zombie='1' " : ""),
- os::current_thread_id());
+ if (flags.state == unloaded) {
+ xtty->begin_elem("make_unloaded thread='" UINTX_FORMAT "'",
+ os::current_thread_id());
+ } else {
+ xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'%s",
+ os::current_thread_id(),
+ (flags.state == zombie ? " zombie='1'" : ""));
+ }
log_identity(xtty);
xtty->stamp();
xtty->end_elem();
}
}
- if (PrintCompilation) {
- print_on(tty, state == zombie ? "made zombie " : "made not entrant ");
+ if (PrintCompilation && flags.state != unloaded) {
+ print_on(tty, flags.state == zombie ? "made zombie " : "made not entrant ");
tty->cr();
}
}
// Common functionality for both make_not_entrant and make_zombie
-void nmethod::make_not_entrant_or_zombie(int state) {
+bool nmethod::make_not_entrant_or_zombie(int state) {
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
- // Code for an on-stack-replacement nmethod is removed when a class gets unloaded.
- // They never become zombie/non-entrant, so the nmethod sweeper will never remove
- // them. Instead the entry_bci is set to InvalidOSREntryBci, so the osr nmethod
- // will never be used anymore. That the nmethods only gets removed when class unloading
- // happens, make life much simpler, since the nmethods are not just going to disappear
- // out of the blue.
- if (is_osr_method()) {
- if (osr_entry_bci() != InvalidOSREntryBci) {
- // only log this once
- log_state_change(state);
- }
- invalidate_osr_method();
- return;
+ // If the method is already zombie there is nothing to do
+ if (is_zombie()) {
+ return false;
}
- // If the method is already zombie or set to the state we want, nothing to do
- if (is_zombie() || (state == not_entrant && is_not_entrant())) {
- return;
- }
-
- log_state_change(state);
-
// Make sure the nmethod is not flushed in case of a safepoint in code below.
nmethodLocker nml(this);
{
+ // invalidate osr nmethod before acquiring the patching lock since
+ // they both acquire leaf locks and we don't want a deadlock.
+ // This logic is equivalent to the logic below for patching the
+ // verified entry point of regular methods.
+ if (is_osr_method()) {
+ // this effectively makes the osr nmethod not entrant
+ invalidate_osr_method();
+ }
+
// Enter critical section. Does not block for safepoint.
MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
+
+ if (flags.state == state) {
+ // another thread already performed this transition so nothing
+ // to do, but return false to indicate this.
+ return false;
+ }
+
// The caller can be calling the method statically or through an inline
// cache call.
- if (!is_not_entrant()) {
+ if (!is_osr_method() && !is_not_entrant()) {
NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
SharedRuntime::get_handle_wrong_method_stub());
assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
@@ -1217,6 +1221,10 @@
// Change state
flags.state = state;
+
+ // Log the transition once
+ log_state_change();
+
} // leave critical region under Patching_lock
if (state == not_entrant) {
@@ -1240,7 +1248,6 @@
// It's a true state change, so mark the method as decompiled.
inc_decompile_count();
-
// zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
// and it hasn't already been reported for this nmethod then report it now.
// (the event may have been reported earilier if the GC marked it for unloading).
@@ -1268,7 +1275,7 @@
// Check whether method got unloaded at a safepoint before this,
// if so we can skip the flushing steps below
- if (method() == NULL) return;
+ if (method() == NULL) return true;
// Remove nmethod from method.
// We need to check if both the _code and _from_compiled_code_entry_point
@@ -1282,6 +1289,8 @@
HandleMark hm;
method()->clear_code();
}
+
+ return true;
}
--- a/hotspot/src/share/vm/code/nmethod.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/code/nmethod.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -252,7 +252,9 @@
void* operator new(size_t size, int nmethod_size);
const char* reloc_string_for(u_char* begin, u_char* end);
- void make_not_entrant_or_zombie(int state);
+ // Returns true if this thread changed the state of the nmethod or
+ // false if another thread performed the transition.
+ bool make_not_entrant_or_zombie(int state);
void inc_decompile_count();
// used to check that writes to nmFlags are done consistently.
@@ -375,10 +377,12 @@
bool is_zombie() const { return flags.state == zombie; }
bool is_unloaded() const { return flags.state == unloaded; }
- // Make the nmethod non entrant. The nmethod will continue to be alive.
- // It is used when an uncommon trap happens.
- void make_not_entrant() { make_not_entrant_or_zombie(not_entrant); }
- void make_zombie() { make_not_entrant_or_zombie(zombie); }
+ // Make the nmethod non entrant. The nmethod will continue to be
+ // alive. It is used when an uncommon trap happens. Returns true
+ // if this thread changed the state of the nmethod or false if
+ // another thread performed the transition.
+ bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
+ bool make_zombie() { return make_not_entrant_or_zombie(zombie); }
// used by jvmti to track if the unload event has been reported
bool unload_reported() { return _unload_reported; }
@@ -563,7 +567,7 @@
// Logging
void log_identity(xmlStream* log) const;
void log_new_nmethod() const;
- void log_state_change(int state) const;
+ void log_state_change() const;
// Prints a comment for one native instruction (reloc info, pc desc)
void print_code_comment_on(outputStream* st, int column, address begin, address end);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -709,7 +709,8 @@
// Support for parallelizing survivor space rescan
if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
- size_t max_plab_samples = MaxNewSize/((SurvivorRatio+2)*MinTLABSize);
+ size_t max_plab_samples = cp->max_gen0_size()/
+ ((SurvivorRatio+2)*MinTLABSize);
_survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
_survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
_cursor = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -351,9 +351,16 @@
CollectionSetChooser::printSortedHeapRegions() {
gclog_or_tty->print_cr("Printing %d Heap Regions sorted by amount of known garbage",
_numMarkedRegions);
+
+ DEBUG_ONLY(int marked_count = 0;)
for (int i = 0; i < _markedRegions.length(); i++) {
- printHeapRegion(_markedRegions.at(i));
+ HeapRegion* r = _markedRegions.at(i);
+ if (r != NULL) {
+ printHeapRegion(r);
+ DEBUG_ONLY(marked_count++;)
+ }
}
+ assert(marked_count == _numMarkedRegions, "must be");
gclog_or_tty->print_cr("Done sorted heap region print");
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -42,28 +42,49 @@
_n_periods(0),
_threads(NULL), _n_threads(0)
{
- if (G1ConcRefine) {
- _n_threads = (int)thread_num();
- if (_n_threads > 0) {
- _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
- int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
- ConcurrentG1RefineThread *next = NULL;
- for (int i = _n_threads - 1; i >= 0; i--) {
- ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
- assert(t != NULL, "Conc refine should have been created");
- assert(t->cg1r() == this, "Conc refine thread should refer to this");
- _threads[i] = t;
- next = t;
- }
- }
+
+ // Ergomonically select initial concurrent refinement parameters
+ if (FLAG_IS_DEFAULT(G1ConcRefineGreenZone)) {
+ FLAG_SET_DEFAULT(G1ConcRefineGreenZone, MAX2<int>(ParallelGCThreads, 1));
+ }
+ set_green_zone(G1ConcRefineGreenZone);
+
+ if (FLAG_IS_DEFAULT(G1ConcRefineYellowZone)) {
+ FLAG_SET_DEFAULT(G1ConcRefineYellowZone, green_zone() * 3);
+ }
+ set_yellow_zone(MAX2<int>(G1ConcRefineYellowZone, green_zone()));
+
+ if (FLAG_IS_DEFAULT(G1ConcRefineRedZone)) {
+ FLAG_SET_DEFAULT(G1ConcRefineRedZone, yellow_zone() * 2);
+ }
+ set_red_zone(MAX2<int>(G1ConcRefineRedZone, yellow_zone()));
+ _n_worker_threads = thread_num();
+ // We need one extra thread to do the young gen rset size sampling.
+ _n_threads = _n_worker_threads + 1;
+ reset_threshold_step();
+
+ _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
+ int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
+ ConcurrentG1RefineThread *next = NULL;
+ for (int i = _n_threads - 1; i >= 0; i--) {
+ ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
+ assert(t != NULL, "Conc refine should have been created");
+ assert(t->cg1r() == this, "Conc refine thread should refer to this");
+ _threads[i] = t;
+ next = t;
}
}
-size_t ConcurrentG1Refine::thread_num() {
- if (G1ConcRefine) {
- return (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
+void ConcurrentG1Refine::reset_threshold_step() {
+ if (FLAG_IS_DEFAULT(G1ConcRefineThresholdStep)) {
+ _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
+ } else {
+ _thread_threshold_step = G1ConcRefineThresholdStep;
}
- return 0;
+}
+
+int ConcurrentG1Refine::thread_num() {
+ return MAX2<int>((G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads, 1);
}
void ConcurrentG1Refine::init() {
@@ -123,6 +144,15 @@
}
}
+void ConcurrentG1Refine::reinitialize_threads() {
+ reset_threshold_step();
+ if (_threads != NULL) {
+ for (int i = 0; i < _n_threads; i++) {
+ _threads[i]->initialize();
+ }
+ }
+}
+
ConcurrentG1Refine::~ConcurrentG1Refine() {
if (G1ConcRSLogCacheSize > 0) {
assert(_card_counts != NULL, "Logic");
@@ -384,4 +414,3 @@
st->cr();
}
}
-
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -29,6 +29,31 @@
class ConcurrentG1Refine: public CHeapObj {
ConcurrentG1RefineThread** _threads;
int _n_threads;
+ int _n_worker_threads;
+ /*
+ * The value of the update buffer queue length falls into one of 3 zones:
+ * green, yellow, red. If the value is in [0, green) nothing is
+ * done, the buffers are left unprocessed to enable the caching effect of the
+ * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
+ * threads are gradually activated. In [yellow, red) all threads are
+ * running. If the length becomes red (max queue length) the mutators start
+ * processing the buffers.
+ *
+ * There are some interesting cases (with G1AdaptiveConcRefine turned off):
+ * 1) green = yellow = red = 0. In this case the mutator will process all
+ * buffers. Except for those that are created by the deferred updates
+ * machinery during a collection.
+ * 2) green = 0. Means no caching. Can be a good way to minimize the
+ * amount of time spent updating rsets during a collection.
+ */
+ int _green_zone;
+ int _yellow_zone;
+ int _red_zone;
+
+ int _thread_threshold_step;
+
+ // Reset the threshold step value based of the current zone boundaries.
+ void reset_threshold_step();
// The cache for card refinement.
bool _use_cache;
@@ -147,6 +172,8 @@
void init(); // Accomplish some initialization that has to wait.
void stop();
+ void reinitialize_threads();
+
// Iterate over the conc refine threads
void threads_do(ThreadClosure *tc);
@@ -178,7 +205,20 @@
void clear_and_record_card_counts();
- static size_t thread_num();
+ static int thread_num();
void print_worker_threads_on(outputStream* st) const;
+
+ void set_green_zone(int x) { _green_zone = x; }
+ void set_yellow_zone(int x) { _yellow_zone = x; }
+ void set_red_zone(int x) { _red_zone = x; }
+
+ int green_zone() const { return _green_zone; }
+ int yellow_zone() const { return _yellow_zone; }
+ int red_zone() const { return _red_zone; }
+
+ int total_thread_num() const { return _n_threads; }
+ int worker_thread_num() const { return _n_worker_threads; }
+
+ int thread_threshold_step() const { return _thread_threshold_step; }
};
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -25,10 +25,6 @@
#include "incls/_precompiled.incl"
#include "incls/_concurrentG1RefineThread.cpp.incl"
-// ======= Concurrent Mark Thread ========
-
-// The CM thread is created when the G1 garbage collector is used
-
ConcurrentG1RefineThread::
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
int worker_id_offset, int worker_id) :
@@ -37,19 +33,42 @@
_worker_id(worker_id),
_active(false),
_next(next),
+ _monitor(NULL),
_cg1r(cg1r),
- _vtime_accum(0.0),
- _interval_ms(5.0)
+ _vtime_accum(0.0)
{
+
+ // Each thread has its own monitor. The i-th thread is responsible for signalling
+ // to thread i+1 if the number of buffers in the queue exceeds a threashold for this
+ // thread. Monitors are also used to wake up the threads during termination.
+ // The 0th worker in notified by mutator threads and has a special monitor.
+ // The last worker is used for young gen rset size sampling.
+ if (worker_id > 0) {
+ _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true);
+ } else {
+ _monitor = DirtyCardQ_CBL_mon;
+ }
+ initialize();
create_and_start();
}
+void ConcurrentG1RefineThread::initialize() {
+ if (_worker_id < cg1r()->worker_thread_num()) {
+ // Current thread activation threshold
+ _threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
+ cg1r()->yellow_zone());
+ // A thread deactivates once the number of buffer reached a deactivation threshold
+ _deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
+ } else {
+ set_active(true);
+ }
+}
+
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1p = g1h->g1_policy();
if (g1p->adaptive_young_list_length()) {
int regions_visited = 0;
-
g1h->young_list_rs_length_sampling_init();
while (g1h->young_list_rs_length_sampling_more()) {
g1h->young_list_rs_length_sampling_next();
@@ -70,99 +89,121 @@
}
}
-void ConcurrentG1RefineThread::run() {
- initialize_in_thread();
+void ConcurrentG1RefineThread::run_young_rs_sampling() {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
_vtime_start = os::elapsedVTime();
- wait_for_universe_init();
+ while(!_should_terminate) {
+ _sts.join();
+ sample_young_list_rs_lengths();
+ _sts.leave();
- while (!_should_terminate) {
- DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
- // Wait for completed log buffers to exist.
- {
- MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
- while (((_worker_id == 0 && !dcqs.process_completed_buffers()) ||
- (_worker_id > 0 && !is_active())) &&
- !_should_terminate) {
- DirtyCardQ_CBL_mon->wait(Mutex::_no_safepoint_check_flag);
- }
- }
-
- if (_should_terminate) {
- return;
+ if (os::supports_vtime()) {
+ _vtime_accum = (os::elapsedVTime() - _vtime_start);
+ } else {
+ _vtime_accum = 0.0;
}
- // Now we take them off (this doesn't hold locks while it applies
- // closures.) (If we did a full collection, then we'll do a full
- // traversal.
- _sts.join();
- int n_logs = 0;
- int lower_limit = 0;
- double start_vtime_sec; // only used when G1SmoothConcRefine is on
- int prev_buffer_num; // only used when G1SmoothConcRefine is on
- // This thread activation threshold
- int threshold = G1UpdateBufferQueueProcessingThreshold * _worker_id;
- // Next thread activation threshold
- int next_threshold = threshold + G1UpdateBufferQueueProcessingThreshold;
- int deactivation_threshold = MAX2<int>(threshold - G1UpdateBufferQueueProcessingThreshold / 2, 0);
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ if (_should_terminate) {
+ break;
+ }
+ _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefineServiceInterval);
+ }
+}
- if (G1SmoothConcRefine) {
- lower_limit = 0;
- start_vtime_sec = os::elapsedVTime();
- prev_buffer_num = (int) dcqs.completed_buffers_num();
- } else {
- lower_limit = G1UpdateBufferQueueProcessingThreshold / 4; // For now.
+void ConcurrentG1RefineThread::wait_for_completed_buffers() {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ while (!_should_terminate && !is_active()) {
+ _monitor->wait(Mutex::_no_safepoint_check_flag);
+ }
+}
+
+bool ConcurrentG1RefineThread::is_active() {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ return _worker_id > 0 ? _active : dcqs.process_completed_buffers();
+}
+
+void ConcurrentG1RefineThread::activate() {
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ if (_worker_id > 0) {
+ if (G1TraceConcurrentRefinement) {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
+ _worker_id, _threshold, (int)dcqs.completed_buffers_num());
}
- while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, lower_limit)) {
- double end_vtime_sec;
- double elapsed_vtime_sec;
- int elapsed_vtime_ms;
- int curr_buffer_num = (int) dcqs.completed_buffers_num();
+ set_active(true);
+ } else {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ dcqs.set_process_completed(true);
+ }
+ _monitor->notify();
+}
- if (G1SmoothConcRefine) {
- end_vtime_sec = os::elapsedVTime();
- elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
- elapsed_vtime_ms = (int) (elapsed_vtime_sec * 1000.0);
+void ConcurrentG1RefineThread::deactivate() {
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ if (_worker_id > 0) {
+ if (G1TraceConcurrentRefinement) {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
+ _worker_id, _deactivation_threshold, (int)dcqs.completed_buffers_num());
+ }
+ set_active(false);
+ } else {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ dcqs.set_process_completed(false);
+ }
+}
+
+void ConcurrentG1RefineThread::run() {
+ initialize_in_thread();
+ wait_for_universe_init();
- if (curr_buffer_num > prev_buffer_num ||
- curr_buffer_num > next_threshold) {
- decreaseInterval(elapsed_vtime_ms);
- } else if (curr_buffer_num < prev_buffer_num) {
- increaseInterval(elapsed_vtime_ms);
- }
+ if (_worker_id >= cg1r()->worker_thread_num()) {
+ run_young_rs_sampling();
+ terminate();
+ }
+
+ _vtime_start = os::elapsedVTime();
+ while (!_should_terminate) {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+
+ // Wait for work
+ wait_for_completed_buffers();
+
+ if (_should_terminate) {
+ break;
+ }
+
+ _sts.join();
+
+ do {
+ int curr_buffer_num = (int)dcqs.completed_buffers_num();
+ // If the number of the buffers falls down into the yellow zone,
+ // that means that the transition period after the evacuation pause has ended.
+ if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
+ dcqs.set_completed_queue_padding(0);
}
- if (_worker_id == 0) {
- sample_young_list_rs_lengths();
- } else if (curr_buffer_num < deactivation_threshold) {
+
+ if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
// If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again.
- MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
deactivate();
- if (G1TraceConcurrentRefinement) {
- gclog_or_tty->print_cr("G1-Refine-deactivated worker %d", _worker_id);
- }
break;
}
// Check if we need to activate the next thread.
- if (curr_buffer_num > next_threshold && _next != NULL && !_next->is_active()) {
- MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
+ if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
_next->activate();
- DirtyCardQ_CBL_mon->notify_all();
- if (G1TraceConcurrentRefinement) {
- gclog_or_tty->print_cr("G1-Refine-activated worker %d", _next->_worker_id);
- }
}
+ } while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, cg1r()->green_zone()));
- if (G1SmoothConcRefine) {
- prev_buffer_num = curr_buffer_num;
- _sts.leave();
- os::sleep(Thread::current(), (jlong) _interval_ms, false);
- _sts.join();
- start_vtime_sec = os::elapsedVTime();
- }
- n_logs++;
+ // We can exit the loop above while being active if there was a yield request.
+ if (is_active()) {
+ deactivate();
}
+
_sts.leave();
if (os::supports_vtime()) {
@@ -172,7 +213,6 @@
}
}
assert(_should_terminate, "just checking");
-
terminate();
}
@@ -191,8 +231,8 @@
}
{
- MutexLockerEx x(DirtyCardQ_CBL_mon, Mutex::_no_safepoint_check_flag);
- DirtyCardQ_CBL_mon->notify_all();
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ _monitor->notify();
}
{
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -40,42 +40,36 @@
// when the number of the rset update buffer crosses a certain threshold. A successor
// would self-deactivate when the number of the buffers falls below the threshold.
bool _active;
- ConcurrentG1RefineThread * _next;
- public:
- virtual void run();
-
- bool is_active() { return _active; }
- void activate() { _active = true; }
- void deactivate() { _active = false; }
-
- private:
- ConcurrentG1Refine* _cg1r;
-
- double _interval_ms;
+ ConcurrentG1RefineThread* _next;
+ Monitor* _monitor;
+ ConcurrentG1Refine* _cg1r;
- void decreaseInterval(int processing_time_ms) {
- double min_interval_ms = (double) processing_time_ms;
- _interval_ms = 0.8 * _interval_ms;
- if (_interval_ms < min_interval_ms)
- _interval_ms = min_interval_ms;
- }
- void increaseInterval(int processing_time_ms) {
- double max_interval_ms = 9.0 * (double) processing_time_ms;
- _interval_ms = 1.1 * _interval_ms;
- if (max_interval_ms > 0 && _interval_ms > max_interval_ms)
- _interval_ms = max_interval_ms;
- }
+ int _thread_threshold_step;
+ // This thread activation threshold
+ int _threshold;
+ // This thread deactivation threshold
+ int _deactivation_threshold;
- void sleepBeforeNextCycle();
+ void sample_young_list_rs_lengths();
+ void run_young_rs_sampling();
+ void wait_for_completed_buffers();
+
+ void set_active(bool x) { _active = x; }
+ bool is_active();
+ void activate();
+ void deactivate();
// For use by G1CollectedHeap, which is a friend.
static SuspendibleThreadSet* sts() { return &_sts; }
- public:
+public:
+ virtual void run();
// Constructor
ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
int worker_id_offset, int worker_id);
+ void initialize();
+
// Printing
void print() const;
void print_on(outputStream* st) const;
@@ -83,13 +77,10 @@
// Total virtual time so far.
double vtime_accum() { return _vtime_accum; }
- ConcurrentG1Refine* cg1r() { return _cg1r; }
-
- void sample_young_list_rs_lengths();
+ ConcurrentG1Refine* cg1r() { return _cg1r; }
// Yield for GC
- void yield();
-
+ void yield();
// shutdown
void stop();
};
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -760,7 +760,6 @@
rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
- satb_mq_set.set_process_completed_threshold(G1SATBProcessCompletedThreshold);
satb_mq_set.set_active_all_threads(true);
// update_g1_committed() will be called at the end of an evac pause
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -61,8 +61,8 @@
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
#endif // _MSC_VER
-DirtyCardQueueSet::DirtyCardQueueSet() :
- PtrQueueSet(true /*notify_when_complete*/),
+DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
+ PtrQueueSet(notify_when_complete),
_closure(NULL),
_shared_dirty_card_queue(this, true /*perm*/),
_free_ids(NULL),
@@ -77,12 +77,12 @@
}
void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
+ int process_completed_threshold,
int max_completed_queue,
Mutex* lock, PtrQueueSet* fl_owner) {
- PtrQueueSet::initialize(cbl_mon, fl_lock, max_completed_queue, fl_owner);
+ PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
+ max_completed_queue, fl_owner);
set_buffer_size(G1UpdateBufferSize);
- set_process_completed_threshold(G1UpdateBufferQueueProcessingThreshold);
-
_shared_dirty_card_queue.set_lock(lock);
_free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
}
@@ -154,9 +154,10 @@
return b;
}
-DirtyCardQueueSet::CompletedBufferNode*
-DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
- CompletedBufferNode* nd = NULL;
+
+BufferNode*
+DirtyCardQueueSet::get_completed_buffer(int stop_at) {
+ BufferNode* nd = NULL;
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
if ((int)_n_completed_buffers <= stop_at) {
@@ -166,53 +167,31 @@
if (_completed_buffers_head != NULL) {
nd = _completed_buffers_head;
- _completed_buffers_head = nd->next;
+ _completed_buffers_head = nd->next();
if (_completed_buffers_head == NULL)
_completed_buffers_tail = NULL;
_n_completed_buffers--;
+ assert(_n_completed_buffers >= 0, "Invariant");
}
debug_only(assert_completed_buffer_list_len_correct_locked());
return nd;
}
-// We only do this in contexts where there is no concurrent enqueueing.
-DirtyCardQueueSet::CompletedBufferNode*
-DirtyCardQueueSet::get_completed_buffer_CAS() {
- CompletedBufferNode* nd = _completed_buffers_head;
-
- while (nd != NULL) {
- CompletedBufferNode* next = nd->next;
- CompletedBufferNode* result =
- (CompletedBufferNode*)Atomic::cmpxchg_ptr(next,
- &_completed_buffers_head,
- nd);
- if (result == nd) {
- return result;
- } else {
- nd = _completed_buffers_head;
- }
- }
- assert(_completed_buffers_head == NULL, "Loop post");
- _completed_buffers_tail = NULL;
- return NULL;
-}
-
bool DirtyCardQueueSet::
apply_closure_to_completed_buffer_helper(int worker_i,
- CompletedBufferNode* nd) {
+ BufferNode* nd) {
if (nd != NULL) {
+ void **buf = BufferNode::make_buffer_from_node(nd);
+ size_t index = nd->index();
bool b =
- DirtyCardQueue::apply_closure_to_buffer(_closure, nd->buf,
- nd->index, _sz,
+ DirtyCardQueue::apply_closure_to_buffer(_closure, buf,
+ index, _sz,
true, worker_i);
- void** buf = nd->buf;
- size_t index = nd->index;
- delete nd;
if (b) {
deallocate_buffer(buf);
return true; // In normal case, go on to next buffer.
} else {
- enqueue_complete_buffer(buf, index, true);
+ enqueue_complete_buffer(buf, index);
return false;
}
} else {
@@ -222,40 +201,36 @@
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
int stop_at,
- bool with_CAS)
+ bool during_pause)
{
- CompletedBufferNode* nd = NULL;
- if (with_CAS) {
- guarantee(stop_at == 0, "Precondition");
- nd = get_completed_buffer_CAS();
- } else {
- nd = get_completed_buffer_lock(stop_at);
- }
+ assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
+ BufferNode* nd = get_completed_buffer(stop_at);
bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
if (res) Atomic::inc(&_processed_buffers_rs_thread);
return res;
}
void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() {
- CompletedBufferNode* nd = _completed_buffers_head;
+ BufferNode* nd = _completed_buffers_head;
while (nd != NULL) {
bool b =
- DirtyCardQueue::apply_closure_to_buffer(_closure, nd->buf, 0, _sz,
- false);
+ DirtyCardQueue::apply_closure_to_buffer(_closure,
+ BufferNode::make_buffer_from_node(nd),
+ 0, _sz, false);
guarantee(b, "Should not stop early.");
- nd = nd->next;
+ nd = nd->next();
}
}
void DirtyCardQueueSet::abandon_logs() {
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
- CompletedBufferNode* buffers_to_delete = NULL;
+ BufferNode* buffers_to_delete = NULL;
{
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
while (_completed_buffers_head != NULL) {
- CompletedBufferNode* nd = _completed_buffers_head;
- _completed_buffers_head = nd->next;
- nd->next = buffers_to_delete;
+ BufferNode* nd = _completed_buffers_head;
+ _completed_buffers_head = nd->next();
+ nd->set_next(buffers_to_delete);
buffers_to_delete = nd;
}
_n_completed_buffers = 0;
@@ -263,10 +238,9 @@
debug_only(assert_completed_buffer_list_len_correct_locked());
}
while (buffers_to_delete != NULL) {
- CompletedBufferNode* nd = buffers_to_delete;
- buffers_to_delete = nd->next;
- deallocate_buffer(nd->buf);
- delete nd;
+ BufferNode* nd = buffers_to_delete;
+ buffers_to_delete = nd->next();
+ deallocate_buffer(BufferNode::make_buffer_from_node(nd));
}
// Since abandon is done only at safepoints, we can safely manipulate
// these queues.
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc. 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
@@ -84,11 +84,12 @@
jint _processed_buffers_rs_thread;
public:
- DirtyCardQueueSet();
+ DirtyCardQueueSet(bool notify_when_complete = true);
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
- int max_completed_queue = 0,
- Mutex* lock = NULL, PtrQueueSet* fl_owner = NULL);
+ int process_completed_threshold,
+ int max_completed_queue,
+ Mutex* lock, PtrQueueSet* fl_owner = NULL);
// The number of parallel ids that can be claimed to allow collector or
// mutator threads to do card-processing work.
@@ -120,12 +121,13 @@
// is returned to the completed buffer set, and this call returns false.
bool apply_closure_to_completed_buffer(int worker_i = 0,
int stop_at = 0,
- bool with_CAS = false);
+ bool during_pause = false);
+
bool apply_closure_to_completed_buffer_helper(int worker_i,
- CompletedBufferNode* nd);
+ BufferNode* nd);
- CompletedBufferNode* get_completed_buffer_CAS();
- CompletedBufferNode* get_completed_buffer_lock(int stop_at);
+ BufferNode* get_completed_buffer(int stop_at);
+
// Applies the current closure to all completed buffers,
// non-consumptively.
void apply_closure_to_all_completed_buffers();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -928,6 +928,8 @@
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty);
+ TraceMemoryManagerStats tms(true /* fullGC */);
+
double start = os::elapsedTime();
g1_policy()->record_full_collection_start();
@@ -1001,6 +1003,8 @@
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+ MemoryService::track_memory_usage();
+
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification
gclog_or_tty->print(" VerifyAfterGC:");
@@ -1371,6 +1375,7 @@
G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
SharedHeap(policy_),
_g1_policy(policy_),
+ _dirty_card_queue_set(false),
_ref_processor(NULL),
_process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
_bot_shared(NULL),
@@ -1456,8 +1461,6 @@
Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
- // We allocate this in any case, but only do no work if the command line
- // param is off.
_cg1r = new ConcurrentG1Refine();
// Reserve the maximum.
@@ -1590,18 +1593,20 @@
JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon,
SATB_Q_FL_lock,
- 0,
+ G1SATBProcessCompletedThreshold,
Shared_SATB_Q_lock);
JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
DirtyCardQ_FL_lock,
- G1UpdateBufferQueueMaxLength,
+ concurrent_g1_refine()->yellow_zone(),
+ concurrent_g1_refine()->red_zone(),
Shared_DirtyCardQ_lock);
if (G1DeferredRSUpdate) {
dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
DirtyCardQ_FL_lock,
- 0,
+ -1, // never trigger processing
+ -1, // no limit on length
Shared_DirtyCardQ_lock,
&JavaThread::dirty_card_queue_set());
}
@@ -1732,13 +1737,6 @@
return car->free();
}
-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");
- MutexLocker ml(Heap_lock);
- collect_locked(cause);
-}
-
void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
assert(Thread::current()->is_VM_thread(), "Precondition#1");
assert(Heap_lock->is_locked(), "Precondition#2");
@@ -1755,17 +1753,31 @@
}
}
-
-void G1CollectedHeap::collect_locked(GCCause::Cause cause) {
- // Don't want to do a GC until cleanup is completed.
- wait_for_cleanup_complete();
-
- // Read the GC count while holding the Heap_lock
- int gc_count_before = SharedHeap::heap()->total_collections();
+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");
+
+ int gc_count_before;
{
- MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back
- VM_G1CollectFull op(gc_count_before, cause);
- VMThread::execute(&op);
+ MutexLocker ml(Heap_lock);
+ // Read the GC count while holding the Heap_lock
+ gc_count_before = SharedHeap::heap()->total_collections();
+
+ // Don't want to do a GC until cleanup is completed.
+ wait_for_cleanup_complete();
+ } // We give up heap lock; VMThread::execute gets it back below
+ switch (cause) {
+ case GCCause::_scavenge_alot: {
+ // Do an incremental pause, which might sometimes be abandoned.
+ VM_G1IncCollectionPause op(gc_count_before, cause);
+ VMThread::execute(&op);
+ break;
+ }
+ default: {
+ // In all other cases, we currently do a full gc.
+ VM_G1CollectFull op(gc_count_before, cause);
+ VMThread::execute(&op);
+ }
}
}
@@ -2119,7 +2131,7 @@
}
size_t G1CollectedHeap::max_capacity() const {
- return _g1_committed.byte_size();
+ return g1_reserved_obj_bytes();
}
jlong G1CollectedHeap::millis_since_last_gc() {
@@ -2638,6 +2650,8 @@
}
{
+ ResourceMark rm;
+
char verbose_str[128];
sprintf(verbose_str, "GC pause ");
if (g1_policy()->in_young_gc_mode()) {
@@ -2649,8 +2663,6 @@
if (g1_policy()->should_initiate_conc_mark())
strcat(verbose_str, " (initial-mark)");
- GCCauseSetter x(this, GCCause::_g1_inc_collection_pause);
-
// if PrintGCDetails is on, we'll print long statistics information
// in the collector policy code, so let's not print this as the output
// is messy if we do.
@@ -2658,7 +2670,8 @@
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty);
- ResourceMark rm;
+ TraceMemoryManagerStats tms(false /* fullGC */);
+
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread");
guarantee(!is_gc_active(), "collection is not reentrant");
@@ -2802,6 +2815,22 @@
_young_list->reset_auxilary_lists();
}
} else {
+ if (_in_cset_fast_test != NULL) {
+ assert(_in_cset_fast_test_base != NULL, "Since _in_cset_fast_test isn't");
+ FREE_C_HEAP_ARRAY(bool, _in_cset_fast_test_base);
+ // this is more for peace of mind; we're nulling them here and
+ // we're expecting them to be null at the beginning of the next GC
+ _in_cset_fast_test = NULL;
+ _in_cset_fast_test_base = NULL;
+ }
+ // This looks confusing, because the DPT should really be empty
+ // at this point -- since we have not done any collection work,
+ // there should not be any derived pointers in the table to update;
+ // however, there is some additional state in the DPT which is
+ // reset at the end of the (null) "gc" here via the following call.
+ // A better approach might be to split off that state resetting work
+ // into a separate method that asserts that the DPT is empty and call
+ // that here. That is deferred for now.
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
}
@@ -2838,6 +2867,8 @@
assert(regions_accounted_for(), "Region leakage.");
+ MemoryService::track_memory_usage();
+
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification
gclog_or_tty->print(" VerifyAfterGC:");
@@ -4209,10 +4240,11 @@
RedirtyLoggedCardTableEntryFastClosure redirty;
dirty_card_queue_set().set_closure(&redirty);
dirty_card_queue_set().apply_closure_to_all_completed_buffers();
- JavaThread::dirty_card_queue_set().merge_bufferlists(&dirty_card_queue_set());
+
+ DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
+ dcq.merge_bufferlists(&dirty_card_queue_set());
assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
}
-
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -692,7 +692,7 @@
// Reserved (g1 only; super method includes perm), capacity and the used
// portion in bytes.
- size_t g1_reserved_obj_bytes() { return _g1_reserved.byte_size(); }
+ size_t g1_reserved_obj_bytes() const { return _g1_reserved.byte_size(); }
virtual size_t capacity() const;
virtual size_t used() const;
// This should be called when we're not holding the heap lock. The
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1516,8 +1516,30 @@
(end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
update_recent_gc_times(end_time_sec, elapsed_ms);
_recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
- // using 1.01 to account for floating point inaccuracies
- assert(recent_avg_pause_time_ratio() < 1.01, "All GC?");
+ if (recent_avg_pause_time_ratio() < 0.0 ||
+ (recent_avg_pause_time_ratio() - 1.0 > 0.0)) {
+#ifndef PRODUCT
+ // Dump info to allow post-facto debugging
+ gclog_or_tty->print_cr("recent_avg_pause_time_ratio() out of bounds");
+ gclog_or_tty->print_cr("-------------------------------------------");
+ gclog_or_tty->print_cr("Recent GC Times (ms):");
+ _recent_gc_times_ms->dump();
+ gclog_or_tty->print_cr("(End Time=%3.3f) Recent GC End Times (s):", end_time_sec);
+ _recent_prev_end_times_for_all_gcs_sec->dump();
+ gclog_or_tty->print_cr("GC = %3.3f, Interval = %3.3f, Ratio = %3.3f",
+ _recent_gc_times_ms->sum(), interval_ms, recent_avg_pause_time_ratio());
+ // In debug mode, terminate the JVM if the user wants to debug at this point.
+ assert(!G1FailOnFPError, "Debugging data for CR 6898948 has been dumped above");
+#endif // !PRODUCT
+ // Clip ratio between 0.0 and 1.0, and continue. This will be fixed in
+ // CR 6902692 by redoing the manner in which the ratio is incrementally computed.
+ if (_recent_avg_pause_time_ratio < 0.0) {
+ _recent_avg_pause_time_ratio = 0.0;
+ } else {
+ assert(_recent_avg_pause_time_ratio - 1.0 > 0.0, "Ctl-point invariant");
+ _recent_avg_pause_time_ratio = 1.0;
+ }
+ }
}
if (G1PolicyVerbose > 1) {
@@ -1892,6 +1914,10 @@
calculate_young_list_min_length();
calculate_young_list_target_config();
+ // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
+ double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSUpdatePauseFractionPercent / 100.0;
+ adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
+
// </NEW PREDICTION>
_target_pause_time_ms = -1.0;
@@ -1899,6 +1925,47 @@
// <NEW PREDICTION>
+void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
+ double update_rs_processed_buffers,
+ double goal_ms) {
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
+
+ if (G1AdaptiveConcRefine) {
+ const int k_gy = 3, k_gr = 6;
+ const double inc_k = 1.1, dec_k = 0.9;
+
+ int g = cg1r->green_zone();
+ if (update_rs_time > goal_ms) {
+ g = (int)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
+ } else {
+ if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
+ g = (int)MAX2(g * inc_k, g + 1.0);
+ }
+ }
+ // Change the refinement threads params
+ cg1r->set_green_zone(g);
+ cg1r->set_yellow_zone(g * k_gy);
+ cg1r->set_red_zone(g * k_gr);
+ cg1r->reinitialize_threads();
+
+ int processing_threshold_delta = MAX2((int)(cg1r->green_zone() * sigma()), 1);
+ int processing_threshold = MIN2(cg1r->green_zone() + processing_threshold_delta,
+ cg1r->yellow_zone());
+ // Change the barrier params
+ dcqs.set_process_completed_threshold(processing_threshold);
+ dcqs.set_max_completed_queue(cg1r->red_zone());
+ }
+
+ int curr_queue_size = dcqs.completed_buffers_num();
+ if (curr_queue_size >= cg1r->yellow_zone()) {
+ dcqs.set_completed_queue_padding(curr_queue_size);
+ } else {
+ dcqs.set_completed_queue_padding(0);
+ }
+ dcqs.notify_if_necessary();
+}
+
double
G1CollectorPolicy::
predict_young_collection_elapsed_time_ms(size_t adjustment) {
@@ -2825,8 +2892,15 @@
double non_young_start_time_sec;
start_recording_regions();
- guarantee(_target_pause_time_ms > -1.0,
+ guarantee(_target_pause_time_ms > -1.0
+ NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot),
"_target_pause_time_ms should have been set!");
+#ifndef PRODUCT
+ if (_target_pause_time_ms <= -1.0) {
+ assert(ScavengeALot && Universe::heap()->gc_cause() == GCCause::_scavenge_alot, "Error");
+ _target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
+ }
+#endif
assert(_collection_set == NULL, "Precondition");
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
@@ -2972,7 +3046,3 @@
G1CollectorPolicy::record_collection_pause_end(abandoned);
assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
}
-
-// Local Variables: ***
-// c-indentation-style: gnu ***
-// End: ***
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -316,6 +316,10 @@
bool verify_young_ages(HeapRegion* head, SurvRateGroup *surv_rate_group);
#endif // PRODUCT
+ void adjust_concurrent_refinement(double update_rs_time,
+ double update_rs_processed_buffers,
+ double goal_ms);
+
protected:
double _pause_time_target_ms;
double _recorded_young_cset_choice_time_ms;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -86,12 +86,22 @@
// increase the array size (:-)
// remove the oldest entry (this might allow more GC time for
// the time slice than what's allowed)
- // concolidate the two entries with the minimum gap between them
- // (this mighte allow less GC time than what's allowed)
- guarantee(0, "array full, currently we can't recover");
+ // consolidate the two entries with the minimum gap between them
+ // (this might allow less GC time than what's allowed)
+ guarantee(NOT_PRODUCT(ScavengeALot ||) G1ForgetfulMMUTracker,
+ "array full, currently we can't recover unless +G1ForgetfulMMUTracker");
+ // In the case where ScavengeALot is true, such overflow is not
+ // uncommon; in such cases, we can, without much loss of precision
+ // or performance (we are GC'ing most of the time anyway!),
+ // simply overwrite the oldest entry in the tracker: this
+ // is also the behaviour when G1ForgetfulMMUTracker is enabled.
+ _head_index = trim_index(_head_index + 1);
+ assert(_head_index == _tail_index, "Because we have a full circular buffer");
+ _tail_index = trim_index(_tail_index + 1);
+ } else {
+ _head_index = trim_index(_head_index + 1);
+ ++_no_entries;
}
- _head_index = trim_index(_head_index + 1);
- ++_no_entries;
_array[_head_index] = G1MMUTrackerQueueElem(start, end);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -99,7 +99,10 @@
// The array is of fixed size and I don't think we'll need more than
// two or three entries with the current behaviour of G1 pauses.
// If the array is full, an easy fix is to look for the pauses with
- // the shortest gap between them and concolidate them.
+ // the shortest gap between them and consolidate them.
+ // For now, we have taken the expedient alternative of forgetting
+ // the oldest entry in the event that +G1ForgetfulMMUTracker, thus
+ // potentially violating MMU specs for some time thereafter.
G1MMUTrackerQueueElem _array[QueueLength];
int _head_index;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -85,7 +85,7 @@
diagnostic(bool, G1SummarizeZFStats, false, \
"Summarize zero-filling info") \
\
- develop(bool, G1TraceConcurrentRefinement, false, \
+ diagnostic(bool, G1TraceConcurrentRefinement, false, \
"Trace G1 concurrent refinement") \
\
product(intx, G1MarkStackSize, 2 * 1024 * 1024, \
@@ -94,19 +94,6 @@
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
"Size of the region stack for concurrent marking.") \
\
- develop(bool, G1ConcRefine, true, \
- "If true, run concurrent rem set refinement for G1") \
- \
- develop(intx, G1ConcRefineTargTraversals, 4, \
- "Number of concurrent refinement we try to achieve") \
- \
- develop(intx, G1ConcRefineInitialDelta, 4, \
- "Number of heap regions of alloc ahead of starting collection " \
- "pause to start concurrent refinement (initially)") \
- \
- develop(bool, G1SmoothConcRefine, true, \
- "Attempts to smooth out the overhead of concurrent refinement") \
- \
develop(bool, G1ConcZeroFill, true, \
"If true, run concurrent zero-filling thread") \
\
@@ -178,13 +165,38 @@
product(intx, G1UpdateBufferSize, 256, \
"Size of an update buffer") \
\
- product(intx, G1UpdateBufferQueueProcessingThreshold, 5, \
+ product(intx, G1ConcRefineYellowZone, 0, \
"Number of enqueued update buffers that will " \
- "trigger concurrent processing") \
+ "trigger concurrent processing. Will be selected ergonomically " \
+ "by default.") \
+ \
+ product(intx, G1ConcRefineRedZone, 0, \
+ "Maximum number of enqueued update buffers before mutator " \
+ "threads start processing new ones instead of enqueueing them. " \
+ "Will be selected ergonomically by default. Zero will disable " \
+ "concurrent processing.") \
+ \
+ product(intx, G1ConcRefineGreenZone, 0, \
+ "The number of update buffers that are left in the queue by the " \
+ "concurrent processing threads. Will be selected ergonomically " \
+ "by default.") \
\
- product(intx, G1UpdateBufferQueueMaxLength, 30, \
- "Maximum number of enqueued update buffers before mutator " \
- "threads start processing new ones instead of enqueueing them") \
+ product(intx, G1ConcRefineServiceInterval, 300, \
+ "The last concurrent refinement thread wakes up every " \
+ "specified number of milliseconds to do miscellaneous work.") \
+ \
+ product(intx, G1ConcRefineThresholdStep, 0, \
+ "Each time the rset update queue increases by this amount " \
+ "activate the next refinement thread if available. " \
+ "Will be selected ergonomically by default.") \
+ \
+ product(intx, G1RSUpdatePauseFractionPercent, 10, \
+ "A target percentage of time that is allowed to be spend on " \
+ "process RS update buffers during the collection pause.") \
+ \
+ product(bool, G1AdaptiveConcRefine, true, \
+ "Select green, yellow and red zones adaptively to meet the " \
+ "the pause requirements.") \
\
develop(intx, G1ConcRSLogCacheSize, 10, \
"Log base 2 of the length of conc RS hot-card cache.") \
@@ -242,6 +254,10 @@
product(bool, G1UseSurvivorSpaces, true, \
"When true, use survivor space.") \
\
+ develop(bool, G1FailOnFPError, false, \
+ "When set, G1 will fail when it encounters an FP 'error', " \
+ "so as to allow debugging") \
+ \
develop(bool, G1FixedTenuringThreshold, false, \
"When set, G1 will not adjust the tenuring threshold") \
\
@@ -252,6 +268,9 @@
"If non-0 is the size of the G1 survivor space, " \
"otherwise SurvivorRatio is used to determine the size") \
\
+ product(bool, G1ForgetfulMMUTracker, false, \
+ "If the MMU tracker's memory is full, forget the oldest entry") \
+ \
product(uintx, G1HeapRegionSize, 0, \
"Size of the G1 regions.") \
\
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -64,8 +64,8 @@
while (_index == 0) {
handle_zero_index();
}
+
assert(_index > 0, "postcondition");
-
_index -= oopSize;
_buf[byte_index_to_index((int)_index)] = ptr;
assert(0 <= _index && _index <= _sz, "Invariant.");
@@ -99,94 +99,110 @@
assert(_sz > 0, "Didn't set a buffer size.");
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
if (_fl_owner->_buf_free_list != NULL) {
- void** res = _fl_owner->_buf_free_list;
- _fl_owner->_buf_free_list = (void**)_fl_owner->_buf_free_list[0];
+ void** res = BufferNode::make_buffer_from_node(_fl_owner->_buf_free_list);
+ _fl_owner->_buf_free_list = _fl_owner->_buf_free_list->next();
_fl_owner->_buf_free_list_sz--;
- // Just override the next pointer with NULL, just in case we scan this part
- // of the buffer.
- res[0] = NULL;
return res;
} else {
- return NEW_C_HEAP_ARRAY(void*, _sz);
+ // Allocate space for the BufferNode in front of the buffer.
+ char *b = NEW_C_HEAP_ARRAY(char, _sz + BufferNode::aligned_size());
+ return BufferNode::make_buffer_from_block(b);
}
}
void PtrQueueSet::deallocate_buffer(void** buf) {
assert(_sz > 0, "Didn't set a buffer size.");
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
- buf[0] = (void*)_fl_owner->_buf_free_list;
- _fl_owner->_buf_free_list = buf;
+ BufferNode *node = BufferNode::make_node_from_buffer(buf);
+ node->set_next(_fl_owner->_buf_free_list);
+ _fl_owner->_buf_free_list = node;
_fl_owner->_buf_free_list_sz++;
}
void PtrQueueSet::reduce_free_list() {
+ assert(_fl_owner == this, "Free list reduction is allowed only for the owner");
// For now we'll adopt the strategy of deleting half.
MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
size_t n = _buf_free_list_sz / 2;
while (n > 0) {
assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
- void** head = _buf_free_list;
- _buf_free_list = (void**)_buf_free_list[0];
- FREE_C_HEAP_ARRAY(void*,head);
+ void* b = BufferNode::make_block_from_node(_buf_free_list);
+ _buf_free_list = _buf_free_list->next();
+ FREE_C_HEAP_ARRAY(char, b);
+ _buf_free_list_sz --;
n--;
}
}
-void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index, bool ignore_max_completed) {
- // I use explicit locking here because there's a bailout in the middle.
- _cbl_mon->lock_without_safepoint_check();
-
- Thread* thread = Thread::current();
- assert( ignore_max_completed ||
- thread->is_Java_thread() ||
- SafepointSynchronize::is_at_safepoint(),
- "invariant" );
- ignore_max_completed = ignore_max_completed || !thread->is_Java_thread();
+void PtrQueue::handle_zero_index() {
+ assert(0 == _index, "Precondition.");
+ // This thread records the full buffer and allocates a new one (while
+ // holding the lock if there is one).
+ if (_buf != NULL) {
+ if (_lock) {
+ locking_enqueue_completed_buffer(_buf);
+ } else {
+ if (qset()->process_or_enqueue_complete_buffer(_buf)) {
+ // Recycle the buffer. No allocation.
+ _sz = qset()->buffer_size();
+ _index = _sz;
+ return;
+ }
+ }
+ }
+ // Reallocate the buffer
+ _buf = qset()->allocate_buffer();
+ _sz = qset()->buffer_size();
+ _index = _sz;
+ assert(0 <= _index && _index <= _sz, "Invariant.");
+}
- if (!ignore_max_completed && _max_completed_queue > 0 &&
- _n_completed_buffers >= (size_t) _max_completed_queue) {
- _cbl_mon->unlock();
- bool b = mut_process_buffer(buf);
- if (b) {
- deallocate_buffer(buf);
- return;
+bool PtrQueueSet::process_or_enqueue_complete_buffer(void** buf) {
+ if (Thread::current()->is_Java_thread()) {
+ // We don't lock. It is fine to be epsilon-precise here.
+ if (_max_completed_queue == 0 || _max_completed_queue > 0 &&
+ _n_completed_buffers >= _max_completed_queue + _completed_queue_padding) {
+ bool b = mut_process_buffer(buf);
+ if (b) {
+ // True here means that the buffer hasn't been deallocated and the caller may reuse it.
+ return true;
+ }
}
+ }
+ // The buffer will be enqueued. The caller will have to get a new one.
+ enqueue_complete_buffer(buf);
+ return false;
+}
- // Otherwise, go ahead and enqueue the buffer. Must reaquire the lock.
- _cbl_mon->lock_without_safepoint_check();
- }
-
- // Here we still hold the _cbl_mon.
- CompletedBufferNode* cbn = new CompletedBufferNode;
- cbn->buf = buf;
- cbn->next = NULL;
- cbn->index = index;
+void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index) {
+ MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+ BufferNode* cbn = BufferNode::new_from_buffer(buf);
+ cbn->set_index(index);
if (_completed_buffers_tail == NULL) {
assert(_completed_buffers_head == NULL, "Well-formedness");
_completed_buffers_head = cbn;
_completed_buffers_tail = cbn;
} else {
- _completed_buffers_tail->next = cbn;
+ _completed_buffers_tail->set_next(cbn);
_completed_buffers_tail = cbn;
}
_n_completed_buffers++;
- if (!_process_completed &&
+ if (!_process_completed && _process_completed_threshold >= 0 &&
_n_completed_buffers >= _process_completed_threshold) {
_process_completed = true;
if (_notify_when_complete)
- _cbl_mon->notify_all();
+ _cbl_mon->notify();
}
debug_only(assert_completed_buffer_list_len_correct_locked());
- _cbl_mon->unlock();
}
int PtrQueueSet::completed_buffers_list_length() {
int n = 0;
- CompletedBufferNode* cbn = _completed_buffers_head;
+ BufferNode* cbn = _completed_buffers_head;
while (cbn != NULL) {
n++;
- cbn = cbn->next;
+ cbn = cbn->next();
}
return n;
}
@@ -197,7 +213,7 @@
}
void PtrQueueSet::assert_completed_buffer_list_len_correct_locked() {
- guarantee((size_t)completed_buffers_list_length() == _n_completed_buffers,
+ guarantee(completed_buffers_list_length() == _n_completed_buffers,
"Completed buffer length is wrong.");
}
@@ -206,12 +222,8 @@
_sz = sz * oopSize;
}
-void PtrQueueSet::set_process_completed_threshold(size_t sz) {
- _process_completed_threshold = sz;
-}
-
-// Merge lists of buffers. Notify waiting threads if the length of the list
-// exceeds threshold. The source queue is emptied as a result. The queues
+// Merge lists of buffers. Notify the processing threads.
+// The source queue is emptied as a result. The queues
// must share the monitor.
void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
@@ -223,7 +235,7 @@
} else {
assert(_completed_buffers_head != NULL, "Well formedness");
if (src->_completed_buffers_head != NULL) {
- _completed_buffers_tail->next = src->_completed_buffers_head;
+ _completed_buffers_tail->set_next(src->_completed_buffers_head);
_completed_buffers_tail = src->_completed_buffers_tail;
}
}
@@ -236,31 +248,13 @@
assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
_completed_buffers_head != NULL && _completed_buffers_tail != NULL,
"Sanity");
-
- if (!_process_completed &&
- _n_completed_buffers >= _process_completed_threshold) {
- _process_completed = true;
- if (_notify_when_complete)
- _cbl_mon->notify_all();
- }
}
-// Merge free lists of the two queues. The free list of the source
-// queue is emptied as a result. The queues must share the same
-// mutex that guards free lists.
-void PtrQueueSet::merge_freelists(PtrQueueSet* src) {
- assert(_fl_lock == src->_fl_lock, "Should share the same lock");
- MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
- if (_buf_free_list != NULL) {
- void **p = _buf_free_list;
- while (*p != NULL) {
- p = (void**)*p;
- }
- *p = src->_buf_free_list;
- } else {
- _buf_free_list = src->_buf_free_list;
+void PtrQueueSet::notify_if_necessary() {
+ MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+ if (_n_completed_buffers >= _process_completed_threshold || _max_completed_queue == 0) {
+ _process_completed = true;
+ if (_notify_when_complete)
+ _cbl_mon->notify();
}
- _buf_free_list_sz += src->_buf_free_list_sz;
- src->_buf_free_list = NULL;
- src->_buf_free_list_sz = 0;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -27,8 +27,10 @@
// the addresses of modified old-generation objects. This type supports
// this operation.
+// The definition of placement operator new(size_t, void*) in the <new>.
+#include <new>
+
class PtrQueueSet;
-
class PtrQueue VALUE_OBJ_CLASS_SPEC {
protected:
@@ -77,7 +79,7 @@
else enqueue_known_active(ptr);
}
- inline void handle_zero_index();
+ void handle_zero_index();
void locking_enqueue_completed_buffer(void** buf);
void enqueue_known_active(void* ptr);
@@ -126,34 +128,65 @@
};
+class BufferNode {
+ size_t _index;
+ BufferNode* _next;
+public:
+ BufferNode() : _index(0), _next(NULL) { }
+ BufferNode* next() const { return _next; }
+ void set_next(BufferNode* n) { _next = n; }
+ size_t index() const { return _index; }
+ void set_index(size_t i) { _index = i; }
+
+ // Align the size of the structure to the size of the pointer
+ static size_t aligned_size() {
+ static const size_t alignment = round_to(sizeof(BufferNode), sizeof(void*));
+ return alignment;
+ }
+
+ // BufferNode is allocated before the buffer.
+ // The chunk of memory that holds both of them is a block.
+
+ // Produce a new BufferNode given a buffer.
+ static BufferNode* new_from_buffer(void** buf) {
+ return new (make_block_from_buffer(buf)) BufferNode;
+ }
+
+ // The following are the required conversion routines:
+ static BufferNode* make_node_from_buffer(void** buf) {
+ return (BufferNode*)make_block_from_buffer(buf);
+ }
+ static void** make_buffer_from_node(BufferNode *node) {
+ return make_buffer_from_block(node);
+ }
+ static void* make_block_from_node(BufferNode *node) {
+ return (void*)node;
+ }
+ static void** make_buffer_from_block(void* p) {
+ return (void**)((char*)p + aligned_size());
+ }
+ static void* make_block_from_buffer(void** p) {
+ return (void*)((char*)p - aligned_size());
+ }
+};
+
// A PtrQueueSet represents resources common to a set of pointer queues.
// In particular, the individual queues allocate buffers from this shared
// set, and return completed buffers to the set.
// All these variables are are protected by the TLOQ_CBL_mon. XXX ???
class PtrQueueSet VALUE_OBJ_CLASS_SPEC {
-
protected:
-
- class CompletedBufferNode: public CHeapObj {
- public:
- void** buf;
- size_t index;
- CompletedBufferNode* next;
- CompletedBufferNode() : buf(NULL),
- index(0), next(NULL){ }
- };
-
Monitor* _cbl_mon; // Protects the fields below.
- CompletedBufferNode* _completed_buffers_head;
- CompletedBufferNode* _completed_buffers_tail;
- size_t _n_completed_buffers;
- size_t _process_completed_threshold;
+ BufferNode* _completed_buffers_head;
+ BufferNode* _completed_buffers_tail;
+ int _n_completed_buffers;
+ int _process_completed_threshold;
volatile bool _process_completed;
// This (and the interpretation of the first element as a "next"
// pointer) are protected by the TLOQ_FL_lock.
Mutex* _fl_lock;
- void** _buf_free_list;
+ BufferNode* _buf_free_list;
size_t _buf_free_list_sz;
// Queue set can share a freelist. The _fl_owner variable
// specifies the owner. It is set to "this" by default.
@@ -170,6 +203,7 @@
// Maximum number of elements allowed on completed queue: after that,
// enqueuer does the work itself. Zero indicates no maximum.
int _max_completed_queue;
+ int _completed_queue_padding;
int completed_buffers_list_length();
void assert_completed_buffer_list_len_correct_locked();
@@ -191,9 +225,12 @@
// Because of init-order concerns, we can't pass these as constructor
// arguments.
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
- int max_completed_queue = 0,
+ int process_completed_threshold,
+ int max_completed_queue,
PtrQueueSet *fl_owner = NULL) {
_max_completed_queue = max_completed_queue;
+ _process_completed_threshold = process_completed_threshold;
+ _completed_queue_padding = 0;
assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
_cbl_mon = cbl_mon;
_fl_lock = fl_lock;
@@ -208,14 +245,17 @@
void deallocate_buffer(void** buf);
// Declares that "buf" is a complete buffer.
- void enqueue_complete_buffer(void** buf, size_t index = 0,
- bool ignore_max_completed = false);
+ void enqueue_complete_buffer(void** buf, size_t index = 0);
+
+ // To be invoked by the mutator.
+ bool process_or_enqueue_complete_buffer(void** buf);
bool completed_buffers_exist_dirty() {
return _n_completed_buffers > 0;
}
bool process_completed_buffers() { return _process_completed; }
+ void set_process_completed(bool x) { _process_completed = x; }
bool active() { return _all_active; }
@@ -226,15 +266,24 @@
// Get the buffer size.
size_t buffer_size() { return _sz; }
- // Set the number of completed buffers that triggers log processing.
- void set_process_completed_threshold(size_t sz);
+ // Get/Set the number of completed buffers that triggers log processing.
+ void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; }
+ int process_completed_threshold() const { return _process_completed_threshold; }
// Must only be called at a safe point. Indicates that the buffer free
// list size may be reduced, if that is deemed desirable.
void reduce_free_list();
- size_t completed_buffers_num() { return _n_completed_buffers; }
+ int completed_buffers_num() { return _n_completed_buffers; }
void merge_bufferlists(PtrQueueSet* src);
- void merge_freelists(PtrQueueSet* src);
+
+ void set_max_completed_queue(int m) { _max_completed_queue = m; }
+ int max_completed_queue() { return _max_completed_queue; }
+
+ void set_completed_queue_padding(int padding) { _completed_queue_padding = padding; }
+ int completed_queue_padding() { return _completed_queue_padding; }
+
+ // Notify the consumer if the number of buffers crossed the threshold
+ void notify_if_necessary();
};
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -67,9 +67,9 @@
{}
void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
- int max_completed_queue,
+ int process_completed_threshold,
Mutex* lock) {
- PtrQueueSet::initialize(cbl_mon, fl_lock, max_completed_queue);
+ PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
_shared_satb_queue.set_lock(lock);
if (ParallelGCThreads > 0) {
_par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads);
@@ -122,12 +122,12 @@
bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
int worker) {
- CompletedBufferNode* nd = NULL;
+ BufferNode* nd = NULL;
{
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
if (_completed_buffers_head != NULL) {
nd = _completed_buffers_head;
- _completed_buffers_head = nd->next;
+ _completed_buffers_head = nd->next();
if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
_n_completed_buffers--;
if (_n_completed_buffers == 0) _process_completed = false;
@@ -135,9 +135,9 @@
}
ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
if (nd != NULL) {
- ObjPtrQueue::apply_closure_to_buffer(cl, nd->buf, 0, _sz);
- deallocate_buffer(nd->buf);
- delete nd;
+ void **buf = BufferNode::make_buffer_from_node(nd);
+ ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
+ deallocate_buffer(buf);
return true;
} else {
return false;
@@ -145,13 +145,13 @@
}
void SATBMarkQueueSet::abandon_partial_marking() {
- CompletedBufferNode* buffers_to_delete = NULL;
+ BufferNode* buffers_to_delete = NULL;
{
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
while (_completed_buffers_head != NULL) {
- CompletedBufferNode* nd = _completed_buffers_head;
- _completed_buffers_head = nd->next;
- nd->next = buffers_to_delete;
+ BufferNode* nd = _completed_buffers_head;
+ _completed_buffers_head = nd->next();
+ nd->set_next(buffers_to_delete);
buffers_to_delete = nd;
}
_completed_buffers_tail = NULL;
@@ -159,10 +159,9 @@
DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
}
while (buffers_to_delete != NULL) {
- CompletedBufferNode* nd = buffers_to_delete;
- buffers_to_delete = nd->next;
- deallocate_buffer(nd->buf);
- delete nd;
+ BufferNode* nd = buffers_to_delete;
+ buffers_to_delete = nd->next();
+ deallocate_buffer(BufferNode::make_buffer_from_node(nd));
}
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
// So we can safely manipulate these queues.
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -60,8 +60,8 @@
SATBMarkQueueSet();
void initialize(Monitor* cbl_mon, Mutex* fl_lock,
- int max_completed_queue = 0,
- Mutex* lock = NULL);
+ int process_completed_threshold,
+ Mutex* lock);
static void handle_zero_index_for_thread(JavaThread* t);
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -42,7 +42,7 @@
void VM_G1IncCollectionPause::doit() {
JvmtiGCForAllocationMarker jgcm;
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- GCCauseSetter x(g1h, GCCause::_g1_inc_collection_pause);
+ GCCauseSetter x(g1h, _gc_cause);
g1h->do_collection_pause_at_safepoint();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -68,8 +68,9 @@
class VM_G1IncCollectionPause: public VM_GC_Operation {
public:
- VM_G1IncCollectionPause(int gc_count_before) :
- VM_GC_Operation(gc_count_before) {}
+ VM_G1IncCollectionPause(int gc_count_before,
+ GCCause::Cause gc_cause = GCCause::_g1_inc_collection_pause) :
+ VM_GC_Operation(gc_count_before) { _gc_cause = gc_cause; }
virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; }
virtual void doit();
virtual const char* name() const {
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 Wed Jul 05 17:04:56 2017 +0200
@@ -109,7 +109,6 @@
dirtyCardQueue.cpp dirtyCardQueue.hpp
dirtyCardQueue.cpp heapRegionRemSet.hpp
dirtyCardQueue.cpp mutexLocker.hpp
-dirtyCardQueue.cpp ptrQueue.inline.hpp
dirtyCardQueue.cpp safepoint.hpp
dirtyCardQueue.cpp thread.hpp
dirtyCardQueue.cpp thread_<os_family>.inline.hpp
@@ -222,6 +221,15 @@
g1MarkSweep.hpp timer.hpp
g1MarkSweep.hpp universe.hpp
+g1MemoryPool.cpp heapRegion.hpp
+g1MemoryPool.cpp g1CollectedHeap.inline.hpp
+g1MemoryPool.cpp g1CollectedHeap.hpp
+g1MemoryPool.cpp g1CollectorPolicy.hpp
+g1MemoryPool.cpp g1MemoryPool.hpp
+
+g1MemoryPool.hpp memoryUsage.hpp
+g1MemoryPool.hpp memoryPool.hpp
+
g1OopClosures.inline.hpp concurrentMark.hpp
g1OopClosures.inline.hpp g1OopClosures.hpp
g1OopClosures.inline.hpp g1CollectedHeap.hpp
@@ -303,12 +311,13 @@
klass.hpp g1OopClosures.hpp
+memoryService.cpp g1MemoryPool.hpp
+
ptrQueue.cpp allocation.hpp
ptrQueue.cpp allocation.inline.hpp
ptrQueue.cpp mutex.hpp
ptrQueue.cpp mutexLocker.hpp
ptrQueue.cpp ptrQueue.hpp
-ptrQueue.cpp ptrQueue.inline.hpp
ptrQueue.cpp thread_<os_family>.inline.hpp
ptrQueue.hpp allocation.hpp
@@ -318,7 +327,6 @@
satbQueue.cpp allocation.inline.hpp
satbQueue.cpp mutexLocker.hpp
-satbQueue.cpp ptrQueue.inline.hpp
satbQueue.cpp satbQueue.hpp
satbQueue.cpp sharedHeap.hpp
satbQueue.cpp thread.hpp
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -51,7 +51,7 @@
cname = PerfDataManager::counter_name(name_space(), "oldCapacity");
_old_capacity = PerfDataManager::create_variable(SUN_GC, cname,
- PerfData::U_Bytes, (jlong) Arguments::initial_heap_size(), CHECK);
+ PerfData::U_Bytes, (jlong) InitialHeapSize, CHECK);
cname = PerfDataManager::counter_name(name_space(), "boundaryMoved");
_boundary_moved = PerfDataManager::create_variable(SUN_GC, cname,
--- a/hotspot/src/share/vm/includeDB_compiler2 Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/includeDB_compiler2 Wed Jul 05 17:04:56 2017 +0200
@@ -149,6 +149,7 @@
c2compiler.hpp abstractCompiler.hpp
callGenerator.cpp addnode.hpp
+callGenerator.cpp bcEscapeAnalyzer.hpp
callGenerator.cpp callGenerator.hpp
callGenerator.cpp callnode.hpp
callGenerator.cpp cfgnode.hpp
@@ -321,6 +322,7 @@
compile.cpp rootnode.hpp
compile.cpp runtime.hpp
compile.cpp signature.hpp
+compile.cpp stringopts.hpp
compile.cpp stubRoutines.hpp
compile.cpp systemDictionary.hpp
compile.cpp timer.hpp
@@ -476,12 +478,16 @@
graphKit.cpp runtime.hpp
graphKit.cpp sharedRuntime.hpp
+graphKit.hpp addnode.hpp
graphKit.hpp callnode.hpp
graphKit.hpp cfgnode.hpp
graphKit.hpp ciEnv.hpp
+graphKit.hpp divnode.hpp
graphKit.hpp compile.hpp
graphKit.hpp deoptimization.hpp
graphKit.hpp phaseX.hpp
+graphKit.hpp mulnode.hpp
+graphKit.hpp subnode.hpp
graphKit.hpp type.hpp
idealKit.cpp addnode.hpp
@@ -490,7 +496,10 @@
idealKit.cpp idealKit.hpp
idealKit.cpp runtime.hpp
+idealKit.hpp addnode.hpp
+idealKit.hpp cfgnode.hpp
idealKit.hpp connode.hpp
+idealKit.hpp divnode.hpp
idealKit.hpp mulnode.hpp
idealKit.hpp phaseX.hpp
idealKit.hpp subnode.hpp
@@ -641,6 +650,7 @@
macro.cpp callnode.hpp
macro.cpp cfgnode.hpp
macro.cpp compile.hpp
+macro.cpp compileLog.hpp
macro.cpp connode.hpp
macro.cpp locknode.hpp
macro.cpp loopnode.hpp
@@ -993,6 +1003,21 @@
split_if.cpp connode.hpp
split_if.cpp loopnode.hpp
+stringopts.hpp phaseX.hpp
+stringopts.hpp node.hpp
+
+stringopts.cpp addnode.hpp
+stringopts.cpp callnode.hpp
+stringopts.cpp callGenerator.hpp
+stringopts.cpp compileLog.hpp
+stringopts.cpp divnode.hpp
+stringopts.cpp idealKit.hpp
+stringopts.cpp graphKit.hpp
+stringopts.cpp rootnode.hpp
+stringopts.cpp runtime.hpp
+stringopts.cpp subnode.hpp
+stringopts.cpp stringopts.hpp
+
stubGenerator_<arch_model>.cpp runtime.hpp
stubRoutines.cpp runtime.hpp
--- a/hotspot/src/share/vm/includeDB_core Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/includeDB_core Wed Jul 05 17:04:56 2017 +0200
@@ -289,7 +289,7 @@
attachListener.hpp debug.hpp
attachListener.hpp ostream.hpp
-barrierSet.cpp barrierSet.hpp
+barrierSet.cpp barrierSet.inline.hpp
barrierSet.cpp collectedHeap.hpp
barrierSet.cpp universe.hpp
@@ -570,6 +570,7 @@
ciEnv.hpp dependencies.hpp
ciEnv.hpp exceptionHandlerTable.hpp
ciEnv.hpp oopMap.hpp
+ciEnv.hpp systemDictionary.hpp
ciEnv.hpp thread.hpp
ciExceptionHandler.cpp ciExceptionHandler.hpp
@@ -1291,6 +1292,7 @@
cpCacheOop.cpp markSweep.inline.hpp
cpCacheOop.cpp objArrayOop.hpp
cpCacheOop.cpp oop.inline.hpp
+cpCacheOop.cpp rewriter.hpp
cpCacheOop.cpp universe.inline.hpp
cpCacheOop.hpp allocation.hpp
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -281,7 +281,7 @@
#define DO_BACKEDGE_CHECKS(skip, branch_pc) \
if ((skip) <= 0) { \
- if (UseCompiler && UseLoopCounter) { \
+ if (UseLoopCounter) { \
bool do_OSR = UseOnStackReplacement; \
BACKEDGE_COUNT->increment(); \
if (do_OSR) do_OSR = BACKEDGE_COUNT->reached_InvocationLimit(); \
@@ -289,16 +289,12 @@
nmethod* osr_nmethod; \
OSR_REQUEST(osr_nmethod, branch_pc); \
if (osr_nmethod != NULL && osr_nmethod->osr_entry_bci() != InvalidOSREntryBci) { \
- intptr_t* buf; \
- CALL_VM(buf=SharedRuntime::OSR_migration_begin(THREAD), handle_exception); \
+ intptr_t* buf = SharedRuntime::OSR_migration_begin(THREAD); \
istate->set_msg(do_osr); \
istate->set_osr_buf((address)buf); \
istate->set_osr_entry(osr_nmethod->osr_entry()); \
return; \
} \
- } else { \
- INCR_INVOCATION_COUNT; \
- SAFEPOINT; \
} \
} /* UseCompiler ... */ \
INCR_INVOCATION_COUNT; \
@@ -1281,12 +1277,7 @@
jfloat f;
jdouble r;
f = STACK_FLOAT(-1);
-#ifdef IA64
- // IA64 gcc bug
- r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero;
-#else
r = (jdouble) f;
-#endif
MORE_STACK(-1); // POP
SET_STACK_DOUBLE(r, 1);
UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -282,18 +282,21 @@
constantPoolOop constants = method()->constants();
constantTag tag = constants->tag_at(i);
+ int nt_index = -1;
+
switch (tag.value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
case JVM_CONSTANT_Fieldref:
+ case JVM_CONSTANT_NameAndType:
break;
default:
st->print_cr(" bad tag=%d at %d", tag.value(), i);
return;
}
- symbolOop name = constants->name_ref_at(orig_i);
- symbolOop signature = constants->signature_ref_at(orig_i);
+ symbolOop name = constants->uncached_name_ref_at(i);
+ symbolOop signature = constants->uncached_signature_ref_at(i);
st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string());
}
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -314,6 +314,20 @@
break;
}
+ case Bytecodes::_invokedynamic: {
+ Thread *thread = Thread::current();
+ ResourceMark rm(thread);
+ methodHandle mh(thread, method);
+ type = Bytecode_invoke_at(mh, bci)->result_type(thread);
+ // since the cache entry might not be initialized:
+ // (NOT needed for the old calling convension)
+ if (!is_top_frame) {
+ int index = Bytes::get_native_u4(bcp+1);
+ method->constants()->cache()->entry_at(index)->set_parameter_size(callee_parameters);
+ }
+ break;
+ }
+
case Bytecodes::_ldc :
type = constant_pool_type( method, *(bcp+1) );
break;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -681,7 +681,7 @@
IRT_END
-// First time execution: Resolve symbols, create a permanent CallSiteImpl object.
+// First time execution: Resolve symbols, create a permanent CallSite object.
IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
ResourceMark rm(thread);
@@ -708,21 +708,16 @@
constantPoolHandle pool(thread, caller_method->constants());
pool->set_invokedynamic(); // mark header to flag active call sites
- int raw_index = four_byte_index(thread);
- assert(constantPoolCacheOopDesc::is_secondary_index(raw_index), "invokedynamic indexes marked specially");
-
- // there are two CPC entries that are of interest:
- int site_index = constantPoolCacheOopDesc::decode_secondary_index(raw_index);
- int main_index = pool->cache()->entry_at(site_index)->main_entry_index();
- // and there is one CP entry, a NameAndType:
- int nt_index = pool->map_instruction_operand_to_index(raw_index);
+ int site_index = four_byte_index(thread);
+ // there is a second CPC entries that is of interest; it caches signature info:
+ int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index();
// first resolve the signature to a MH.invoke methodOop
if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) {
JvmtiHideSingleStepping jhss(thread);
CallInfo info;
LinkResolver::resolve_invoke(info, Handle(), pool,
- raw_index, bytecode, CHECK);
+ site_index, bytecode, CHECK);
// The main entry corresponds to a JVM_CONSTANT_NameAndType, and serves
// as a common reference point for all invokedynamic call sites with
// that exact call descriptor. We will link it in the CP cache exactly
@@ -741,7 +736,7 @@
assert(mh_invdyn.not_null() && mh_invdyn->is_method() && mh_invdyn->is_method_handle_invoke(),
"correct result from LinkResolver::resolve_invokedynamic");
- symbolHandle call_site_name(THREAD, pool->nt_name_ref_at(nt_index));
+ symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index));
Handle call_site
= SystemDictionary::make_dynamic_call_site(caller_method->method_holder(),
caller_method->method_idnum(),
@@ -753,61 +748,11 @@
// In the secondary entry, the f1 field is the call site, and the f2 (index)
// field is some data about the invoke site.
int extra_data = 0;
- pool->cache()->entry_at(site_index)->set_dynamic_call(call_site(), extra_data);
+ pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site(), extra_data);
}
IRT_END
-// Called on first time execution, and also whenever the CallSite.target is null.
-// FIXME: Do more of this in Java code.
-IRT_ENTRY(void, InterpreterRuntime::bootstrap_invokedynamic(JavaThread* thread, oopDesc* call_site)) {
- methodHandle mh_invdyn(thread, (methodOop) sun_dyn_CallSiteImpl::vmmethod(call_site));
- Handle mh_type(thread, mh_invdyn->method_handle_type());
- objArrayHandle mh_ptypes(thread, java_dyn_MethodType::ptypes(mh_type()));
-
- // squish the arguments down to a single array
- int nargs = mh_ptypes->length();
- objArrayHandle arg_array;
- {
- objArrayOop aaoop = oopFactory::new_objArray(SystemDictionary::object_klass(), nargs, CHECK);
- arg_array = objArrayHandle(thread, aaoop);
- }
- frame fr = thread->last_frame();
- assert(fr.interpreter_frame_bcp() != NULL, "sanity");
- int tos_offset = 0;
- for (int i = nargs; --i >= 0; ) {
- intptr_t* slot_addr = fr.interpreter_frame_tos_at(tos_offset++);
- oop ptype = mh_ptypes->obj_at(i);
- oop arg = NULL;
- if (!java_lang_Class::is_primitive(ptype)) {
- arg = *(oop*) slot_addr;
- } else {
- BasicType bt = java_lang_Class::primitive_type(ptype);
- assert(frame::interpreter_frame_expression_stack_direction() < 0, "else reconsider this code");
- jvalue value;
- Interpreter::get_jvalue_in_slot(slot_addr, bt, &value);
- tos_offset += type2size[bt]-1;
- arg = java_lang_boxing_object::create(bt, &value, CHECK);
- // FIXME: These boxing objects are not canonicalized under
- // the Java autoboxing rules. They should be...
- // The best approach would be to push the arglist creation into Java.
- // The JVM should use a lower-level interface to communicate argument lists.
- }
- arg_array->obj_at_put(i, arg);
- }
-
- // now find the bootstrap method
- oop bootstrap_mh_oop = instanceKlass::cast(fr.interpreter_frame_method()->method_holder())->bootstrap_method();
- assert(bootstrap_mh_oop != NULL, "resolve_invokedynamic ensures a BSM");
-
- // return the bootstrap method and argument array via vm_result/_2
- thread->set_vm_result(bootstrap_mh_oop);
- thread->set_vm_result_2(arg_array());
-}
-IRT_END
-
-
-
//------------------------------------------------------------------------------------------------------------------------
// Miscellaneous
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -91,7 +91,6 @@
// Calls
static void resolve_invoke (JavaThread* thread, Bytecodes::Code bytecode);
static void resolve_invokedynamic(JavaThread* thread);
- static void bootstrap_invokedynamic(JavaThread* thread, oopDesc* call_site);
// Breakpoints
static void _breakpoint(JavaThread* thread, methodOopDesc* method, address bcp);
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1015,11 +1015,8 @@
// This guy is reached from InterpreterRuntime::resolve_invokedynamic.
- assert(constantPoolCacheOopDesc::is_secondary_index(raw_index), "must be secondary index");
- int nt_index = pool->map_instruction_operand_to_index(raw_index);
-
// At this point, we only need the signature, and can ignore the name.
- symbolHandle method_signature(THREAD, pool->nt_signature_ref_at(nt_index));
+ symbolHandle method_signature(THREAD, pool->signature_ref_at(raw_index)); // raw_index works directly
symbolHandle method_name = vmSymbolHandles::invoke_name();
KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -48,16 +48,6 @@
}
-int Rewriter::add_extra_cp_cache_entry(int main_entry) {
- // Hack: We put it on the map as an encoded value.
- // The only place that consumes this is ConstantPoolCacheEntry::set_initial_state
- int encoded = constantPoolCacheOopDesc::encode_secondary_index(main_entry);
- int plain_secondary_index = _cp_cache_map.append(encoded);
- return constantPoolCacheOopDesc::encode_secondary_index(plain_secondary_index);
-}
-
-
-
// Creates a constant pool cache given a CPC map
// This creates the constant pool cache initially in a state
// that is unsafe for concurrent GC processing but sets it to
@@ -127,7 +117,7 @@
assert(p[-1] == Bytecodes::_invokedynamic, "");
int cp_index = Bytes::get_Java_u2(p);
int cpc = maybe_add_cp_cache_entry(cp_index); // add lazily
- int cpc2 = add_extra_cp_cache_entry(cpc);
+ int cpc2 = add_secondary_cp_cache_entry(cpc);
// Replace the trailing four bytes with a CPC index for the dynamic
// call site. Unlike other CPC entries, there is one per bytecode,
@@ -137,7 +127,7 @@
// all these entries. That is the main reason invokedynamic
// must have a five-byte instruction format. (Of course, other JVM
// implementations can use the bytes for other purposes.)
- Bytes::put_native_u4(p, cpc2);
+ Bytes::put_native_u4(p, constantPoolCacheOopDesc::encode_secondary_index(cpc2));
// Note: We use native_u4 format exclusively for 4-byte indexes.
}
--- a/hotspot/src/share/vm/interpreter/rewriter.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/rewriter.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -43,13 +43,18 @@
bool has_cp_cache(int i) { return (uint)i < (uint)_cp_map.length() && _cp_map[i] >= 0; }
int maybe_add_cp_cache_entry(int i) { return has_cp_cache(i) ? _cp_map[i] : add_cp_cache_entry(i); }
int add_cp_cache_entry(int cp_index) {
+ assert((cp_index & _secondary_entry_tag) == 0, "bad tag");
assert(_cp_map[cp_index] == -1, "not twice on same cp_index");
int cache_index = _cp_cache_map.append(cp_index);
_cp_map.at_put(cp_index, cache_index);
assert(cp_entry_to_cp_cache(cp_index) == cache_index, "");
return cache_index;
}
- int add_extra_cp_cache_entry(int main_entry);
+ int add_secondary_cp_cache_entry(int main_cpc_entry) {
+ assert(main_cpc_entry < _cp_cache_map.length(), "must be earlier CP cache entry");
+ int cache_index = _cp_cache_map.append(main_cpc_entry | _secondary_entry_tag);
+ return cache_index;
+ }
// All the work goes in here:
Rewriter(instanceKlassHandle klass, TRAPS);
@@ -65,4 +70,8 @@
public:
// Driver routine:
static void rewrite(instanceKlassHandle klass, TRAPS);
+
+ enum {
+ _secondary_entry_tag = nth_bit(30)
+ };
};
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -178,14 +178,12 @@
#endif // !PRODUCT
EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries];
EntryPoint TemplateInterpreter::_earlyret_entry;
-EntryPoint TemplateInterpreter::_return_unbox_entry;
EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ];
EntryPoint TemplateInterpreter::_continuation_entry;
EntryPoint TemplateInterpreter::_safept_entry;
address TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
-address TemplateInterpreter::_return_5_unbox_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
DispatchTable TemplateInterpreter::_active_table;
DispatchTable TemplateInterpreter::_normal_table;
@@ -253,22 +251,6 @@
}
}
- if (EnableInvokeDynamic) {
- CodeletMark cm(_masm, "unboxing return entry points");
- Interpreter::_return_unbox_entry =
- EntryPoint(
- generate_return_unbox_entry_for(btos, 5),
- generate_return_unbox_entry_for(ctos, 5),
- generate_return_unbox_entry_for(stos, 5),
- generate_return_unbox_entry_for(atos, 5), // cast conversion
- generate_return_unbox_entry_for(itos, 5),
- generate_return_unbox_entry_for(ltos, 5),
- generate_return_unbox_entry_for(ftos, 5),
- generate_return_unbox_entry_for(dtos, 5),
- Interpreter::_return_entry[5].entry(vtos) // no unboxing for void
- );
- }
-
{ CodeletMark cm(_masm, "earlyret entry points");
Interpreter::_earlyret_entry =
EntryPoint(
@@ -319,8 +301,6 @@
int index = Interpreter::TosState_as_index(states[j]);
Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3);
Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5);
- if (EnableInvokeDynamic)
- Interpreter::_return_5_unbox_addrs_by_index[index] = Interpreter::return_unbox_entry(states[j], 5);
}
{ CodeletMark cm(_masm, "continuation entry points");
@@ -485,9 +465,11 @@
void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
assert(t->is_valid(), "template must exist");
switch (t->tos_in()) {
- case btos: vep = __ pc(); __ pop(btos); bep = __ pc(); generate_and_dispatch(t); break;
- case ctos: vep = __ pc(); __ pop(ctos); sep = __ pc(); generate_and_dispatch(t); break;
- case stos: vep = __ pc(); __ pop(stos); sep = __ pc(); generate_and_dispatch(t); break;
+ case btos:
+ case ctos:
+ case stos:
+ ShouldNotReachHere(); // btos/ctos/stos should use itos.
+ break;
case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
@@ -547,18 +529,6 @@
}
-address TemplateInterpreter::return_unbox_entry(TosState state, int length) {
- assert(EnableInvokeDynamic, "");
- if (state == vtos) {
- // no unboxing to do, actually
- return return_entry(state, length);
- } else {
- assert(length == 5, "unboxing entries generated for invokedynamic only");
- return _return_unbox_entry.entry(state);
- }
-}
-
-
address TemplateInterpreter::deopt_entry(TosState state, int length) {
guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length");
return _deopt_entry[length].entry(state);
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -110,14 +110,12 @@
#endif // !PRODUCT
static EntryPoint _return_entry[number_of_return_entries]; // entry points to return to from a call
static EntryPoint _earlyret_entry; // entry point to return early from a call
- static EntryPoint _return_unbox_entry; // entry point to unbox a return value from a call
static EntryPoint _deopt_entry[number_of_deopt_entries]; // entry points to return to from a deoptimization
static EntryPoint _continuation_entry;
static EntryPoint _safept_entry;
static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries
static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries
- static address _return_5_unbox_addrs_by_index[number_of_return_addrs]; // for invokedynamic bootstrap methods
static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch)
static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode)
@@ -159,12 +157,10 @@
// Support for invokes
static address* return_3_addrs_by_index_table() { return _return_3_addrs_by_index; }
static address* return_5_addrs_by_index_table() { return _return_5_addrs_by_index; }
- static address* return_5_unbox_addrs_by_index_table() { return _return_5_unbox_addrs_by_index; }
static int TosState_as_index(TosState state); // computes index into return_3_entry_by_index table
static address return_entry (TosState state, int length);
static address deopt_entry (TosState state, int length);
- static address return_unbox_entry(TosState state, int length);
// Safepoint support
static void notice_safepoints(); // stops the thread when reaching a safepoint
--- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -51,10 +51,7 @@
address generate_WrongMethodType_handler();
address generate_ArrayIndexOutOfBounds_handler(const char* name);
address generate_continuation_for(TosState state);
- address generate_return_entry_for(TosState state, int step, bool unbox = false);
- address generate_return_unbox_entry_for(TosState state, int step) {
- return generate_return_entry_for(state, step, true);
- }
+ address generate_return_entry_for(TosState state, int step);
address generate_earlyret_entry_for(TosState state);
address generate_deopt_entry_for(TosState state, int step);
address generate_safept_entry_for(TosState state, address runtime_entry);
--- a/hotspot/src/share/vm/memory/barrierSet.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/barrierSet.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -41,11 +41,6 @@
// count is number of array elements being written
void BarrierSet::static_write_ref_array_post(HeapWord* start, size_t count) {
- assert(count <= (size_t)max_intx, "count too large");
- HeapWord* end = start + objArrayOopDesc::array_size((int)count);
-#if 0
- warning("Post:\t" INTPTR_FORMAT "[" SIZE_FORMAT "] : [" INTPTR_FORMAT","INTPTR_FORMAT")\t",
- start, count, start, end);
-#endif
- Universe::heap()->barrier_set()->write_ref_array_work(MemRegion(start, end));
+ // simply delegate to instance method
+ Universe::heap()->barrier_set()->write_ref_array(start, count);
}
--- a/hotspot/src/share/vm/memory/barrierSet.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -121,17 +121,20 @@
virtual void read_ref_array(MemRegion mr) = 0;
virtual void read_prim_array(MemRegion mr) = 0;
+ // Below length is the # array elements being written
virtual void write_ref_array_pre( oop* dst, int length) {}
virtual void write_ref_array_pre(narrowOop* dst, int length) {}
+ // Below MemRegion mr is expected to be HeapWord-aligned
inline void write_ref_array(MemRegion mr);
+ // Below count is the # array elements being written, starting
+ // at the address "start", which may not necessarily be HeapWord-aligned
+ inline void write_ref_array(HeapWord* start, size_t count);
- // Static versions, suitable for calling from generated code.
+ // Static versions, suitable for calling from generated code;
+ // count is # array elements being written, starting with "start",
+ // which may not necessarily be HeapWord-aligned.
static void static_write_ref_array_pre(HeapWord* start, size_t count);
static void static_write_ref_array_post(HeapWord* start, size_t count);
- // Narrow oop versions of the above; count is # of array elements being written,
- // starting with "start", which is HeapWord-aligned.
- static void static_write_ref_array_pre_narrow(HeapWord* start, size_t count);
- static void static_write_ref_array_post_narrow(HeapWord* start, size_t count);
protected:
virtual void write_ref_array_work(MemRegion mr) = 0;
--- a/hotspot/src/share/vm/memory/barrierSet.inline.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/barrierSet.inline.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -43,6 +43,8 @@
}
void BarrierSet::write_ref_array(MemRegion mr) {
+ assert((HeapWord*)align_size_down((uintptr_t)mr.start(), HeapWordSize) == mr.start() , "Unaligned start");
+ assert((HeapWord*)align_size_up ((uintptr_t)mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
if (kind() == CardTableModRef) {
((CardTableModRefBS*)this)->inline_write_ref_array(mr);
} else {
@@ -50,6 +52,34 @@
}
}
+// count is number of array elements being written
+void BarrierSet::write_ref_array(HeapWord* start, size_t count) {
+ assert(count <= (size_t)max_intx, "count too large");
+ HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize));
+ // In the case of compressed oops, start and end may potentially be misaligned;
+ // so we need to conservatively align the first downward (this is not
+ // strictly necessary for current uses, but a case of good hygiene and,
+ // if you will, aesthetics) and the second upward (this is essential for
+ // current uses) to a HeapWord boundary, so we mark all cards overlapping
+ // this write. In the event that this evolves in the future to calling a
+ // logging barrier of narrow oop granularity, like the pre-barrier for G1
+ // (mentioned here merely by way of example), we will need to change this
+ // interface, much like the pre-barrier one above, so it is "exactly precise"
+ // (if i may be allowed the adverbial redundancy for emphasis) and does not
+ // include narrow oop slots not included in the original write interval.
+ HeapWord* aligned_start = (HeapWord*)align_size_down((uintptr_t)start, HeapWordSize);
+ HeapWord* aligned_end = (HeapWord*)align_size_up ((uintptr_t)end, HeapWordSize);
+ // If compressed oops were not being used, these should already be aligned
+ assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
+ "Expected heap word alignment of start and end");
+#if 0
+ warning("Post:\t" INTPTR_FORMAT "[" SIZE_FORMAT "] : [" INTPTR_FORMAT","INTPTR_FORMAT")\t",
+ start, count, aligned_start, aligned_end);
+#endif
+ write_ref_array_work(MemRegion(aligned_start, aligned_end));
+}
+
+
void BarrierSet::write_region(MemRegion mr) {
if (kind() == CardTableModRef) {
((CardTableModRefBS*)this)->inline_write_region(mr);
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -511,6 +511,8 @@
}
void CardTableModRefBS::dirty_MemRegion(MemRegion mr) {
+ assert((HeapWord*)align_size_down((uintptr_t)mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
+ assert((HeapWord*)align_size_up ((uintptr_t)mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
jbyte* cur = byte_for(mr.start());
jbyte* last = byte_after(mr.last());
while (cur < last) {
@@ -520,6 +522,8 @@
}
void CardTableModRefBS::invalidate(MemRegion mr, bool whole_heap) {
+ assert((HeapWord*)align_size_down((uintptr_t)mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
+ assert((HeapWord*)align_size_up ((uintptr_t)mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
for (int i = 0; i < _cur_covered_regions; i++) {
MemRegion mri = mr.intersection(_covered[i]);
if (!mri.is_empty()) dirty_MemRegion(mri);
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -55,7 +55,7 @@
void CollectorPolicy::initialize_size_info() {
// User inputs from -mx and ms are aligned
- set_initial_heap_byte_size(Arguments::initial_heap_size());
+ set_initial_heap_byte_size(InitialHeapSize);
if (initial_heap_byte_size() == 0) {
set_initial_heap_byte_size(NewSize + OldSize);
}
--- a/hotspot/src/share/vm/memory/heap.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/heap.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -464,7 +464,7 @@
}
// Verify that freelist contains the right amount of free space
- guarantee(len == _free_segments, "wrong freelist");
+ // guarantee(len == _free_segments, "wrong freelist");
// Verify that the number of free blocks is not out of hand.
static int free_block_threshold = 10000;
@@ -479,5 +479,5 @@
for(HeapBlock *h = first_block(); h != NULL; h = next_block(h)) {
if (h->free()) count--;
}
- guarantee(count == 0, "missing free blocks");
+ // guarantee(count == 0, "missing free blocks");
}
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -299,8 +299,8 @@
template <class T>
-static bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
- AbstractRefProcTaskExecutor* task_executor) {
+bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
+ AbstractRefProcTaskExecutor* task_executor) {
// Remember old value of pending references list
T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
--- a/hotspot/src/share/vm/memory/sharedHeap.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/sharedHeap.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -224,10 +224,6 @@
CodeBlobClosure* code_roots,
OopClosure* non_root_closure);
-
- // Like CollectedHeap::collect, but assume that the caller holds the Heap_lock.
- virtual void collect_locked(GCCause::Cause cause) = 0;
-
// The functions below are helper functions that a subclass of
// "SharedHeap" can use in the implementation of its virtual
// functions.
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -67,6 +67,8 @@
objArrayOop Universe::_the_empty_system_obj_array = NULL;
objArrayOop Universe::_the_empty_class_klass_array = NULL;
objArrayOop Universe::_the_array_interfaces_array = NULL;
+oop Universe::_the_null_string = NULL;
+oop Universe::_the_min_jint_string = NULL;
LatestMethodOopCache* Universe::_finalizer_register_cache = NULL;
LatestMethodOopCache* Universe::_loader_addClass_cache = NULL;
ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL;
@@ -187,6 +189,8 @@
f->do_oop((oop*)&_the_empty_system_obj_array);
f->do_oop((oop*)&_the_empty_class_klass_array);
f->do_oop((oop*)&_the_array_interfaces_array);
+ f->do_oop((oop*)&_the_null_string);
+ f->do_oop((oop*)&_the_min_jint_string);
_finalizer_register_cache->oops_do(f);
_loader_addClass_cache->oops_do(f);
_reflect_invoke_cache->oops_do(f);
@@ -289,6 +293,9 @@
klassOop ok = SystemDictionary::object_klass();
+ _the_null_string = StringTable::intern("null", CHECK);
+ _the_min_jint_string = StringTable::intern("-2147483648", CHECK);
+
if (UseSharedSpaces) {
// Verify shared interfaces array.
assert(_the_array_interfaces_array->obj_at(0) ==
@@ -744,22 +751,22 @@
static const uint64_t OopEncodingHeapMax = NarrowOopHeapMax << LogMinObjAlignmentInBytes;
char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
+ size_t base = 0;
#ifdef _LP64
if (UseCompressedOops) {
assert(mode == UnscaledNarrowOop ||
mode == ZeroBasedNarrowOop ||
mode == HeapBasedNarrowOop, "mode is invalid");
+ const size_t total_size = heap_size + HeapBaseMinAddress;
// Return specified base for the first request.
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
- return (char*)HeapBaseMinAddress;
- }
- const size_t total_size = heap_size + HeapBaseMinAddress;
- if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) {
+ base = HeapBaseMinAddress;
+ } else if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) {
if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) &&
(Universe::narrow_oop_shift() == 0)) {
// Use 32-bits oops without encoding and
// place heap's top on the 4Gb boundary
- return (char*)(NarrowOopHeapMax - heap_size);
+ base = (NarrowOopHeapMax - heap_size);
} else {
// Can't reserve with NarrowOopShift == 0
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
@@ -768,16 +775,38 @@
// Use zero based compressed oops with encoding and
// place heap's top on the 32Gb boundary in case
// total_size > 4Gb or failed to reserve below 4Gb.
- return (char*)(OopEncodingHeapMax - heap_size);
+ base = (OopEncodingHeapMax - heap_size);
}
}
} else {
// Can't reserve below 32Gb.
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
}
+ // Set narrow_oop_base and narrow_oop_use_implicit_null_checks
+ // used in ReservedHeapSpace() constructors.
+ // The final values will be set in initialize_heap() below.
+ if (base != 0 && (base + heap_size) <= OopEncodingHeapMax) {
+ // Use zero based compressed oops
+ Universe::set_narrow_oop_base(NULL);
+ // Don't need guard page for implicit checks in indexed
+ // addressing mode with zero based Compressed Oops.
+ Universe::set_narrow_oop_use_implicit_null_checks(true);
+ } else {
+ // Set to a non-NULL value so the ReservedSpace ctor computes
+ // the correct no-access prefix.
+ // The final value will be set in initialize_heap() below.
+ Universe::set_narrow_oop_base((address)NarrowOopHeapMax);
+#ifdef _WIN64
+ if (UseLargePages) {
+ // Cannot allocate guard pages for implicit checks in indexed
+ // addressing mode when large pages are specified on windows.
+ Universe::set_narrow_oop_use_implicit_null_checks(false);
+ }
+#endif // _WIN64
+ }
}
#endif
- return NULL; // also return NULL (don't care) for 32-bit VM
+ return (char*)base; // also return NULL (don't care) for 32-bit VM
}
jint Universe::initialize_heap() {
--- a/hotspot/src/share/vm/memory/universe.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -169,6 +169,8 @@
static objArrayOop _the_empty_system_obj_array; // Canonicalized system obj array
static objArrayOop _the_empty_class_klass_array; // Canonicalized obj array of type java.lang.Class
static objArrayOop _the_array_interfaces_array; // Canonicalized 2-array of cloneable & serializable klasses
+ static oop _the_null_string; // A cache of "null" as a Java string
+ static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string
static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects
static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks
@@ -310,6 +312,8 @@
static objArrayOop the_empty_system_obj_array () { return _the_empty_system_obj_array; }
static objArrayOop the_empty_class_klass_array () { return _the_empty_class_klass_array; }
static objArrayOop the_array_interfaces_array() { return _the_array_interfaces_array; }
+ static oop the_null_string() { return _the_null_string; }
+ static oop the_min_jint_string() { return _the_min_jint_string; }
static methodOop finalizer_register_method() { return _finalizer_register_cache->get_methodOop(); }
static methodOop loader_addClass_method() { return _loader_addClass_cache->get_methodOop(); }
static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; }
--- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -262,25 +262,48 @@
int constantPoolOopDesc::impl_name_and_type_ref_index_at(int which, bool uncached) {
- jint ref_index = field_or_method_at(which, uncached);
+ int i = which;
+ if (!uncached && cache() != NULL) {
+ if (constantPoolCacheOopDesc::is_secondary_index(which))
+ // Invokedynamic indexes are always processed in native order
+ // so there is no question of reading a native u2 in Java order here.
+ return cache()->main_entry_at(which)->constant_pool_index();
+ // change byte-ordering and go via cache
+ i = remap_instruction_operand_from_cache(which);
+ } else {
+ if (tag_at(which).is_name_and_type())
+ // invokedynamic index is a simple name-and-type
+ return which;
+ }
+ assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
+ jint ref_index = *int_at_addr(i);
return extract_high_short_from_int(ref_index);
}
int constantPoolOopDesc::impl_klass_ref_index_at(int which, bool uncached) {
- jint ref_index = field_or_method_at(which, uncached);
+ guarantee(!constantPoolCacheOopDesc::is_secondary_index(which),
+ "an invokedynamic instruction does not have a klass");
+ int i = which;
+ if (!uncached && cache() != NULL) {
+ // change byte-ordering and go via cache
+ i = remap_instruction_operand_from_cache(which);
+ }
+ assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
+ jint ref_index = *int_at_addr(i);
return extract_low_short_from_int(ref_index);
}
-int constantPoolOopDesc::map_instruction_operand_to_index(int operand) {
- if (constantPoolCacheOopDesc::is_secondary_index(operand)) {
- return cache()->main_entry_at(operand)->constant_pool_index();
- }
+int constantPoolOopDesc::remap_instruction_operand_from_cache(int operand) {
+ // Operand was fetched by a stream using get_Java_u2, yet was stored
+ // by Rewriter::rewrite_member_reference in native order.
+ // So now we have to fix the damage by swapping back to native order.
assert((int)(u2)operand == operand, "clean u2");
- int index = Bytes::swap_u2(operand);
- return cache()->entry_at(index)->constant_pool_index();
+ int cpc_index = Bytes::swap_u2(operand);
+ int member_index = cache()->entry_at(cpc_index)->constant_pool_index();
+ return member_index;
}
--- a/hotspot/src/share/vm/oops/constantPoolOop.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/constantPoolOop.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -342,12 +342,14 @@
}
// The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve,
- // name_and_type_ref_index_at) all expect constant pool indices
- // from the bytecodes to be passed in, which are actually potentially byte-swapped
- // or rewritten constant pool cache indices. They all call map_instruction_operand_to_index.
- int map_instruction_operand_to_index(int operand);
+ // name_and_type_ref_index_at) all expect to be passed indices obtained
+ // directly from the bytecode, and extracted according to java byte order.
+ // If the indices are meant to refer to fields or methods, they are
+ // actually potentially byte-swapped, rewritten constant pool cache indices.
+ // The routine remap_instruction_operand_from_cache manages the adjustment
+ // of these values back to constant pool indices.
- // There are also "uncached" versions which do not map the operand index; see below.
+ // There are also "uncached" versions which do not adjust the operand index; see below.
// Lookup for entries consisting of (klass_index, name_and_type index)
klassOop klass_ref_at(int which, TRAPS);
@@ -361,8 +363,6 @@
// Lookup for entries consisting of (name_index, signature_index)
int name_ref_index_at(int which_nt); // == low-order jshort of name_and_type_at(which_nt)
int signature_ref_index_at(int which_nt); // == high-order jshort of name_and_type_at(which_nt)
- symbolOop nt_name_ref_at(int which_nt) { return symbol_at(name_ref_index_at(which_nt)); }
- symbolOop nt_signature_ref_at(int which_nt) { return symbol_at(signature_ref_index_at(which_nt)); }
BasicType basic_type_for_signature_at(int which);
@@ -425,18 +425,7 @@
int impl_klass_ref_index_at(int which, bool uncached);
int impl_name_and_type_ref_index_at(int which, bool uncached);
- // Takes either a constant pool cache index in possibly byte-swapped
- // byte order (which comes from the bytecodes after rewriting) or,
- // if "uncached" is true, a vanilla constant pool index
- jint field_or_method_at(int which, bool uncached) {
- int i = which;
- if (!uncached && cache() != NULL) {
- // change byte-ordering and go via cache
- i = map_instruction_operand_to_index(which);
- }
- assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
- return *int_at_addr(i);
- }
+ int remap_instruction_operand_from_cache(int operand);
// Used while constructing constant pool (only by ClassFileParser)
jint klass_index_at(int which) {
--- a/hotspot/src/share/vm/oops/cpCacheOop.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -28,21 +28,17 @@
// Implememtation of ConstantPoolCacheEntry
-void ConstantPoolCacheEntry::set_initial_state(int index) {
- if (constantPoolCacheOopDesc::is_secondary_index(index)) {
- // Hack: The rewriter is trying to say that this entry itself
- // will be a secondary entry.
- int main_index = constantPoolCacheOopDesc::decode_secondary_index(index);
- assert(0 <= main_index && main_index < 0x10000, "sanity check");
- _indices = (main_index << 16);
- assert(main_entry_index() == main_index, "");
- return;
- }
+void ConstantPoolCacheEntry::initialize_entry(int index) {
assert(0 < index && index < 0x10000, "sanity check");
_indices = index;
assert(constant_pool_index() == index, "");
}
+void ConstantPoolCacheEntry::initialize_secondary_entry(int main_index) {
+ assert(0 <= main_index && main_index < 0x10000, "sanity check");
+ _indices = (main_index << 16);
+ assert(main_entry_index() == main_index, "");
+}
int ConstantPoolCacheEntry::as_flags(TosState state, bool is_final,
bool is_vfinal, bool is_volatile,
@@ -223,10 +219,10 @@
void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, int extra_data) {
- methodOop method = (methodOop) sun_dyn_CallSiteImpl::vmmethod(call_site());
+ methodOop method = (methodOop) java_dyn_CallSite::vmmethod(call_site());
assert(method->is_method(), "must be initialized properly");
int param_size = method->size_of_parameters();
- assert(param_size > 1, "method argument size must include MH.this & initial dynamic receiver");
+ assert(param_size >= 1, "method argument size must include MH.this");
param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic
if (Atomic::cmpxchg_ptr(call_site(), &_f1, NULL) == NULL) {
// racing threads might be trying to install their own favorites
@@ -439,7 +435,18 @@
void constantPoolCacheOopDesc::initialize(intArray& inverse_index_map) {
assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
- for (int i = 0; i < length(); i++) entry_at(i)->set_initial_state(inverse_index_map[i]);
+ for (int i = 0; i < length(); i++) {
+ ConstantPoolCacheEntry* e = entry_at(i);
+ int original_index = inverse_index_map[i];
+ if ((original_index & Rewriter::_secondary_entry_tag) != 0) {
+ int main_index = (original_index - Rewriter::_secondary_entry_tag);
+ assert(!entry_at(main_index)->is_secondary_entry(), "valid main index");
+ e->initialize_secondary_entry(main_index);
+ } else {
+ e->initialize_entry(original_index);
+ }
+ assert(entry_at(i) == e, "sanity");
+ }
}
// RedefineClasses() API support:
--- a/hotspot/src/share/vm/oops/cpCacheOop.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -154,7 +154,8 @@
};
// Initialization
- void set_initial_state(int index); // sets entry to initial state
+ void initialize_entry(int original_index); // initialize primary entry
+ void initialize_secondary_entry(int main_index); // initialize secondary entry
void set_field( // sets entry to resolved field state
Bytecodes::Code get_code, // the bytecode used for reading the field
@@ -251,6 +252,7 @@
// Code generation support
static WordSize size() { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); }
+ static ByteSize size_in_bytes() { return in_ByteSize(sizeof(ConstantPoolCacheEntry)); }
static ByteSize indices_offset() { return byte_offset_of(ConstantPoolCacheEntry, _indices); }
static ByteSize f1_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f1); }
static ByteSize f2_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f2); }
@@ -321,6 +323,7 @@
ConstantPoolCacheEntry* base() const { return (ConstantPoolCacheEntry*)((address)this + in_bytes(base_offset())); }
friend class constantPoolCacheKlass;
+ friend class ConstantPoolCacheEntry;
public:
// Initialization
@@ -329,7 +332,8 @@
// Secondary indexes.
// They must look completely different from normal indexes.
// The main reason is that byte swapping is sometimes done on normal indexes.
- // Also, it is helpful for debugging to tell the two apart.
+ // Also, some of the CP accessors do different things for secondary indexes.
+ // Finally, it is helpful for debugging to tell the two apart.
static bool is_secondary_index(int i) { return (i < 0); }
static int decode_secondary_index(int i) { assert(is_secondary_index(i), ""); return ~i; }
static int encode_secondary_index(int i) { assert(!is_secondary_index(i), ""); return ~i; }
@@ -337,18 +341,35 @@
// Accessors
void set_constant_pool(constantPoolOop pool) { oop_store_without_check((oop*)&_constant_pool, (oop)pool); }
constantPoolOop constant_pool() const { return _constant_pool; }
- ConstantPoolCacheEntry* entry_at(int i) const { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; }
+ // Fetches the entry at the given index.
+ // The entry may be either primary or secondary.
+ // In either case the index must not be encoded or byte-swapped in any way.
+ ConstantPoolCacheEntry* entry_at(int i) const {
+ assert(0 <= i && i < length(), "index out of bounds");
+ return base() + i;
+ }
+ // Fetches the secondary entry referred to by index.
+ // The index may be a secondary index, and must not be byte-swapped.
+ ConstantPoolCacheEntry* secondary_entry_at(int i) const {
+ int raw_index = i;
+ if (is_secondary_index(i)) { // correct these on the fly
+ raw_index = decode_secondary_index(i);
+ }
+ assert(entry_at(raw_index)->is_secondary_entry(), "not a secondary entry");
+ return entry_at(raw_index);
+ }
+ // Given a primary or secondary index, fetch the corresponding primary entry.
+ // Indirect through the secondary entry, if the index is encoded as a secondary index.
+ // The index must not be byte-swapped.
ConstantPoolCacheEntry* main_entry_at(int i) const {
- ConstantPoolCacheEntry* e;
+ int primary_index = i;
if (is_secondary_index(i)) {
// run through an extra level of indirection:
- i = decode_secondary_index(i);
- e = entry_at(i);
- i = e->main_entry_index();
+ int raw_index = decode_secondary_index(i);
+ primary_index = entry_at(raw_index)->main_entry_index();
}
- e = entry_at(i);
- assert(!e->is_secondary_entry(), "only one level of indirection");
- return e;
+ assert(!entry_at(primary_index)->is_secondary_entry(), "only one level of indirection");
+ return entry_at(primary_index);
}
// GC support
@@ -359,6 +380,12 @@
// Code generation
static ByteSize base_offset() { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
+ static ByteSize entry_offset(int raw_index) {
+ int index = raw_index;
+ if (is_secondary_index(raw_index))
+ index = decode_secondary_index(raw_index);
+ return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index);
+ }
// RedefineClasses() API support:
// If any entry of this constantPoolCache points to any of
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1556,13 +1556,13 @@
case Bytecodes::_getfield: do_field(true, false, itr->get_index_big(), itr->bci()); break;
case Bytecodes::_putfield: do_field(false, false, itr->get_index_big(), itr->bci()); break;
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokespecial: do_method(false, false, itr->get_index_big(), itr->bci()); break;
- case Bytecodes::_invokestatic: do_method(true, false, itr->get_index_big(), itr->bci()); break;
- case Bytecodes::_invokedynamic: do_method(false, true, itr->get_index_int(), itr->bci()); break;
- case Bytecodes::_invokeinterface: do_method(false, true, itr->get_index_big(), itr->bci()); break;
- case Bytecodes::_newarray:
- case Bytecodes::_anewarray: pp_new_ref(vCTS, itr->bci()); break;
+ case Bytecodes::_invokevirtual:
+ case Bytecodes::_invokespecial: do_method(false, false, itr->get_index_big(), itr->bci()); break;
+ case Bytecodes::_invokestatic: do_method(true, false, itr->get_index_big(), itr->bci()); break;
+ case Bytecodes::_invokedynamic: do_method(true, false, itr->get_index_int(), itr->bci()); break;
+ case Bytecodes::_invokeinterface: do_method(false, true, itr->get_index_big(), itr->bci()); break;
+ case Bytecodes::_newarray:
+ case Bytecodes::_anewarray: pp_new_ref(vCTS, itr->bci()); break;
case Bytecodes::_checkcast: do_checkcast(); break;
case Bytecodes::_arraylength:
case Bytecodes::_instanceof: pp(rCTS, vCTS); break;
@@ -1900,11 +1900,9 @@
}
void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
- // Dig up signature for field in constant pool
- constantPoolOop cp = _method->constants();
- int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);
- int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx); // @@@@@
- symbolOop signature = cp->symbol_at(signatureIdx);
+ // Dig up signature for field in constant pool
+ constantPoolOop cp = _method->constants();
+ symbolOop signature = cp->signature_ref_at(idx);
// Parse method signature
CellTypeState out[4];
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2045,8 +2045,9 @@
// As we walk along, look for equalities between outer1 and class2.
// Eventually, the walks will terminate as outer1 stops
// at the top-level class around the original class.
- symbolOop ignore_name;
- klassOop next = outer1->compute_enclosing_class(ignore_name, CHECK_false);
+ bool ignore_inner_is_member;
+ klassOop next = outer1->compute_enclosing_class(&ignore_inner_is_member,
+ CHECK_false);
if (next == NULL) break;
if (next == class2()) return true;
outer1 = instanceKlassHandle(THREAD, next);
@@ -2055,8 +2056,9 @@
// Now do the same for class2.
instanceKlassHandle outer2 = class2;
for (;;) {
- symbolOop ignore_name;
- klassOop next = outer2->compute_enclosing_class(ignore_name, CHECK_false);
+ bool ignore_inner_is_member;
+ klassOop next = outer2->compute_enclosing_class(&ignore_inner_is_member,
+ CHECK_false);
if (next == NULL) break;
// Might as well check the new outer against all available values.
if (next == class1()) return true;
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -337,12 +337,12 @@
static bool is_same_class_package(oop class_loader1, symbolOop class_name1, oop class_loader2, symbolOop class_name2);
// find an enclosing class (defined where original code was, in jvm.cpp!)
- klassOop compute_enclosing_class(symbolOop& simple_name_result, TRAPS) {
+ klassOop compute_enclosing_class(bool* inner_is_member, TRAPS) {
instanceKlassHandle self(THREAD, this->as_klassOop());
- return compute_enclosing_class_impl(self, simple_name_result, THREAD);
+ return compute_enclosing_class_impl(self, inner_is_member, THREAD);
}
static klassOop compute_enclosing_class_impl(instanceKlassHandle self,
- symbolOop& simple_name_result, TRAPS);
+ bool* inner_is_member, TRAPS);
// tell if two classes have the same enclosing class (at package level)
bool is_same_package_member(klassOop class2, TRAPS) {
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -317,6 +317,11 @@
pm->claim_or_forward_breadth(sg_addr);
}
+ oop* bsm_addr = ik->adr_bootstrap_method();
+ if (PSScavenge::should_scavenge(bsm_addr)) {
+ pm->claim_or_forward_breadth(bsm_addr);
+ }
+
klassKlass::oop_copy_contents(pm, obj);
}
@@ -345,6 +350,11 @@
pm->claim_or_forward_depth(sg_addr);
}
+ oop* bsm_addr = ik->adr_bootstrap_method();
+ if (PSScavenge::should_scavenge(bsm_addr)) {
+ pm->claim_or_forward_depth(bsm_addr);
+ }
+
klassKlass::oop_copy_contents(pm, obj);
}
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -78,9 +78,9 @@
#ifndef SERIALGC
template <class T>
-static void specialized_oop_follow_contents(instanceRefKlass* ref,
- ParCompactionManager* cm,
- oop obj) {
+void specialized_oop_follow_contents(instanceRefKlass* ref,
+ ParCompactionManager* cm,
+ oop obj) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr);
debug_only(
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -127,16 +127,14 @@
// pointer delta is scaled to number of elements (length field in
// objArrayOop) which we assume is 32 bit.
assert(pd == (size_t)(int)pd, "length field overflow");
- const size_t done_word_len = objArrayOopDesc::array_size((int)pd);
- bs->write_ref_array(MemRegion((HeapWord*)dst, done_word_len));
+ bs->write_ref_array((HeapWord*)dst, pd);
THROW(vmSymbols::java_lang_ArrayStoreException());
return;
}
}
}
}
- const size_t word_len = objArrayOopDesc::array_size(length);
- bs->write_ref_array(MemRegion((HeapWord*)dst, word_len));
+ bs->write_ref_array((HeapWord*)dst, length);
}
void objArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
--- a/hotspot/src/share/vm/oops/objArrayOop.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/objArrayOop.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -37,6 +37,32 @@
return &((T*)base())[index];
}
+private:
+ // Give size of objArrayOop in HeapWords minus the header
+ static int array_size(int length) {
+ const int OopsPerHeapWord = HeapWordSize/heapOopSize;
+ assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0),
+ "Else the following (new) computation would be in error");
+#ifdef ASSERT
+ // The old code is left in for sanity-checking; it'll
+ // go away pretty soon. XXX
+ // Without UseCompressedOops, this is simply:
+ // oop->length() * HeapWordsPerOop;
+ // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
+ // The oop elements are aligned up to wordSize
+ const int HeapWordsPerOop = heapOopSize/HeapWordSize;
+ int old_res;
+ if (HeapWordsPerOop > 0) {
+ old_res = length * HeapWordsPerOop;
+ } else {
+ old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord;
+ }
+#endif // ASSERT
+ int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
+ assert(res == old_res, "Inconsistency between old and new.");
+ return res;
+ }
+
public:
// Returns the offset of the first element.
static int base_offset_in_bytes() {
@@ -67,27 +93,14 @@
// Sizing
static int header_size() { return arrayOopDesc::header_size(T_OBJECT); }
int object_size() { return object_size(length()); }
- int array_size() { return array_size(length()); }
static int object_size(int length) {
// This returns the object size in HeapWords.
- return align_object_size(header_size() + array_size(length));
- }
-
- // Give size of objArrayOop in HeapWords minus the header
- static int array_size(int length) {
- // Without UseCompressedOops, this is simply:
- // oop->length() * HeapWordsPerOop;
- // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
- // The oop elements are aligned up to wordSize
- const int HeapWordsPerOop = heapOopSize/HeapWordSize;
- if (HeapWordsPerOop > 0) {
- return length * HeapWordsPerOop;
- } else {
- const int OopsPerHeapWord = HeapWordSize/heapOopSize;
- int word_len = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord;
- return word_len;
- }
+ uint asz = array_size(length);
+ uint osz = align_object_size(header_size() + asz);
+ assert(osz >= asz, "no overflow");
+ assert((int)osz > 0, "no overflow");
+ return (int)osz;
}
// special iterators for index ranges, returns size of object
--- a/hotspot/src/share/vm/oops/oop.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/oops/oop.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -30,13 +30,12 @@
// no virtual functions allowed
// store into oop with store check
-template <class T> void oop_store(T* p, oop v);
-template <class T> void oop_store(volatile T* p, oop v);
+template <class T> inline void oop_store(T* p, oop v);
+template <class T> inline void oop_store(volatile T* p, oop v);
// store into oop without store check
-template <class T> void oop_store_without_check(T* p, oop v);
-template <class T> void oop_store_without_check(volatile T* p, oop v);
-
+template <class T> inline void oop_store_without_check(T* p, oop v);
+template <class T> inline void oop_store_without_check(volatile T* p, oop v);
extern bool always_do_update_barrier;
--- a/hotspot/src/share/vm/opto/c2_globals.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -25,4 +25,4 @@
# include "incls/_precompiled.incl"
# include "incls/_c2_globals.cpp.incl"
-C2_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
+C2_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -26,7 +26,7 @@
// Defines all globals flags used by the server compiler.
//
-#define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+#define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct) \
\
notproduct(intx, CompileZapFirst, 0, \
"If +ZapDeadCompiledLocals, " \
@@ -394,6 +394,12 @@
product(bool, UseOptoBiasInlining, true, \
"Generate biased locking code in C2 ideal graph") \
\
+ product(bool, OptimizeStringConcat, false, \
+ "Optimize the construction of Strings by StringBuilder") \
+ \
+ notproduct(bool, PrintOptimizeStringConcat, false, \
+ "Print information about transformations performed on Strings") \
+ \
product(intx, ValueSearchLimit, 1000, \
"Recursion limit in PhaseMacroExpand::value_from_mem_phi") \
\
@@ -413,4 +419,4 @@
product(bool, BlockLayoutRotateLoops, true, \
"Allow back branches to be fall throughs in the block layour") \
-C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
+C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -98,12 +98,21 @@
//---------------------------DirectCallGenerator------------------------------
// Internal class which handles all out-of-line calls w/o receiver type checks.
class DirectCallGenerator : public CallGenerator {
-public:
- DirectCallGenerator(ciMethod* method)
- : CallGenerator(method)
+ private:
+ CallStaticJavaNode* _call_node;
+ // Force separate memory and I/O projections for the exceptional
+ // paths to facilitate late inlinig.
+ bool _separate_io_proj;
+
+ public:
+ DirectCallGenerator(ciMethod* method, bool separate_io_proj)
+ : CallGenerator(method),
+ _separate_io_proj(separate_io_proj)
{
}
virtual JVMState* generate(JVMState* jvms);
+
+ CallStaticJavaNode* call_node() const { return _call_node; }
};
JVMState* DirectCallGenerator::generate(JVMState* jvms) {
@@ -129,9 +138,10 @@
call->set_optimized_virtual(true);
}
kit.set_arguments_for_java_call(call);
- kit.set_edges_for_java_call(call);
- Node* ret = kit.set_results_for_java_call(call);
+ kit.set_edges_for_java_call(call, false, _separate_io_proj);
+ Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
kit.push_node(method()->return_type()->basic_type(), ret);
+ _call_node = call; // Save the call node in case we need it later
return kit.transfer_exceptions_into_jvms();
}
@@ -238,9 +248,9 @@
return new ParseGenerator(m, expected_uses, true);
}
-CallGenerator* CallGenerator::for_direct_call(ciMethod* m) {
+CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) {
assert(!m->is_abstract(), "for_direct_call mismatch");
- return new DirectCallGenerator(m);
+ return new DirectCallGenerator(m, separate_io_proj);
}
CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
@@ -248,6 +258,108 @@
return new VirtualCallGenerator(m, vtable_index);
}
+// Allow inlining decisions to be delayed
+class LateInlineCallGenerator : public DirectCallGenerator {
+ CallGenerator* _inline_cg;
+
+ public:
+ LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
+ DirectCallGenerator(method, true), _inline_cg(inline_cg) {}
+
+ virtual bool is_late_inline() const { return true; }
+
+ // Convert the CallStaticJava into an inline
+ virtual void do_late_inline();
+
+ JVMState* generate(JVMState* jvms) {
+ // Record that this call site should be revisited once the main
+ // parse is finished.
+ Compile::current()->add_late_inline(this);
+
+ // Emit the CallStaticJava and request separate projections so
+ // that the late inlining logic can distinguish between fall
+ // through and exceptional uses of the memory and io projections
+ // as is done for allocations and macro expansion.
+ return DirectCallGenerator::generate(jvms);
+ }
+
+};
+
+
+void LateInlineCallGenerator::do_late_inline() {
+ // Can't inline it
+ if (call_node() == NULL || call_node()->outcnt() == 0 ||
+ call_node()->in(0) == NULL || call_node()->in(0)->is_top())
+ return;
+
+ CallStaticJavaNode* call = call_node();
+
+ // Make a clone of the JVMState that appropriate to use for driving a parse
+ Compile* C = Compile::current();
+ JVMState* jvms = call->jvms()->clone_shallow(C);
+ uint size = call->req();
+ SafePointNode* map = new (C, size) SafePointNode(size, jvms);
+ for (uint i1 = 0; i1 < size; i1++) {
+ map->init_req(i1, call->in(i1));
+ }
+
+ // Make sure the state is a MergeMem for parsing.
+ if (!map->in(TypeFunc::Memory)->is_MergeMem()) {
+ map->set_req(TypeFunc::Memory, MergeMemNode::make(C, map->in(TypeFunc::Memory)));
+ }
+
+ // Make enough space for the expression stack and transfer the incoming arguments
+ int nargs = method()->arg_size();
+ jvms->set_map(map);
+ map->ensure_stack(jvms, jvms->method()->max_stack());
+ if (nargs > 0) {
+ for (int i1 = 0; i1 < nargs; i1++) {
+ map->set_req(i1 + jvms->argoff(), call->in(TypeFunc::Parms + i1));
+ }
+ }
+
+ CompileLog* log = C->log();
+ if (log != NULL) {
+ log->head("late_inline method='%d'", log->identify(method()));
+ JVMState* p = jvms;
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail("late_inline");
+ }
+
+ // Setup default node notes to be picked up by the inlining
+ Node_Notes* old_nn = C->default_node_notes();
+ if (old_nn != NULL) {
+ Node_Notes* entry_nn = old_nn->clone(C);
+ entry_nn->set_jvms(jvms);
+ C->set_default_node_notes(entry_nn);
+ }
+
+ // Now perform the inling using the synthesized JVMState
+ JVMState* new_jvms = _inline_cg->generate(jvms);
+ if (new_jvms == NULL) return; // no change
+ if (C->failing()) return;
+
+ // Capture any exceptional control flow
+ GraphKit kit(new_jvms);
+
+ // Find the result object
+ Node* result = C->top();
+ int result_size = method()->return_type()->size();
+ if (result_size != 0 && !kit.stopped()) {
+ result = (result_size == 1) ? kit.pop() : kit.pop_pair();
+ }
+
+ kit.replace_call(call, result);
+}
+
+
+CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) {
+ return new LateInlineCallGenerator(method, inline_cg);
+}
+
//---------------------------WarmCallGenerator--------------------------------
// Internal class which handles initial deferral of inlining decisions.
@@ -315,70 +427,7 @@
}
void WarmCallInfo::make_hot() {
- Compile* C = Compile::current();
- // Replace the callnode with something better.
- CallJavaNode* call = this->call()->as_CallJava();
- ciMethod* method = call->method();
- int nargs = method->arg_size();
- JVMState* jvms = call->jvms()->clone_shallow(C);
- uint size = TypeFunc::Parms + MAX2(2, nargs);
- SafePointNode* map = new (C, size) SafePointNode(size, jvms);
- for (uint i1 = 0; i1 < (uint)(TypeFunc::Parms + nargs); i1++) {
- map->init_req(i1, call->in(i1));
- }
- jvms->set_map(map);
- jvms->set_offsets(map->req());
- jvms->set_locoff(TypeFunc::Parms);
- jvms->set_stkoff(TypeFunc::Parms);
- GraphKit kit(jvms);
-
- JVMState* new_jvms = _hot_cg->generate(kit.jvms());
- if (new_jvms == NULL) return; // no change
- if (C->failing()) return;
-
- kit.set_jvms(new_jvms);
- Node* res = C->top();
- int res_size = method->return_type()->size();
- if (res_size != 0) {
- kit.inc_sp(-res_size);
- res = kit.argument(0);
- }
- GraphKit ekit(kit.combine_and_pop_all_exception_states()->jvms());
-
- // Replace the call:
- for (DUIterator i = call->outs(); call->has_out(i); i++) {
- Node* n = call->out(i);
- Node* nn = NULL; // replacement
- if (n->is_Proj()) {
- ProjNode* nproj = n->as_Proj();
- assert(nproj->_con < (uint)(TypeFunc::Parms + (res_size ? 1 : 0)), "sane proj");
- if (nproj->_con == TypeFunc::Parms) {
- nn = res;
- } else {
- nn = kit.map()->in(nproj->_con);
- }
- if (nproj->_con == TypeFunc::I_O) {
- for (DUIterator j = nproj->outs(); nproj->has_out(j); j++) {
- Node* e = nproj->out(j);
- if (e->Opcode() == Op_CreateEx) {
- e->replace_by(ekit.argument(0));
- } else if (e->Opcode() == Op_Catch) {
- for (DUIterator k = e->outs(); e->has_out(k); k++) {
- CatchProjNode* p = e->out(j)->as_CatchProj();
- if (p->is_handler_proj()) {
- p->replace_by(ekit.control());
- } else {
- p->replace_by(kit.control());
- }
- }
- }
- }
- }
- }
- NOT_PRODUCT(if (!nn) n->dump(2));
- assert(nn != NULL, "don't know what to do with this user");
- n->replace_by(nn);
- }
+ Unimplemented();
}
void WarmCallInfo::make_cold() {
--- a/hotspot/src/share/vm/opto/callGenerator.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -57,6 +57,13 @@
// is_trap: Does not return to the caller. (E.g., uncommon trap.)
virtual bool is_trap() const { return false; }
+ // is_late_inline: supports conversion of call into an inline
+ virtual bool is_late_inline() const { return false; }
+ // Replace the call with an inline version of the code
+ virtual void do_late_inline() { ShouldNotReachHere(); }
+
+ virtual CallStaticJavaNode* call_node() const { ShouldNotReachHere(); return NULL; }
+
// Note: It is possible for a CG to be both inline and virtual.
// (The hashCode intrinsic does a vtable check and an inlined fast path.)
@@ -92,9 +99,12 @@
static CallGenerator* for_osr(ciMethod* m, int osr_bci);
// How to generate vanilla out-of-line call sites:
- static CallGenerator* for_direct_call(ciMethod* m); // static, special
+ static CallGenerator* for_direct_call(ciMethod* m, bool separate_io_projs = false); // static, special
static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface
+ // How to generate a replace a direct call with an inline version
+ static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
+
// How to make a call but defer the decision whether to inline or not.
static CallGenerator* for_warm_call(WarmCallInfo* ci,
CallGenerator* if_cold,
--- a/hotspot/src/share/vm/opto/callnode.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -693,6 +693,84 @@
}
+void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj) {
+ projs->fallthrough_proj = NULL;
+ projs->fallthrough_catchproj = NULL;
+ projs->fallthrough_ioproj = NULL;
+ projs->catchall_ioproj = NULL;
+ projs->catchall_catchproj = NULL;
+ projs->fallthrough_memproj = NULL;
+ projs->catchall_memproj = NULL;
+ projs->resproj = NULL;
+ projs->exobj = NULL;
+
+ for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
+ ProjNode *pn = fast_out(i)->as_Proj();
+ if (pn->outcnt() == 0) continue;
+ switch (pn->_con) {
+ case TypeFunc::Control:
+ {
+ // For Control (fallthrough) and I_O (catch_all_index) we have CatchProj -> Catch -> Proj
+ projs->fallthrough_proj = pn;
+ DUIterator_Fast jmax, j = pn->fast_outs(jmax);
+ const Node *cn = pn->fast_out(j);
+ if (cn->is_Catch()) {
+ ProjNode *cpn = NULL;
+ for (DUIterator_Fast kmax, k = cn->fast_outs(kmax); k < kmax; k++) {
+ cpn = cn->fast_out(k)->as_Proj();
+ assert(cpn->is_CatchProj(), "must be a CatchProjNode");
+ if (cpn->_con == CatchProjNode::fall_through_index)
+ projs->fallthrough_catchproj = cpn;
+ else {
+ assert(cpn->_con == CatchProjNode::catch_all_index, "must be correct index.");
+ projs->catchall_catchproj = cpn;
+ }
+ }
+ }
+ break;
+ }
+ case TypeFunc::I_O:
+ if (pn->_is_io_use)
+ projs->catchall_ioproj = pn;
+ else
+ projs->fallthrough_ioproj = pn;
+ for (DUIterator j = pn->outs(); pn->has_out(j); j++) {
+ Node* e = pn->out(j);
+ if (e->Opcode() == Op_CreateEx && e->in(0)->is_CatchProj()) {
+ assert(projs->exobj == NULL, "only one");
+ projs->exobj = e;
+ }
+ }
+ break;
+ case TypeFunc::Memory:
+ if (pn->_is_io_use)
+ projs->catchall_memproj = pn;
+ else
+ projs->fallthrough_memproj = pn;
+ break;
+ case TypeFunc::Parms:
+ projs->resproj = pn;
+ break;
+ default:
+ assert(false, "unexpected projection from allocation node.");
+ }
+ }
+
+ // The resproj may not exist because the result couuld be ignored
+ // and the exception object may not exist if an exception handler
+ // swallows the exception but all the other must exist and be found.
+ assert(projs->fallthrough_proj != NULL, "must be found");
+ assert(projs->fallthrough_catchproj != NULL, "must be found");
+ assert(projs->fallthrough_memproj != NULL, "must be found");
+ assert(projs->fallthrough_ioproj != NULL, "must be found");
+ assert(projs->catchall_catchproj != NULL, "must be found");
+ if (separate_io_proj) {
+ assert(projs->catchall_memproj != NULL, "must be found");
+ assert(projs->catchall_ioproj != NULL, "must be found");
+ }
+}
+
+
//=============================================================================
uint CallJavaNode::size_of() const { return sizeof(*this); }
uint CallJavaNode::cmp( const Node &n ) const {
--- a/hotspot/src/share/vm/opto/callnode.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -470,6 +470,23 @@
#endif
};
+
+// Simple container for the outgoing projections of a call. Useful
+// for serious surgery on calls.
+class CallProjections : public StackObj {
+public:
+ Node* fallthrough_proj;
+ Node* fallthrough_catchproj;
+ Node* fallthrough_memproj;
+ Node* fallthrough_ioproj;
+ Node* catchall_catchproj;
+ Node* catchall_memproj;
+ Node* catchall_ioproj;
+ Node* resproj;
+ Node* exobj;
+};
+
+
//------------------------------CallNode---------------------------------------
// Call nodes now subsume the function of debug nodes at callsites, so they
// contain the functionality of a full scope chain of debug nodes.
@@ -521,6 +538,11 @@
// or returns NULL if there is no one.
Node *result_cast();
+ // Collect all the interesting edges from a call for use in
+ // replacing the call by something else. Used by macro expansion
+ // and the late inlining support.
+ void extract_projections(CallProjections* projs, bool separate_io_proj);
+
virtual uint match_edge(uint idx) const;
#ifndef PRODUCT
@@ -529,6 +551,7 @@
#endif
};
+
//------------------------------CallJavaNode-----------------------------------
// Make a static or dynamic subroutine call node using Java calling
// convention. (The "Java" calling convention is the compiler's calling
--- a/hotspot/src/share/vm/opto/compile.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -224,6 +224,32 @@
}
+void Compile::gvn_replace_by(Node* n, Node* nn) {
+ for (DUIterator_Last imin, i = n->last_outs(imin); i >= imin; ) {
+ Node* use = n->last_out(i);
+ bool is_in_table = initial_gvn()->hash_delete(use);
+ uint uses_found = 0;
+ for (uint j = 0; j < use->len(); j++) {
+ if (use->in(j) == n) {
+ if (j < use->req())
+ use->set_req(j, nn);
+ else
+ use->set_prec(j, nn);
+ uses_found++;
+ }
+ }
+ if (is_in_table) {
+ // reinsert into table
+ initial_gvn()->hash_find_insert(use);
+ }
+ record_for_igvn(use);
+ i -= uses_found; // we deleted 1 or more copies of this edge
+ }
+}
+
+
+
+
// Identify all nodes that are reachable from below, useful.
// Use breadth-first pass that records state in a Unique_Node_List,
// recursive traversal is slower.
@@ -554,6 +580,28 @@
rethrow_exceptions(kit.transfer_exceptions_into_jvms());
}
+ if (!failing() && has_stringbuilder()) {
+ {
+ // remove useless nodes to make the usage analysis simpler
+ ResourceMark rm;
+ PhaseRemoveUseless pru(initial_gvn(), &for_igvn);
+ }
+
+ {
+ ResourceMark rm;
+ print_method("Before StringOpts", 3);
+ PhaseStringOpts pso(initial_gvn(), &for_igvn);
+ print_method("After StringOpts", 3);
+ }
+
+ // now inline anything that we skipped the first time around
+ while (_late_inlines.length() > 0) {
+ CallGenerator* cg = _late_inlines.pop();
+ cg->do_late_inline();
+ }
+ }
+ assert(_late_inlines.length() == 0, "should have been processed");
+
print_method("Before RemoveUseless", 3);
// Remove clutter produced by parsing.
@@ -820,6 +868,7 @@
_fixed_slots = 0;
set_has_split_ifs(false);
set_has_loops(has_method() && method()->has_loops()); // first approximation
+ set_has_stringbuilder(false);
_deopt_happens = true; // start out assuming the worst
_trap_can_recompile = false; // no traps emitted yet
_major_progress = true; // start out assuming good things will happen
@@ -1803,6 +1852,7 @@
!n->is_Phi() && // a few noisely useless nodes
!n->is_Proj() &&
!n->is_MachTemp() &&
+ !n->is_SafePointScalarObject() &&
!n->is_Catch() && // Would be nice to print exception table targets
!n->is_MergeMem() && // Not very interesting
!n->is_top() && // Debug info table constants
@@ -2240,6 +2290,30 @@
break;
}
+ case Op_Proj: {
+ if (OptimizeStringConcat) {
+ ProjNode* p = n->as_Proj();
+ if (p->_is_io_use) {
+ // Separate projections were used for the exception path which
+ // are normally removed by a late inline. If it wasn't inlined
+ // then they will hang around and should just be replaced with
+ // the original one.
+ Node* proj = NULL;
+ // Replace with just one
+ for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) {
+ Node *use = i.get();
+ if (use->is_Proj() && p != use && use->as_Proj()->_con == p->_con) {
+ proj = use;
+ break;
+ }
+ }
+ assert(p != NULL, "must be found");
+ p->subsume_by(proj);
+ }
+ }
+ break;
+ }
+
case Op_Phi:
if (n->as_Phi()->bottom_type()->isa_narrowoop()) {
// The EncodeP optimization may create Phi with the same edges
--- a/hotspot/src/share/vm/opto/compile.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -149,6 +149,7 @@
bool _has_loops; // True if the method _may_ have some loops
bool _has_split_ifs; // True if the method _may_ have some split-if
bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores.
+ bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated
uint _trap_hist[trapHistLength]; // Cumulative traps
bool _trap_can_recompile; // Have we emitted a recompiling trap?
uint _decompile_count; // Cumulative decompilation counts.
@@ -219,6 +220,9 @@
Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN
WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining.
+ GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after
+ // main parsing has finished.
+
// Matching, CFG layout, allocation, code generation
PhaseCFG* _cfg; // Results of CFG finding
bool _select_24_bit_instr; // We selected an instruction with a 24-bit result
@@ -298,6 +302,8 @@
void set_has_split_ifs(bool z) { _has_split_ifs = z; }
bool has_unsafe_access() const { return _has_unsafe_access; }
void set_has_unsafe_access(bool z) { _has_unsafe_access = z; }
+ bool has_stringbuilder() const { return _has_stringbuilder; }
+ void set_has_stringbuilder(bool z) { _has_stringbuilder = z; }
void set_trap_count(uint r, uint c) { assert(r < trapHistLength, "oob"); _trap_hist[r] = c; }
uint trap_count(uint r) const { assert(r < trapHistLength, "oob"); return _trap_hist[r]; }
bool trap_can_recompile() const { return _trap_can_recompile; }
@@ -475,6 +481,7 @@
// Decide how to build a call.
// The profile factor is a discount to apply to this site's interp. profile.
CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor);
+ bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
// Report if there were too many traps at a current method and bci.
// Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded.
@@ -495,6 +502,11 @@
void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; }
void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; }
+ // Replace n by nn using initial_gvn, calling hash_delete and
+ // record_for_igvn as needed.
+ void gvn_replace_by(Node* n, Node* nn);
+
+
void identify_useful_nodes(Unique_Node_List &useful);
void remove_useless_nodes (Unique_Node_List &useful);
@@ -502,6 +514,9 @@
void set_warm_calls(WarmCallInfo* l) { _warm_calls = l; }
WarmCallInfo* pop_warm_call();
+ // Record this CallGenerator for inlining at the end of parsing.
+ void add_late_inline(CallGenerator* cg) { _late_inlines.push(cg); }
+
// Matching, CFG layout, allocation, code generation
PhaseCFG* cfg() { return _cfg; }
bool select_24_bit_instr() const { return _select_24_bit_instr; }
--- a/hotspot/src/share/vm/opto/doCall.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -128,6 +128,12 @@
if (allow_inline) {
CallGenerator* cg = CallGenerator::for_inline(call_method, expected_uses);
+ if (require_inline && cg != NULL && should_delay_inlining(call_method, jvms)) {
+ // Delay the inlining of this method to give us the
+ // opportunity to perform some high level optimizations
+ // first.
+ return CallGenerator::for_late_inline(call_method, cg);
+ }
if (cg == NULL) {
// Fall through.
} else if (require_inline || !InlineWarmCalls) {
@@ -225,10 +231,63 @@
} else {
// Class Hierarchy Analysis or Type Profile reveals a unique target,
// or it is a static or special call.
- return CallGenerator::for_direct_call(call_method);
+ return CallGenerator::for_direct_call(call_method, should_delay_inlining(call_method, jvms));
}
}
+// Return true for methods that shouldn't be inlined early so that
+// they are easier to analyze and optimize as intrinsics.
+bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
+ if (has_stringbuilder()) {
+
+ if ((call_method->holder() == C->env()->StringBuilder_klass() ||
+ call_method->holder() == C->env()->StringBuffer_klass()) &&
+ (jvms->method()->holder() == C->env()->StringBuilder_klass() ||
+ jvms->method()->holder() == C->env()->StringBuffer_klass())) {
+ // Delay SB calls only when called from non-SB code
+ return false;
+ }
+
+ switch (call_method->intrinsic_id()) {
+ case vmIntrinsics::_StringBuilder_void:
+ case vmIntrinsics::_StringBuilder_int:
+ case vmIntrinsics::_StringBuilder_String:
+ case vmIntrinsics::_StringBuilder_append_char:
+ case vmIntrinsics::_StringBuilder_append_int:
+ case vmIntrinsics::_StringBuilder_append_String:
+ case vmIntrinsics::_StringBuilder_toString:
+ case vmIntrinsics::_StringBuffer_void:
+ case vmIntrinsics::_StringBuffer_int:
+ case vmIntrinsics::_StringBuffer_String:
+ case vmIntrinsics::_StringBuffer_append_char:
+ case vmIntrinsics::_StringBuffer_append_int:
+ case vmIntrinsics::_StringBuffer_append_String:
+ case vmIntrinsics::_StringBuffer_toString:
+ case vmIntrinsics::_Integer_toString:
+ return true;
+
+ case vmIntrinsics::_String_String:
+ {
+ Node* receiver = jvms->map()->in(jvms->argoff() + 1);
+ if (receiver->is_Proj() && receiver->in(0)->is_CallStaticJava()) {
+ CallStaticJavaNode* csj = receiver->in(0)->as_CallStaticJava();
+ ciMethod* m = csj->method();
+ if (m != NULL &&
+ (m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString ||
+ m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString))
+ // Delay String.<init>(new SB())
+ return true;
+ }
+ return false;
+ }
+
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
// uncommon-trap call-sites where callee is unloaded, uninitialized or will not link
bool Parse::can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass* klass) {
--- a/hotspot/src/share/vm/opto/escape.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -537,11 +537,13 @@
}
const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
- // Do NOT remove the next call: ensure an new alias index is allocated
- // for the instance type
+ // Do NOT remove the next line: ensure a new alias index is allocated
+ // for the instance type. Note: C++ will not remove it since the call
+ // has side effect.
int alias_idx = _compile->get_alias_index(tinst);
igvn->set_type(addp, tinst);
// record the allocation in the node map
+ assert(ptnode_adr(addp->_idx)->_node != NULL, "should be registered");
set_map(addp->_idx, get_map(base->_idx));
// Set addp's Base and Address to 'base'.
@@ -617,9 +619,14 @@
const TypePtr *atype = C->get_adr_type(alias_idx);
result = PhiNode::make(orig_phi->in(0), NULL, Type::MEMORY, atype);
C->copy_node_notes_to(result, orig_phi);
- set_map_phi(orig_phi->_idx, result);
igvn->set_type(result, result->bottom_type());
record_for_optimizer(result);
+
+ debug_only(Node* pn = ptnode_adr(orig_phi->_idx)->_node;)
+ assert(pn == NULL || pn == orig_phi, "wrong node");
+ set_map(orig_phi->_idx, result);
+ ptnode_adr(orig_phi->_idx)->_node = orig_phi;
+
new_created = true;
return result;
}
@@ -710,6 +717,81 @@
}
//
+// Move memory users to their memory slices.
+//
+void ConnectionGraph::move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *igvn) {
+ Compile* C = _compile;
+
+ const TypePtr* tp = igvn->type(n->in(MemNode::Address))->isa_ptr();
+ assert(tp != NULL, "ptr type");
+ int alias_idx = C->get_alias_index(tp);
+ int general_idx = C->get_general_index(alias_idx);
+
+ // Move users first
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ Node* use = n->fast_out(i);
+ if (use->is_MergeMem()) {
+ MergeMemNode* mmem = use->as_MergeMem();
+ assert(n == mmem->memory_at(alias_idx), "should be on instance memory slice");
+ if (n != mmem->memory_at(general_idx) || alias_idx == general_idx) {
+ continue; // Nothing to do
+ }
+ // Replace previous general reference to mem node.
+ uint orig_uniq = C->unique();
+ Node* m = find_inst_mem(n, general_idx, orig_phis, igvn);
+ assert(orig_uniq == C->unique(), "no new nodes");
+ mmem->set_memory_at(general_idx, m);
+ --imax;
+ --i;
+ } else if (use->is_MemBar()) {
+ assert(!use->is_Initialize(), "initializing stores should not be moved");
+ if (use->req() > MemBarNode::Precedent &&
+ use->in(MemBarNode::Precedent) == n) {
+ // Don't move related membars.
+ record_for_optimizer(use);
+ continue;
+ }
+ tp = use->as_MemBar()->adr_type()->isa_ptr();
+ if (tp != NULL && C->get_alias_index(tp) == alias_idx ||
+ alias_idx == general_idx) {
+ continue; // Nothing to do
+ }
+ // Move to general memory slice.
+ uint orig_uniq = C->unique();
+ Node* m = find_inst_mem(n, general_idx, orig_phis, igvn);
+ assert(orig_uniq == C->unique(), "no new nodes");
+ igvn->hash_delete(use);
+ imax -= use->replace_edge(n, m);
+ igvn->hash_insert(use);
+ record_for_optimizer(use);
+ --i;
+#ifdef ASSERT
+ } else if (use->is_Mem()) {
+ if (use->Opcode() == Op_StoreCM && use->in(MemNode::OopStore) == n) {
+ // Don't move related cardmark.
+ continue;
+ }
+ // Memory nodes should have new memory input.
+ tp = igvn->type(use->in(MemNode::Address))->isa_ptr();
+ assert(tp != NULL, "ptr type");
+ int idx = C->get_alias_index(tp);
+ assert(get_map(use->_idx) != NULL || idx == alias_idx,
+ "Following memory nodes should have new memory input or be on the same memory slice");
+ } else if (use->is_Phi()) {
+ // Phi nodes should be split and moved already.
+ tp = use->as_Phi()->adr_type()->isa_ptr();
+ assert(tp != NULL, "ptr type");
+ int idx = C->get_alias_index(tp);
+ assert(idx == alias_idx, "Following Phi nodes should be on the same memory slice");
+ } else {
+ use->dump();
+ assert(false, "should not be here");
+#endif
+ }
+ }
+}
+
+//
// Search memory chain of "mem" to find a MemNode whose address
// is the specified alias index.
//
@@ -774,10 +856,18 @@
C->get_alias_index(result->as_Phi()->adr_type()) != alias_idx) {
Node *un = result->as_Phi()->unique_input(phase);
if (un != NULL) {
+ orig_phis.append_if_missing(result->as_Phi());
result = un;
} else {
break;
}
+ } else if (result->is_ClearArray()) {
+ if (!ClearArrayNode::step_through(&result, (uint)tinst->instance_id(), phase)) {
+ // Can not bypass initialization of the instance
+ // we are looking for.
+ break;
+ }
+ // Otherwise skip it (the call updated 'result' value).
} else if (result->Opcode() == Op_SCMemProj) {
assert(result->in(0)->is_LoadStore(), "sanity");
const Type *at = phase->type(result->in(0)->in(MemNode::Address));
@@ -807,7 +897,6 @@
return result;
}
-
//
// Convert the types of unescaped object to instance types where possible,
// propagate the new type information through the graph, and update memory
@@ -899,12 +988,13 @@
//
void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist) {
GrowableArray<Node *> memnode_worklist;
- GrowableArray<Node *> mergemem_worklist;
GrowableArray<PhiNode *> orig_phis;
+
PhaseGVN *igvn = _compile->initial_gvn();
uint new_index_start = (uint) _compile->num_alias_types();
- VectorSet visited(Thread::current()->resource_area());
- VectorSet ptset(Thread::current()->resource_area());
+ Arena* arena = Thread::current()->resource_area();
+ VectorSet visited(arena);
+ VectorSet ptset(arena);
// Phase 1: Process possible allocations from alloc_worklist.
@@ -980,6 +1070,8 @@
// - non-escaping
// - eligible to be a unique type
// - not determined to be ineligible by escape analysis
+ assert(ptnode_adr(alloc->_idx)->_node != NULL &&
+ ptnode_adr(n->_idx)->_node != NULL, "should be registered");
set_map(alloc->_idx, n);
set_map(n->_idx, alloc);
const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
@@ -1024,7 +1116,7 @@
alloc_worklist.append_if_missing(addp2);
}
alloc_worklist.append_if_missing(use);
- } else if (use->is_Initialize()) {
+ } else if (use->is_MemBar()) {
memnode_worklist.append_if_missing(use);
}
}
@@ -1034,10 +1126,12 @@
PointsTo(ptset, get_addp_base(n), igvn);
assert(ptset.Size() == 1, "AddP address is unique");
uint elem = ptset.getelem(); // Allocation node's index
- if (elem == _phantom_object)
+ if (elem == _phantom_object) {
+ assert(false, "escaped allocation");
continue; // Assume the value was set outside this method.
+ }
Node *base = get_map(elem); // CheckCastPP node
- if (!split_AddP(n, base, igvn)) continue; // wrong type
+ if (!split_AddP(n, base, igvn)) continue; // wrong type from dead path
tinst = igvn->type(base)->isa_oopptr();
} else if (n->is_Phi() ||
n->is_CheckCastPP() ||
@@ -1052,8 +1146,10 @@
PointsTo(ptset, n, igvn);
if (ptset.Size() == 1) {
uint elem = ptset.getelem(); // Allocation node's index
- if (elem == _phantom_object)
+ if (elem == _phantom_object) {
+ assert(false, "escaped allocation");
continue; // Assume the value was set outside this method.
+ }
Node *val = get_map(elem); // CheckCastPP node
TypeNode *tn = n->as_Type();
tinst = igvn->type(val)->isa_oopptr();
@@ -1068,8 +1164,7 @@
tn_t = tn_type->isa_oopptr();
}
- if (tn_t != NULL &&
- tinst->cast_to_instance_id(TypeOopPtr::InstanceBot)->higher_equal(tn_t)) {
+ if (tn_t != NULL && tinst->klass()->is_subtype_of(tn_t->klass())) {
if (tn_type->isa_narrowoop()) {
tn_type = tinst->make_narrowoop();
} else {
@@ -1081,33 +1176,25 @@
igvn->hash_insert(tn);
record_for_optimizer(n);
} else {
- continue; // wrong type
+ assert(tn_type == TypePtr::NULL_PTR ||
+ tn_t != NULL && !tinst->klass()->is_subtype_of(tn_t->klass()),
+ "unexpected type");
+ continue; // Skip dead path with different type
}
}
} else {
+ debug_only(n->dump();)
+ assert(false, "EA: unexpected node");
continue;
}
- // push users on appropriate worklist
+ // push allocation's users on appropriate worklist
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node *use = n->fast_out(i);
if(use->is_Mem() && use->in(MemNode::Address) == n) {
- memnode_worklist.append_if_missing(use);
- } else if (use->is_Initialize()) {
+ // Load/store to instance's field
memnode_worklist.append_if_missing(use);
- } else if (use->is_MergeMem()) {
- mergemem_worklist.append_if_missing(use);
- } else if (use->is_SafePoint() && tinst != NULL) {
- // Look for MergeMem nodes for calls which reference unique allocation
- // (through CheckCastPP nodes) even for debug info.
- Node* m = use->in(TypeFunc::Memory);
- uint iid = tinst->instance_id();
- while (m->is_Proj() && m->in(0)->is_SafePoint() &&
- m->in(0) != use && !m->in(0)->_idx != iid) {
- m = m->in(0)->in(TypeFunc::Memory);
- }
- if (m->is_MergeMem()) {
- mergemem_worklist.append_if_missing(m);
- }
+ } else if (use->is_MemBar()) {
+ memnode_worklist.append_if_missing(use);
} else if (use->is_AddP() && use->outcnt() > 0) { // No dead nodes
Node* addp2 = find_second_addp(use, n);
if (addp2 != NULL) {
@@ -1120,6 +1207,29 @@
use->is_DecodeN() ||
(use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) {
alloc_worklist.append_if_missing(use);
+#ifdef ASSERT
+ } else if (use->is_Mem()) {
+ assert(use->in(MemNode::Address) != n, "EA: missing allocation reference path");
+ } else if (use->is_MergeMem()) {
+ assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist");
+ } else if (use->is_SafePoint()) {
+ // Look for MergeMem nodes for calls which reference unique allocation
+ // (through CheckCastPP nodes) even for debug info.
+ Node* m = use->in(TypeFunc::Memory);
+ if (m->is_MergeMem()) {
+ assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist");
+ }
+ } else {
+ uint op = use->Opcode();
+ if (!(op == Op_CmpP || op == Op_Conv2B ||
+ op == Op_CastP2X || op == Op_StoreCM ||
+ op == Op_FastLock || op == Op_AryEq || op == Op_StrComp ||
+ op == Op_StrEquals || op == Op_StrIndexOf)) {
+ n->dump();
+ use->dump();
+ assert(false, "EA: missing allocation reference path");
+ }
+#endif
}
}
@@ -1137,19 +1247,16 @@
Node *n = memnode_worklist.pop();
if (visited.test_set(n->_idx))
continue;
- if (n->is_Phi()) {
- assert(n->as_Phi()->adr_type() != TypePtr::BOTTOM, "narrow memory slice required");
- // we don't need to do anything, but the users must be pushed if we haven't processed
- // this Phi before
- } else if (n->is_Initialize()) {
- // we don't need to do anything, but the users of the memory projection must be pushed
- n = n->as_Initialize()->proj_out(TypeFunc::Memory);
+ if (n->is_Phi() || n->is_ClearArray()) {
+ // we don't need to do anything, but the users must be pushed
+ } else if (n->is_MemBar()) { // Initialize, MemBar nodes
+ // we don't need to do anything, but the users must be pushed
+ n = n->as_MemBar()->proj_out(TypeFunc::Memory);
if (n == NULL)
continue;
} else {
assert(n->is_Mem(), "memory node required.");
Node *addr = n->in(MemNode::Address);
- assert(addr->is_AddP(), "AddP required");
const Type *addr_t = igvn->type(addr);
if (addr_t == Type::TOP)
continue;
@@ -1161,6 +1268,10 @@
return;
}
if (mem != n->in(MemNode::Memory)) {
+ // We delay the memory edge update since we need old one in
+ // MergeMem code below when instances memory slices are separated.
+ debug_only(Node* pn = ptnode_adr(n->_idx)->_node;)
+ assert(pn == NULL || pn == n, "wrong node");
set_map(n->_idx, mem);
ptnode_adr(n->_idx)->_node = n;
}
@@ -1181,36 +1292,55 @@
// push user on appropriate worklist
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node *use = n->fast_out(i);
- if (use->is_Phi()) {
+ if (use->is_Phi() || use->is_ClearArray()) {
memnode_worklist.append_if_missing(use);
} else if(use->is_Mem() && use->in(MemNode::Memory) == n) {
+ if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores
+ continue;
memnode_worklist.append_if_missing(use);
- } else if (use->is_Initialize()) {
+ } else if (use->is_MemBar()) {
memnode_worklist.append_if_missing(use);
+#ifdef ASSERT
+ } else if(use->is_Mem()) {
+ assert(use->in(MemNode::Memory) != n, "EA: missing memory path");
} else if (use->is_MergeMem()) {
- mergemem_worklist.append_if_missing(use);
+ assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist");
+ } else {
+ uint op = use->Opcode();
+ if (!(op == Op_StoreCM ||
+ (op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL &&
+ strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) ||
+ op == Op_AryEq || op == Op_StrComp ||
+ op == Op_StrEquals || op == Op_StrIndexOf)) {
+ n->dump();
+ use->dump();
+ assert(false, "EA: missing memory path");
+ }
+#endif
}
}
}
// Phase 3: Process MergeMem nodes from mergemem_worklist.
- // Walk each memory moving the first node encountered of each
+ // Walk each memory slice moving the first node encountered of each
// instance type to the the input corresponding to its alias index.
- while (mergemem_worklist.length() != 0) {
- Node *n = mergemem_worklist.pop();
- assert(n->is_MergeMem(), "MergeMem node required.");
- if (visited.test_set(n->_idx))
- continue;
- MergeMemNode *nmm = n->as_MergeMem();
+ uint length = _mergemem_worklist.length();
+ for( uint next = 0; next < length; ++next ) {
+ MergeMemNode* nmm = _mergemem_worklist.at(next);
+ assert(!visited.test_set(nmm->_idx), "should not be visited before");
// Note: we don't want to use MergeMemStream here because we only want to
- // scan inputs which exist at the start, not ones we add during processing.
+ // scan inputs which exist at the start, not ones we add during processing.
+ // Note 2: MergeMem may already contains instance memory slices added
+ // during find_inst_mem() call when memory nodes were processed above.
+ igvn->hash_delete(nmm);
uint nslices = nmm->req();
- igvn->hash_delete(nmm);
for (uint i = Compile::AliasIdxRaw+1; i < nslices; i++) {
Node* mem = nmm->in(i);
Node* cur = NULL;
if (mem == NULL || mem->is_top())
continue;
+ // First, update mergemem by moving memory nodes to corresponding slices
+ // if their type became more precise since this mergemem was created.
while (mem->is_Mem()) {
const Type *at = igvn->type(mem->in(MemNode::Address));
if (at != Type::TOP) {
@@ -1229,7 +1359,7 @@
}
nmm->set_memory_at(i, (cur != NULL) ? cur : mem);
// Find any instance of the current type if we haven't encountered
- // a value of the instance along the chain.
+ // already a memory slice of the instance along the memory chain.
for (uint ni = new_index_start; ni < new_index_end; ni++) {
if((uint)_compile->get_general_index(ni) == i) {
Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni);
@@ -1245,11 +1375,11 @@
}
// Find the rest of instances values
for (uint ni = new_index_start; ni < new_index_end; ni++) {
- const TypeOopPtr *tinst = igvn->C->get_adr_type(ni)->isa_oopptr();
+ const TypeOopPtr *tinst = _compile->get_adr_type(ni)->isa_oopptr();
Node* result = step_through_mergemem(nmm, ni, tinst);
if (result == nmm->base_memory()) {
// Didn't find instance memory, search through general slice recursively.
- result = nmm->memory_at(igvn->C->get_general_index(ni));
+ result = nmm->memory_at(_compile->get_general_index(ni));
result = find_inst_mem(result, ni, orig_phis, igvn);
if (_compile->failing()) {
return;
@@ -1259,41 +1389,6 @@
}
igvn->hash_insert(nmm);
record_for_optimizer(nmm);
-
- // Propagate new memory slices to following MergeMem nodes.
- for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
- Node *use = n->fast_out(i);
- if (use->is_Call()) {
- CallNode* in = use->as_Call();
- if (in->proj_out(TypeFunc::Memory) != NULL) {
- Node* m = in->proj_out(TypeFunc::Memory);
- for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) {
- Node* mm = m->fast_out(j);
- if (mm->is_MergeMem()) {
- mergemem_worklist.append_if_missing(mm);
- }
- }
- }
- if (use->is_Allocate()) {
- use = use->as_Allocate()->initialization();
- if (use == NULL) {
- continue;
- }
- }
- }
- if (use->is_Initialize()) {
- InitializeNode* in = use->as_Initialize();
- if (in->proj_out(TypeFunc::Memory) != NULL) {
- Node* m = in->proj_out(TypeFunc::Memory);
- for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) {
- Node* mm = m->fast_out(j);
- if (mm->is_MergeMem()) {
- mergemem_worklist.append_if_missing(mm);
- }
- }
- }
- }
- }
}
// Phase 4: Update the inputs of non-instance memory Phis and
@@ -1322,19 +1417,48 @@
}
// Update the memory inputs of MemNodes with the value we computed
- // in Phase 2.
+ // in Phase 2 and move stores memory users to corresponding memory slices.
+#ifdef ASSERT
+ visited.Clear();
+ Node_Stack old_mems(arena, _compile->unique() >> 2);
+#endif
for (uint i = 0; i < nodes_size(); i++) {
Node *nmem = get_map(i);
if (nmem != NULL) {
Node *n = ptnode_adr(i)->_node;
- if (n != NULL && n->is_Mem()) {
+ assert(n != NULL, "sanity");
+ if (n->is_Mem()) {
+#ifdef ASSERT
+ Node* old_mem = n->in(MemNode::Memory);
+ if (!visited.test_set(old_mem->_idx)) {
+ old_mems.push(old_mem, old_mem->outcnt());
+ }
+#endif
+ assert(n->in(MemNode::Memory) != nmem, "sanity");
+ if (!n->is_Load()) {
+ // Move memory users of a store first.
+ move_inst_mem(n, orig_phis, igvn);
+ }
+ // Now update memory input
igvn->hash_delete(n);
n->set_req(MemNode::Memory, nmem);
igvn->hash_insert(n);
record_for_optimizer(n);
+ } else {
+ assert(n->is_Allocate() || n->is_CheckCastPP() ||
+ n->is_AddP() || n->is_Phi(), "unknown node used for set_map()");
}
}
}
+#ifdef ASSERT
+ // Verify that memory was split correctly
+ while (old_mems.is_nonempty()) {
+ Node* old_mem = old_mems.node();
+ uint old_cnt = old_mems.index();
+ old_mems.pop();
+ assert(old_cnt = old_mem->outcnt(), "old mem could be lost");
+ }
+#endif
}
bool ConnectionGraph::has_candidates(Compile *C) {
@@ -1381,8 +1505,20 @@
ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
has_allocations = true;
}
- if(n->is_AddP())
- cg_worklist.append(n->_idx);
+ if(n->is_AddP()) {
+ // Collect address nodes which directly reference an allocation.
+ // Use them during stage 3 below to build initial connection graph
+ // field edges. Other field edges could be added after StoreP/LoadP
+ // nodes are processed during stage 4 below.
+ Node* base = get_addp_base(n);
+ if(base->is_Proj() && base->in(0)->is_Allocate()) {
+ cg_worklist.append(n->_idx);
+ }
+ } else if (n->is_MergeMem()) {
+ // Collect all MergeMem nodes to add memory slices for
+ // scalar replaceable objects in split_unique_types().
+ _mergemem_worklist.append(n->as_MergeMem());
+ }
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node* m = n->fast_out(i); // Get user
worklist_init.push(m);
@@ -1423,12 +1559,13 @@
}
}
- VectorSet ptset(Thread::current()->resource_area());
+ Arena* arena = Thread::current()->resource_area();
+ VectorSet ptset(arena);
GrowableArray<uint> deferred_edges;
- VectorSet visited(Thread::current()->resource_area());
+ VectorSet visited(arena);
- // 5. Remove deferred edges from the graph and collect
- // information needed for type splitting.
+ // 5. Remove deferred edges from the graph and adjust
+ // escape state of nonescaping objects.
cg_length = cg_worklist.length();
for( uint next = 0; next < cg_length; ++next ) {
int ni = cg_worklist.at(next);
@@ -1438,98 +1575,9 @@
remove_deferred(ni, &deferred_edges, &visited);
Node *n = ptn->_node;
if (n->is_AddP()) {
- // Search for objects which are not scalar replaceable.
- // Mark their escape state as ArgEscape to propagate the state
- // to referenced objects.
- // Note: currently there are no difference in compiler optimizations
- // for ArgEscape objects and NoEscape objects which are not
- // scalar replaceable.
-
- int offset = ptn->offset();
- Node *base = get_addp_base(n);
- ptset.Clear();
- PointsTo(ptset, base, igvn);
- int ptset_size = ptset.Size();
-
- // Check if a field's initializing value is recorded and add
- // a corresponding NULL field's value if it is not recorded.
- // Connection Graph does not record a default initialization by NULL
- // captured by Initialize node.
- //
- // Note: it will disable scalar replacement in some cases:
- //
- // Point p[] = new Point[1];
- // p[0] = new Point(); // Will be not scalar replaced
- //
- // but it will save us from incorrect optimizations in next cases:
- //
- // Point p[] = new Point[1];
- // if ( x ) p[0] = new Point(); // Will be not scalar replaced
- //
- // Without a control flow analysis we can't distinguish above cases.
- //
- if (offset != Type::OffsetBot && ptset_size == 1) {
- uint elem = ptset.getelem(); // Allocation node's index
- // It does not matter if it is not Allocation node since
- // only non-escaping allocations are scalar replaced.
- if (ptnode_adr(elem)->_node->is_Allocate() &&
- ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) {
- AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate();
- InitializeNode* ini = alloc->initialization();
- Node* value = NULL;
- if (ini != NULL) {
- BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
- Node* store = ini->find_captured_store(offset, type2aelembytes(ft), igvn);
- if (store != NULL && store->is_Store())
- value = store->in(MemNode::ValueIn);
- }
- if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
- // A field's initializing value was not recorded. Add NULL.
- uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
- add_pointsto_edge(ni, null_idx);
- }
- }
- }
-
- // An object is not scalar replaceable if the field which may point
- // to it has unknown offset (unknown element of an array of objects).
- //
- if (offset == Type::OffsetBot) {
- uint e_cnt = ptn->edge_count();
- for (uint ei = 0; ei < e_cnt; ei++) {
- uint npi = ptn->edge_target(ei);
- set_escape_state(npi, PointsToNode::ArgEscape);
- ptnode_adr(npi)->_scalar_replaceable = false;
- }
- }
-
- // Currently an object is not scalar replaceable if a LoadStore node
- // access its field since the field value is unknown after it.
- //
- bool has_LoadStore = false;
- for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
- Node *use = n->fast_out(i);
- if (use->is_LoadStore()) {
- has_LoadStore = true;
- break;
- }
- }
- // An object is not scalar replaceable if the address points
- // to unknown field (unknown element for arrays, offset is OffsetBot).
- //
- // Or the address may point to more then one object. This may produce
- // the false positive result (set scalar_replaceable to false)
- // since the flow-insensitive escape analysis can't separate
- // the case when stores overwrite the field's value from the case
- // when stores happened on different control branches.
- //
- if (ptset_size > 1 || ptset_size != 0 &&
- (has_LoadStore || offset == Type::OffsetBot)) {
- for( VectorSetI j(&ptset); j.test(); ++j ) {
- set_escape_state(j.elem, PointsToNode::ArgEscape);
- ptnode_adr(j.elem)->_scalar_replaceable = false;
- }
- }
+ // Search for objects which are not scalar replaceable
+ // and adjust their escape state.
+ verify_escape_state(ni, ptset, igvn);
}
}
}
@@ -1646,6 +1694,150 @@
return has_non_escaping_obj;
}
+// Search for objects which are not scalar replaceable.
+void ConnectionGraph::verify_escape_state(int nidx, VectorSet& ptset, PhaseTransform* phase) {
+ PointsToNode* ptn = ptnode_adr(nidx);
+ Node* n = ptn->_node;
+ assert(n->is_AddP(), "Should be called for AddP nodes only");
+ // Search for objects which are not scalar replaceable.
+ // Mark their escape state as ArgEscape to propagate the state
+ // to referenced objects.
+ // Note: currently there are no difference in compiler optimizations
+ // for ArgEscape objects and NoEscape objects which are not
+ // scalar replaceable.
+
+ Compile* C = _compile;
+
+ int offset = ptn->offset();
+ Node* base = get_addp_base(n);
+ ptset.Clear();
+ PointsTo(ptset, base, phase);
+ int ptset_size = ptset.Size();
+
+ // Check if a oop field's initializing value is recorded and add
+ // a corresponding NULL field's value if it is not recorded.
+ // Connection Graph does not record a default initialization by NULL
+ // captured by Initialize node.
+ //
+ // Note: it will disable scalar replacement in some cases:
+ //
+ // Point p[] = new Point[1];
+ // p[0] = new Point(); // Will be not scalar replaced
+ //
+ // but it will save us from incorrect optimizations in next cases:
+ //
+ // Point p[] = new Point[1];
+ // if ( x ) p[0] = new Point(); // Will be not scalar replaced
+ //
+ // Do a simple control flow analysis to distinguish above cases.
+ //
+ if (offset != Type::OffsetBot && ptset_size == 1) {
+ uint elem = ptset.getelem(); // Allocation node's index
+ // It does not matter if it is not Allocation node since
+ // only non-escaping allocations are scalar replaced.
+ if (ptnode_adr(elem)->_node->is_Allocate() &&
+ ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) {
+ AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate();
+ InitializeNode* ini = alloc->initialization();
+
+ // Check only oop fields.
+ const Type* adr_type = n->as_AddP()->bottom_type();
+ BasicType basic_field_type = T_INT;
+ if (adr_type->isa_instptr()) {
+ ciField* field = C->alias_type(adr_type->isa_instptr())->field();
+ if (field != NULL) {
+ basic_field_type = field->layout_type();
+ } else {
+ // Ignore non field load (for example, klass load)
+ }
+ } else if (adr_type->isa_aryptr()) {
+ const Type* elemtype = adr_type->isa_aryptr()->elem();
+ basic_field_type = elemtype->array_element_basic_type();
+ } else {
+ // Raw pointers are used for initializing stores so skip it.
+ assert(adr_type->isa_rawptr() && base->is_Proj() &&
+ (base->in(0) == alloc),"unexpected pointer type");
+ }
+ if (basic_field_type == T_OBJECT ||
+ basic_field_type == T_NARROWOOP ||
+ basic_field_type == T_ARRAY) {
+ Node* value = NULL;
+ if (ini != NULL) {
+ BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
+ Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase);
+ if (store != NULL && store->is_Store()) {
+ value = store->in(MemNode::ValueIn);
+ } else if (ptn->edge_count() > 0) { // Are there oop stores?
+ // Check for a store which follows allocation without branches.
+ // For example, a volatile field store is not collected
+ // by Initialize node. TODO: it would be nice to use idom() here.
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ store = n->fast_out(i);
+ if (store->is_Store() && store->in(0) != NULL) {
+ Node* ctrl = store->in(0);
+ while(!(ctrl == ini || ctrl == alloc || ctrl == NULL ||
+ ctrl == C->root() || ctrl == C->top() || ctrl->is_Region() ||
+ ctrl->is_IfTrue() || ctrl->is_IfFalse())) {
+ ctrl = ctrl->in(0);
+ }
+ if (ctrl == ini || ctrl == alloc) {
+ value = store->in(MemNode::ValueIn);
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
+ // A field's initializing value was not recorded. Add NULL.
+ uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
+ add_pointsto_edge(nidx, null_idx);
+ }
+ }
+ }
+ }
+
+ // An object is not scalar replaceable if the field which may point
+ // to it has unknown offset (unknown element of an array of objects).
+ //
+ if (offset == Type::OffsetBot) {
+ uint e_cnt = ptn->edge_count();
+ for (uint ei = 0; ei < e_cnt; ei++) {
+ uint npi = ptn->edge_target(ei);
+ set_escape_state(npi, PointsToNode::ArgEscape);
+ ptnode_adr(npi)->_scalar_replaceable = false;
+ }
+ }
+
+ // Currently an object is not scalar replaceable if a LoadStore node
+ // access its field since the field value is unknown after it.
+ //
+ bool has_LoadStore = false;
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ Node *use = n->fast_out(i);
+ if (use->is_LoadStore()) {
+ has_LoadStore = true;
+ break;
+ }
+ }
+ // An object is not scalar replaceable if the address points
+ // to unknown field (unknown element for arrays, offset is OffsetBot).
+ //
+ // Or the address may point to more then one object. This may produce
+ // the false positive result (set scalar_replaceable to false)
+ // since the flow-insensitive escape analysis can't separate
+ // the case when stores overwrite the field's value from the case
+ // when stores happened on different control branches.
+ //
+ if (ptset_size > 1 || ptset_size != 0 &&
+ (has_LoadStore || offset == Type::OffsetBot)) {
+ for( VectorSetI j(&ptset); j.test(); ++j ) {
+ set_escape_state(j.elem, PointsToNode::ArgEscape);
+ ptnode_adr(j.elem)->_scalar_replaceable = false;
+ }
+ }
+}
+
void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
switch (call->Opcode()) {
@@ -1657,6 +1849,7 @@
assert(false, "should be done already");
break;
#endif
+ case Op_CallLeaf:
case Op_CallLeafNoFP:
{
// Stub calls, objects do not escape but they are not scale replaceable.
@@ -1667,9 +1860,23 @@
const Type* at = d->field_at(i);
Node *arg = call->in(i)->uncast();
const Type *aat = phase->type(arg);
- if (!arg->is_top() && at->isa_ptr() && aat->isa_ptr()) {
+ if (!arg->is_top() && at->isa_ptr() && aat->isa_ptr() &&
+ ptnode_adr(arg->_idx)->escape_state() < PointsToNode::ArgEscape) {
+
assert(aat == Type::TOP || aat == TypePtr::NULL_PTR ||
aat->isa_ptr() != NULL, "expecting an Ptr");
+#ifdef ASSERT
+ if (!(call->Opcode() == Op_CallLeafNoFP &&
+ call->as_CallLeaf()->_name != NULL &&
+ (strstr(call->as_CallLeaf()->_name, "arraycopy") != 0) ||
+ 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
set_escape_state(arg->_idx, PointsToNode::ArgEscape);
if (arg->is_AddP()) {
//
@@ -1706,9 +1913,10 @@
for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
const Type* at = d->field_at(i);
int k = i - TypeFunc::Parms;
+ Node *arg = call->in(i)->uncast();
- if (at->isa_oopptr() != NULL) {
- Node *arg = call->in(i)->uncast();
+ if (at->isa_oopptr() != NULL &&
+ ptnode_adr(arg->_idx)->escape_state() < PointsToNode::ArgEscape) {
bool global_escapes = false;
bool fields_escapes = false;
@@ -1942,20 +2150,23 @@
record_for_optimizer(n);
_processed.set(n->_idx);
} else {
- // Have to process call's arguments first.
+ // Don't mark as processed since call's arguments have to be processed.
PointsToNode::NodeType nt = PointsToNode::UnknownType;
+ PointsToNode::EscapeState es = PointsToNode::UnknownEscape;
// Check if a call returns an object.
const TypeTuple *r = n->as_Call()->tf()->range();
- if (n->is_CallStaticJava() && r->cnt() > TypeFunc::Parms &&
+ if (r->cnt() > TypeFunc::Parms &&
+ r->field_at(TypeFunc::Parms)->isa_ptr() &&
n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
- // Note: use isa_ptr() instead of isa_oopptr() here because
- // the _multianewarray functions return a TypeRawPtr.
- if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
- nt = PointsToNode::JavaObject;
+ nt = PointsToNode::JavaObject;
+ if (!n->is_CallStaticJava()) {
+ // Since the called mathod is statically unknown assume
+ // the worst case that the returned value globally escapes.
+ es = PointsToNode::GlobalEscape;
}
}
- add_node(n, nt, PointsToNode::UnknownEscape, false);
+ add_node(n, nt, es, false);
}
return;
}
@@ -2088,18 +2299,27 @@
}
case Op_Proj:
{
- // we are only interested in the result projection from a call
+ // we are only interested in the oop result projection from a call
if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
- add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
- process_call_result(n->as_Proj(), phase);
- if (!_processed.test(n->_idx)) {
- // The call's result may need to be processed later if the call
- // returns it's argument and the argument is not processed yet.
- _delayed_worklist.push(n);
+ const TypeTuple *r = n->in(0)->as_Call()->tf()->range();
+ assert(r->cnt() > TypeFunc::Parms, "sanity");
+ if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
+ add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
+ int ti = n->in(0)->_idx;
+ // The call may not be registered yet (since not all its inputs are registered)
+ // if this is the projection from backbranch edge of Phi.
+ if (ptnode_adr(ti)->node_type() != PointsToNode::UnknownType) {
+ process_call_result(n->as_Proj(), phase);
+ }
+ if (!_processed.test(n->_idx)) {
+ // The call's result may need to be processed later if the call
+ // returns it's argument and the argument is not processed yet.
+ _delayed_worklist.push(n);
+ }
+ break;
}
- } else {
- _processed.set(n->_idx);
}
+ _processed.set(n->_idx);
break;
}
case Op_Return:
@@ -2160,6 +2380,15 @@
}
break;
}
+ case Op_AryEq:
+ case Op_StrComp:
+ case Op_StrEquals:
+ case Op_StrIndexOf:
+ {
+ // char[] arrays passed to string intrinsics are not scalar replaceable.
+ add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
+ break;
+ }
case Op_ThreadLocal:
{
add_node(n, PointsToNode::JavaObject, PointsToNode::ArgEscape, true);
@@ -2174,6 +2403,7 @@
void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) {
uint n_idx = n->_idx;
+ assert(ptnode_adr(n_idx)->_node != NULL, "node should be registered");
// Don't set processed bit for AddP, LoadP, StoreP since
// they may need more then one pass to process.
@@ -2211,6 +2441,7 @@
case Op_DecodeN:
{
int ti = n->in(1)->_idx;
+ assert(ptnode_adr(ti)->node_type() != PointsToNode::UnknownType, "all nodes should be registered");
if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
add_pointsto_edge(n_idx, ti);
} else {
@@ -2250,7 +2481,6 @@
#endif
Node* adr = n->in(MemNode::Address)->uncast();
- const Type *adr_type = phase->type(adr);
Node* adr_base;
if (adr->is_AddP()) {
adr_base = get_addp_base(adr);
@@ -2302,13 +2532,19 @@
}
case Op_Proj:
{
- // we are only interested in the result projection from a call
+ // we are only interested in the oop result projection from a call
if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
- process_call_result(n->as_Proj(), phase);
- assert(_processed.test(n_idx), "all call results should be processed");
- } else {
- assert(false, "Op_Proj");
+ assert(ptnode_adr(n->in(0)->_idx)->node_type() != PointsToNode::UnknownType,
+ "all nodes should be registered");
+ const TypeTuple *r = n->in(0)->as_Call()->tf()->range();
+ assert(r->cnt() > TypeFunc::Parms, "sanity");
+ if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
+ process_call_result(n->as_Proj(), phase);
+ assert(_processed.test(n_idx), "all call results should be processed");
+ break;
+ }
}
+ assert(false, "Op_Proj");
break;
}
case Op_Return:
@@ -2320,6 +2556,7 @@
}
#endif
int ti = n->in(TypeFunc::Parms)->_idx;
+ assert(ptnode_adr(ti)->node_type() != PointsToNode::UnknownType, "node should be registered");
if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
add_pointsto_edge(n_idx, ti);
} else {
@@ -2354,14 +2591,38 @@
}
break;
}
+ case Op_AryEq:
+ case Op_StrComp:
+ case Op_StrEquals:
+ case Op_StrIndexOf:
+ {
+ // char[] arrays passed to string intrinsic do not escape but
+ // they are not scalar replaceable. Adjust escape state for them.
+ // Start from in(2) edge since in(1) is memory edge.
+ for (uint i = 2; i < n->req(); i++) {
+ Node* adr = n->in(i)->uncast();
+ const Type *at = phase->type(adr);
+ if (!adr->is_top() && at->isa_ptr()) {
+ assert(at == Type::TOP || at == TypePtr::NULL_PTR ||
+ at->isa_ptr() != NULL, "expecting an Ptr");
+ if (adr->is_AddP()) {
+ adr = get_addp_base(adr);
+ }
+ // Mark as ArgEscape everything "adr" could point to.
+ set_escape_state(adr->_idx, PointsToNode::ArgEscape);
+ }
+ }
+ _processed.set(n_idx);
+ break;
+ }
case Op_ThreadLocal:
{
assert(false, "Op_ThreadLocal");
break;
}
default:
- ;
- // nothing to do
+ // This method should be called only for EA specific nodes.
+ ShouldNotReachHere();
}
}
--- a/hotspot/src/share/vm/opto/escape.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/escape.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -210,6 +210,8 @@
Unique_Node_List _delayed_worklist; // Nodes to be processed before
// the call build_connection_graph().
+ GrowableArray<MergeMemNode *> _mergemem_worklist; // List of all MergeMem nodes
+
VectorSet _processed; // Records which nodes have been
// processed.
@@ -289,7 +291,7 @@
bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
- Node *find_mem(Node *mem, int alias_idx, PhaseGVN *igvn);
+ void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *igvn);
Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
// Propagate unique types created for unescaped allocated objects
@@ -298,7 +300,6 @@
// manage entries in _node_map
void set_map(int idx, Node *n) { _node_map.map(idx, n); }
- void set_map_phi(int idx, PhiNode *p) { _node_map.map(idx, (Node *) p); }
Node *get_map(int idx) { return _node_map[idx]; }
PhiNode *get_map_phi(int idx) {
Node *phi = _node_map[idx];
@@ -315,6 +316,9 @@
// Set the escape state of a node
void set_escape_state(uint ni, PointsToNode::EscapeState es);
+ // Search for objects which are not scalar replaceable.
+ void verify_escape_state(int nidx, VectorSet& ptset, PhaseTransform* phase);
+
public:
ConnectionGraph(Compile *C);
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1351,8 +1351,8 @@
}
//------------------------------set_all_memory_call----------------------------
-void GraphKit::set_all_memory_call(Node* call) {
- Node* newmem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+void GraphKit::set_all_memory_call(Node* call, bool separate_io_proj) {
+ Node* newmem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory, separate_io_proj) );
set_all_memory(newmem);
}
@@ -1573,7 +1573,7 @@
//---------------------------set_edges_for_java_call---------------------------
// Connect a newly created call into the current JVMS.
// A return value node (if any) is returned from set_edges_for_java_call.
-void GraphKit::set_edges_for_java_call(CallJavaNode* call, bool must_throw) {
+void GraphKit::set_edges_for_java_call(CallJavaNode* call, bool must_throw, bool separate_io_proj) {
// Add the predefined inputs:
call->init_req( TypeFunc::Control, control() );
@@ -1595,13 +1595,13 @@
// Re-use the current map to produce the result.
set_control(_gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Control)));
- set_i_o( _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O )));
- set_all_memory_call(xcall);
+ set_i_o( _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O , separate_io_proj)));
+ set_all_memory_call(xcall, separate_io_proj);
//return xcall; // no need, caller already has it
}
-Node* GraphKit::set_results_for_java_call(CallJavaNode* call) {
+Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_proj) {
if (stopped()) return top(); // maybe the call folded up?
// Capture the return value, if any.
@@ -1614,8 +1614,15 @@
// Note: Since any out-of-line call can produce an exception,
// we always insert an I_O projection from the call into the result.
- make_slow_call_ex(call, env()->Throwable_klass(), false);
-
+ make_slow_call_ex(call, env()->Throwable_klass(), separate_io_proj);
+
+ if (separate_io_proj) {
+ // The caller requested separate projections be used by the fall
+ // through and exceptional paths, so replace the projections for
+ // the fall through path.
+ set_i_o(_gvn.transform( new (C, 1) ProjNode(call, TypeFunc::I_O) ));
+ set_all_memory(_gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ));
+ }
return ret;
}
@@ -1678,6 +1685,64 @@
}
}
+
+// Replace the call with the current state of the kit.
+void GraphKit::replace_call(CallNode* call, Node* result) {
+ JVMState* ejvms = NULL;
+ if (has_exceptions()) {
+ ejvms = transfer_exceptions_into_jvms();
+ }
+
+ SafePointNode* final_state = stop();
+
+ // Find all the needed outputs of this call
+ CallProjections callprojs;
+ call->extract_projections(&callprojs, true);
+
+ // Replace all the old call edges with the edges from the inlining result
+ C->gvn_replace_by(callprojs.fallthrough_catchproj, final_state->in(TypeFunc::Control));
+ C->gvn_replace_by(callprojs.fallthrough_memproj, final_state->in(TypeFunc::Memory));
+ C->gvn_replace_by(callprojs.fallthrough_ioproj, final_state->in(TypeFunc::I_O));
+
+ // Replace the result with the new result if it exists and is used
+ if (callprojs.resproj != NULL && result != NULL) {
+ C->gvn_replace_by(callprojs.resproj, result);
+ }
+
+ if (ejvms == NULL) {
+ // No exception edges to simply kill off those paths
+ C->gvn_replace_by(callprojs.catchall_catchproj, C->top());
+ C->gvn_replace_by(callprojs.catchall_memproj, C->top());
+ C->gvn_replace_by(callprojs.catchall_ioproj, C->top());
+
+ // Replace the old exception object with top
+ if (callprojs.exobj != NULL) {
+ C->gvn_replace_by(callprojs.exobj, C->top());
+ }
+ } else {
+ GraphKit ekit(ejvms);
+
+ // Load my combined exception state into the kit, with all phis transformed:
+ SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
+
+ Node* ex_oop = ekit.use_exception_state(ex_map);
+
+ C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control());
+ C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory());
+ C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o());
+
+ // Replace the old exception object with the newly created one
+ if (callprojs.exobj != NULL) {
+ C->gvn_replace_by(callprojs.exobj, ex_oop);
+ }
+ }
+
+ // Disconnect the call from the graph
+ call->disconnect_inputs(NULL);
+ C->gvn_replace_by(call, C->top());
+}
+
+
//------------------------------increment_counter------------------------------
// for statistics: increment a VM counter by 1
@@ -3459,4 +3524,3 @@
sync_kit(ideal);
}
#undef __
-
--- a/hotspot/src/share/vm/opto/graphKit.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -279,6 +279,34 @@
}
Node* basic_plus_adr(Node* base, Node* ptr, Node* offset);
+
+ // Some convenient shortcuts for common nodes
+ Node* IfTrue(IfNode* iff) { return _gvn.transform(new (C,1) IfTrueNode(iff)); }
+ Node* IfFalse(IfNode* iff) { return _gvn.transform(new (C,1) IfFalseNode(iff)); }
+
+ Node* AddI(Node* l, Node* r) { return _gvn.transform(new (C,3) AddINode(l, r)); }
+ Node* SubI(Node* l, Node* r) { return _gvn.transform(new (C,3) SubINode(l, r)); }
+ Node* MulI(Node* l, Node* r) { return _gvn.transform(new (C,3) MulINode(l, r)); }
+ Node* DivI(Node* ctl, Node* l, Node* r) { return _gvn.transform(new (C,3) DivINode(ctl, l, r)); }
+
+ Node* AndI(Node* l, Node* r) { return _gvn.transform(new (C,3) AndINode(l, r)); }
+ Node* OrI(Node* l, Node* r) { return _gvn.transform(new (C,3) OrINode(l, r)); }
+ Node* XorI(Node* l, Node* r) { return _gvn.transform(new (C,3) XorINode(l, r)); }
+
+ Node* MaxI(Node* l, Node* r) { return _gvn.transform(new (C,3) MaxINode(l, r)); }
+ Node* MinI(Node* l, Node* r) { return _gvn.transform(new (C,3) MinINode(l, r)); }
+
+ Node* LShiftI(Node* l, Node* r) { return _gvn.transform(new (C,3) LShiftINode(l, r)); }
+ Node* RShiftI(Node* l, Node* r) { return _gvn.transform(new (C,3) RShiftINode(l, r)); }
+ Node* URShiftI(Node* l, Node* r) { return _gvn.transform(new (C,3) URShiftINode(l, r)); }
+
+ Node* CmpI(Node* l, Node* r) { return _gvn.transform(new (C,3) CmpINode(l, r)); }
+ Node* CmpL(Node* l, Node* r) { return _gvn.transform(new (C,3) CmpLNode(l, r)); }
+ Node* CmpP(Node* l, Node* r) { return _gvn.transform(new (C,3) CmpPNode(l, r)); }
+ Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C,2) BoolNode(cmp, relop)); }
+
+ Node* AddP(Node* b, Node* a, Node* o) { return _gvn.transform(new (C,4) AddPNode(b, a, o)); }
+
// Convert between int and long, and size_t.
// (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.)
Node* ConvI2L(Node* offset);
@@ -400,7 +428,7 @@
void set_all_memory(Node* newmem);
// Create a memory projection from the call, then set_all_memory.
- void set_all_memory_call(Node* call);
+ void set_all_memory_call(Node* call, bool separate_io_proj = false);
// Create a LoadNode, reading from the parser's memory state.
// (Note: require_atomic_access is useful only with T_LONG.)
@@ -543,12 +571,12 @@
// Transform the call, and update the basics: control, i_o, memory.
// (The next step is usually to call set_results_for_java_call.)
void set_edges_for_java_call(CallJavaNode* call,
- bool must_throw = false);
+ bool must_throw = false, bool separate_io_proj = false);
// Finish up a java call that was started by set_edges_for_java_call.
// Call add_exception on any throw arising from the call.
// Return the call result (transformed).
- Node* set_results_for_java_call(CallJavaNode* call);
+ Node* set_results_for_java_call(CallJavaNode* call, bool separate_io_proj = false);
// Similar to set_edges_for_java_call, but simplified for runtime calls.
void set_predefined_output_for_runtime_call(Node* call) {
@@ -559,6 +587,11 @@
const TypePtr* hook_mem);
Node* set_predefined_input_for_runtime_call(SafePointNode* call);
+ // Replace the call with the current state of the kit. Requires
+ // that the call was generated with separate io_projs so that
+ // exceptional control flow can be handled properly.
+ void replace_call(CallNode* call, Node* result);
+
// helper functions for statistics
void increment_counter(address counter_addr); // increment a debug counter
void increment_counter(Node* counter_addr); // increment a debug counter
--- a/hotspot/src/share/vm/opto/lcm.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -616,8 +616,9 @@
assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
}
}
- if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire &&
- n->req() > TypeFunc::Parms ) {
+ if( n->is_Mach() && n->req() > TypeFunc::Parms &&
+ (n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ||
+ n->as_Mach()->ideal_Opcode() == Op_MemBarVolatile) ) {
// MemBarAcquire could be created without Precedent edge.
// del_req() replaces the specified edge with the last input edge
// and then removes the last edge. If the specified edge > number of
--- a/hotspot/src/share/vm/opto/loopnode.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1279,7 +1279,8 @@
// Visit all children, looking for Phis
for (DUIterator i = cl->outs(); cl->has_out(i); i++) {
Node *out = cl->out(i);
- if (!out->is_Phi() || out == phi) continue; // Looking for other phis
+ // Look for other phis (secondary IVs). Skip dead ones
+ if (!out->is_Phi() || out == phi || !phase->has_node(out)) continue;
PhiNode* phi2 = out->as_Phi();
Node *incr2 = phi2->in( LoopNode::LoopBackControl );
// Look for induction variables of the form: X += constant
--- a/hotspot/src/share/vm/opto/macro.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -316,6 +316,21 @@
assert(adr_idx == Compile::AliasIdxRaw, "address must match or be raw");
}
mem = mem->in(MemNode::Memory);
+ } else if (mem->is_ClearArray()) {
+ if (!ClearArrayNode::step_through(&mem, alloc->_idx, phase)) {
+ // Can not bypass initialization of the instance
+ // we are looking.
+ debug_only(intptr_t offset;)
+ assert(alloc == AllocateNode::Ideal_allocation(mem->in(3), phase, offset), "sanity");
+ InitializeNode* init = alloc->as_Allocate()->initialization();
+ // We are looking for stored value, return Initialize node
+ // or memory edge from Allocate node.
+ if (init != NULL)
+ return init;
+ else
+ return alloc->in(TypeFunc::Memory); // It will produce zero value (see callers).
+ }
+ // Otherwise skip it (the call updated 'mem' value).
} else if (mem->Opcode() == Op_SCMemProj) {
assert(mem->in(0)->is_LoadStore(), "sanity");
const TypePtr* atype = mem->in(0)->in(MemNode::Address)->bottom_type()->is_ptr();
@@ -823,6 +838,18 @@
Node *n = use->last_out(k);
uint oc2 = use->outcnt();
if (n->is_Store()) {
+#ifdef ASSERT
+ // Verify that there is no dependent MemBarVolatile nodes,
+ // they should be removed during IGVN, see MemBarNode::Ideal().
+ for (DUIterator_Fast pmax, p = n->fast_outs(pmax);
+ p < pmax; p++) {
+ Node* mb = n->fast_out(p);
+ assert(mb->is_Initialize() || !mb->is_MemBar() ||
+ mb->req() <= MemBarNode::Precedent ||
+ mb->in(MemBarNode::Precedent) != n,
+ "MemBarVolatile should be eliminated for non-escaping object");
+ }
+#endif
_igvn.replace_node(n, n->in(MemNode::Memory));
} else {
eliminate_card_mark(n);
@@ -912,15 +939,29 @@
return false;
}
+ CompileLog* log = C->log();
+ if (log != NULL) {
+ Node* klass = alloc->in(AllocateNode::KlassNode);
+ const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
+ log->head("eliminate_allocation type='%d'",
+ log->identify(tklass->klass()));
+ JVMState* p = alloc->jvms();
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail("eliminate_allocation");
+ }
+
process_users_of_allocation(alloc);
#ifndef PRODUCT
-if (PrintEliminateAllocations) {
- if (alloc->is_AllocateArray())
- tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx);
- else
- tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx);
-}
+ if (PrintEliminateAllocations) {
+ if (alloc->is_AllocateArray())
+ tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx);
+ else
+ tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx);
+ }
#endif
return true;
@@ -1639,6 +1680,18 @@
} // if (!oldbox->is_eliminated())
} // if (alock->is_Lock() && !lock->is_coarsened())
+ CompileLog* log = C->log();
+ if (log != NULL) {
+ log->head("eliminate_lock lock='%d'",
+ alock->is_Lock());
+ JVMState* p = alock->jvms();
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail("eliminate_lock");
+ }
+
#ifndef PRODUCT
if (PrintEliminateLocks) {
if (alock->is_Lock()) {
--- a/hotspot/src/share/vm/opto/matcher.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1832,67 +1832,23 @@
case Op_Binary: // These are introduced in the Post_Visit state.
ShouldNotReachHere();
break;
- case Op_StoreB: // Do match these, despite no ideal reg
- case Op_StoreC:
- case Op_StoreCM:
- case Op_StoreD:
- case Op_StoreF:
- case Op_StoreI:
- case Op_StoreL:
- case Op_StoreP:
- case Op_StoreN:
- case Op_Store16B:
- case Op_Store8B:
- case Op_Store4B:
- case Op_Store8C:
- case Op_Store4C:
- case Op_Store2C:
- case Op_Store4I:
- case Op_Store2I:
- case Op_Store2L:
- case Op_Store4F:
- case Op_Store2F:
- case Op_Store2D:
case Op_ClearArray:
case Op_SafePoint:
mem_op = true;
break;
- case Op_LoadB:
- case Op_LoadUS:
- case Op_LoadD:
- case Op_LoadF:
- case Op_LoadI:
- case Op_LoadKlass:
- case Op_LoadNKlass:
- case Op_LoadL:
- case Op_LoadS:
- case Op_LoadP:
- case Op_LoadN:
- case Op_LoadRange:
- case Op_LoadD_unaligned:
- case Op_LoadL_unaligned:
- case Op_Load16B:
- case Op_Load8B:
- case Op_Load4B:
- case Op_Load4C:
- case Op_Load2C:
- case Op_Load8C:
- case Op_Load8S:
- case Op_Load4S:
- case Op_Load2S:
- case Op_Load4I:
- case Op_Load2I:
- case Op_Load2L:
- case Op_Load4F:
- case Op_Load2F:
- case Op_Load2D:
- mem_op = true;
- // Must be root of match tree due to prior load conflict
- if( C->subsume_loads() == false ) {
- set_shared(n);
+ default:
+ if( n->is_Store() ) {
+ // Do match stores, despite no ideal reg
+ mem_op = true;
+ break;
+ }
+ if( n->is_Mem() ) { // Loads and LoadStores
+ mem_op = true;
+ // Loads must be root of match tree due to prior load conflict
+ if( C->subsume_loads() == false )
+ set_shared(n);
}
// Fall into default case
- default:
if( !n->ideal_reg() )
set_dontcare(n); // Unmatchable Nodes
} // end_switch
@@ -1913,15 +1869,15 @@
continue; // for(int i = ...)
}
- // Clone addressing expressions as they are "free" in most instructions
+ if( mop == Op_AddP && m->in(AddPNode::Base)->Opcode() == Op_DecodeN ) {
+ // Bases used in addresses must be shared but since
+ // they are shared through a DecodeN they may appear
+ // to have a single use so force sharing here.
+ set_shared(m->in(AddPNode::Base)->in(1));
+ }
+
+ // Clone addressing expressions as they are "free" in memory access instructions
if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
- if (m->in(AddPNode::Base)->Opcode() == Op_DecodeN) {
- // Bases used in addresses must be shared but since
- // they are shared through a DecodeN they may appear
- // to have a single use so force sharing here.
- set_shared(m->in(AddPNode::Base)->in(1));
- }
-
// Some inputs for address expression are not put on stack
// to avoid marking them as shared and forcing them into register
// if they are used only in address expressions.
--- a/hotspot/src/share/vm/opto/memnode.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -123,6 +123,13 @@
} else {
assert(false, "unexpected projection");
}
+ } else if (result->is_ClearArray()) {
+ if (!ClearArrayNode::step_through(&result, instance_id, phase)) {
+ // Can not bypass initialization of the instance
+ // we are looking for.
+ break;
+ }
+ // Otherwise skip it (the call updated 'result' value).
} else if (result->is_MergeMem()) {
result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
}
@@ -255,6 +262,13 @@
return NodeSentinel; // caller will return NULL
}
+ // Do NOT remove or optimize the next lines: ensure a new alias index
+ // is allocated for an oop pointer type before Escape Analysis.
+ // Note: C++ will not remove it since the call has side effect.
+ if ( t_adr->isa_oopptr() ) {
+ int alias_idx = phase->C->get_alias_index(t_adr->is_ptr());
+ }
+
#ifdef ASSERT
Node* base = NULL;
if (address->is_AddP())
@@ -530,6 +544,15 @@
} else if (mem->is_Proj() && mem->in(0)->is_MemBar()) {
mem = mem->in(0)->in(TypeFunc::Memory);
continue; // (a) advance through independent MemBar memory
+ } else if (mem->is_ClearArray()) {
+ if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) {
+ // (the call updated 'mem' value)
+ continue; // (a) advance through independent allocation memory
+ } else {
+ // Can not bypass initialization of the instance
+ // we are looking for.
+ return mem;
+ }
} else if (mem->is_MergeMem()) {
int alias_idx = phase->C->get_alias_index(adr_type());
mem = mem->as_MergeMem()->memory_at(alias_idx);
@@ -1496,6 +1519,8 @@
}
}
} else if (tp->base() == Type::InstPtr) {
+ const TypeInstPtr* tinst = tp->is_instptr();
+ ciKlass* klass = tinst->klass();
assert( off != Type::OffsetBot ||
// arrays can be cast to Objects
tp->is_oopptr()->klass()->is_java_lang_Object() ||
@@ -1503,6 +1528,25 @@
phase->C->has_unsafe_access(),
"Field accesses must be precise" );
// For oop loads, we expect the _type to be precise
+ if (OptimizeStringConcat && klass == phase->C->env()->String_klass() &&
+ adr->is_AddP() && off != Type::OffsetBot) {
+ // For constant Strings treat the fields as compile time constants.
+ Node* base = adr->in(AddPNode::Base);
+ if (base->Opcode() == Op_ConP) {
+ const TypeOopPtr* t = phase->type(base)->isa_oopptr();
+ ciObject* string = t->const_oop();
+ ciConstant constant = string->as_instance()->field_value_by_offset(off);
+ if (constant.basic_type() == T_INT) {
+ return TypeInt::make(constant.as_int());
+ } else if (constant.basic_type() == T_ARRAY) {
+ if (adr->bottom_type()->is_ptr_to_narrowoop()) {
+ return TypeNarrowOop::make_from_constant(constant.as_object());
+ } else {
+ return TypeOopPtr::make_from_constant(constant.as_object());
+ }
+ }
+ }
+ }
} else if (tp->base() == Type::KlassPtr) {
assert( off != Type::OffsetBot ||
// arrays can be cast to Objects
@@ -2426,6 +2470,31 @@
return mem;
}
+//----------------------------step_through----------------------------------
+// Return allocation input memory edge if it is different instance
+// or itself if it is the one we are looking for.
+bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) {
+ Node* n = *np;
+ assert(n->is_ClearArray(), "sanity");
+ intptr_t offset;
+ AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset);
+ // This method is called only before Allocate nodes are expanded during
+ // macro nodes expansion. Before that ClearArray nodes are only generated
+ // in LibraryCallKit::generate_arraycopy() which follows allocations.
+ assert(alloc != NULL, "should have allocation");
+ if (alloc->_idx == instance_id) {
+ // Can not bypass initialization of the instance we are looking for.
+ return false;
+ }
+ // Otherwise skip it.
+ InitializeNode* init = alloc->initialization();
+ if (init != NULL)
+ *np = init->in(TypeFunc::Memory);
+ else
+ *np = alloc->in(TypeFunc::Memory);
+ return true;
+}
+
//----------------------------clear_memory-------------------------------------
// Generate code to initialize object storage to zero.
Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
@@ -2599,7 +2668,30 @@
// Return a node which is more "ideal" than the current node. Strip out
// control copies
Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
- return remove_dead_region(phase, can_reshape) ? this : NULL;
+ if (remove_dead_region(phase, can_reshape)) return this;
+
+ // Eliminate volatile MemBars for scalar replaced objects.
+ if (can_reshape && req() == (Precedent+1) &&
+ (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) {
+ // Volatile field loads and stores.
+ Node* my_mem = in(MemBarNode::Precedent);
+ if (my_mem != NULL && my_mem->is_Mem()) {
+ const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
+ // Check for scalar replaced object reference.
+ if( t_oop != NULL && t_oop->is_known_instance_field() &&
+ t_oop->offset() != Type::OffsetBot &&
+ t_oop->offset() != Type::OffsetTop) {
+ // Replace MemBar projections by its inputs.
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
+ igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
+ // Must return either the original node (now dead) or a new node
+ // (Do not return a top here, since that would break the uniqueness of top.)
+ return new (phase->C, 1) ConINode(TypeInt::ZERO);
+ }
+ }
+ }
+ return NULL;
}
//------------------------------Value------------------------------------------
--- a/hotspot/src/share/vm/opto/memnode.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -717,7 +717,10 @@
//------------------------------ClearArray-------------------------------------
class ClearArrayNode: public Node {
public:
- ClearArrayNode( Node *ctrl, Node *arymem, Node *word_cnt, Node *base ) : Node(ctrl,arymem,word_cnt,base) {}
+ ClearArrayNode( Node *ctrl, Node *arymem, Node *word_cnt, Node *base )
+ : Node(ctrl,arymem,word_cnt,base) {
+ init_class_id(Class_ClearArray);
+ }
virtual int Opcode() const;
virtual const Type *bottom_type() const { return Type::MEMORY; }
// ClearArray modifies array elements, and so affects only the
@@ -743,6 +746,9 @@
Node* start_offset,
Node* end_offset,
PhaseGVN* phase);
+ // Return allocation input memory edge if it is different instance
+ // or itself if it is the one we are looking for.
+ static bool step_through(Node** np, uint instance_id, PhaseTransform* phase);
};
//------------------------------StrComp-------------------------------------
--- a/hotspot/src/share/vm/opto/node.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/node.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -47,6 +47,7 @@
class CatchNode;
class CatchProjNode;
class CheckCastPPNode;
+class ClearArrayNode;
class CmpNode;
class CodeBuffer;
class ConstraintCastNode;
@@ -599,8 +600,9 @@
DEFINE_CLASS_ID(BoxLock, Node, 10)
DEFINE_CLASS_ID(Add, Node, 11)
DEFINE_CLASS_ID(Mul, Node, 12)
+ DEFINE_CLASS_ID(ClearArray, Node, 13)
- _max_classes = ClassMask_Mul
+ _max_classes = ClassMask_ClearArray
};
#undef DEFINE_CLASS_ID
@@ -661,18 +663,25 @@
return (_flags & Flag_is_Call) != 0;
}
+ CallNode* isa_Call() const {
+ return is_Call() ? as_Call() : NULL;
+ }
+
CallNode *as_Call() const { // Only for CallNode (not for MachCallNode)
assert((_class_id & ClassMask_Call) == Class_Call, "invalid node class");
return (CallNode*)this;
}
- #define DEFINE_CLASS_QUERY(type) \
- bool is_##type() const { \
+ #define DEFINE_CLASS_QUERY(type) \
+ bool is_##type() const { \
return ((_class_id & ClassMask_##type) == Class_##type); \
- } \
- type##Node *as_##type() const { \
- assert(is_##type(), "invalid node class"); \
- return (type##Node*)this; \
+ } \
+ type##Node *as_##type() const { \
+ assert(is_##type(), "invalid node class"); \
+ return (type##Node*)this; \
+ } \
+ type##Node* isa_##type() const { \
+ return (is_##type()) ? as_##type() : NULL; \
}
DEFINE_CLASS_QUERY(AbstractLock)
@@ -691,6 +700,7 @@
DEFINE_CLASS_QUERY(CatchProj)
DEFINE_CLASS_QUERY(CheckCastPP)
DEFINE_CLASS_QUERY(ConstraintCast)
+ DEFINE_CLASS_QUERY(ClearArray)
DEFINE_CLASS_QUERY(CMove)
DEFINE_CLASS_QUERY(Cmp)
DEFINE_CLASS_QUERY(CountedLoop)
@@ -1249,6 +1259,24 @@
#undef I_VDUI_ONLY
#undef VDUI_ONLY
+// An Iterator that truly follows the iterator pattern. Doesn't
+// support deletion but could be made to.
+//
+// for (SimpleDUIterator i(n); i.has_next(); i.next()) {
+// Node* m = i.get();
+//
+class SimpleDUIterator : public StackObj {
+ private:
+ Node* node;
+ DUIterator_Fast i;
+ DUIterator_Fast imax;
+ public:
+ SimpleDUIterator(Node* n): node(n), i(n->fast_outs(imax)) {}
+ bool has_next() { return i < imax; }
+ void next() { i++; }
+ Node* get() { return node->fast_out(i); }
+};
+
//-----------------------------------------------------------------------------
// Map dense integer indices to Nodes. Uses classic doubling-array trick.
@@ -1290,6 +1318,12 @@
public:
Node_List() : Node_Array(Thread::current()->resource_area()), _cnt(0) {}
Node_List(Arena *a) : Node_Array(a), _cnt(0) {}
+ bool contains(Node* n) {
+ for (uint e = 0; e < size(); e++) {
+ if (at(e) == n) return true;
+ }
+ return false;
+ }
void insert( uint i, Node *n ) { Node_Array::insert(i,n); _cnt++; }
void remove( uint i ) { Node_Array::remove(i); _cnt--; }
void push( Node *b ) { map(_cnt++,b); }
--- a/hotspot/src/share/vm/opto/parse1.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/parse1.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -231,12 +231,13 @@
// Use the raw liveness computation to make sure that unexpected
// values don't propagate into the OSR frame.
- MethodLivenessResult live_locals = method()->raw_liveness_at_bci(osr_bci());
+ MethodLivenessResult live_locals = method()->liveness_at_bci(osr_bci());
if (!live_locals.is_valid()) {
// Degenerate or breakpointed method.
C->record_method_not_compilable("OSR in empty or breakpointed method");
return;
}
+ MethodLivenessResult raw_live_locals = method()->raw_liveness_at_bci(osr_bci());
// Extract the needed locals from the interpreter frame.
Node *locals_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals-1)*wordSize);
@@ -316,6 +317,10 @@
continue;
}
}
+ if (type->basic_type() == T_ADDRESS && !raw_live_locals.at(index)) {
+ // Skip type check for dead address locals
+ continue;
+ }
set_local(index, check_interpreter_type(l, type, bad_type_exit));
}
--- a/hotspot/src/share/vm/opto/parse3.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/parse3.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -240,19 +240,19 @@
// membar is dependent on the store, keeping any other membars generated
// below from floating up past the store.
int adr_idx = C->get_alias_index(adr_type);
- insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx);
+ insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store);
// Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
// volatile alias indices. Skip this if the membar is redundant.
if (adr_idx != Compile::AliasIdxBot) {
- insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot);
+ insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store);
}
// Finally, place alias-index-specific membars for each volatile index
// that isn't the adr_idx membar. Typically there's only 1 or 2.
for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) {
if (i != adr_idx && C->alias_type(i)->is_volatile()) {
- insert_mem_bar_volatile(Op_MemBarVolatile, i);
+ insert_mem_bar_volatile(Op_MemBarVolatile, i, store);
}
}
}
--- a/hotspot/src/share/vm/opto/parseHelper.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -221,6 +221,14 @@
// Push resultant oop onto stack
push(obj);
+
+ // Keep track of whether opportunities exist for StringBuilder
+ // optimizations.
+ if (OptimizeStringConcat &&
+ (klass == C->env()->StringBuilder_klass() ||
+ klass == C->env()->StringBuffer_klass())) {
+ C->set_has_stringbuilder(true);
+ }
}
#ifndef PRODUCT
--- a/hotspot/src/share/vm/opto/phase.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/phase.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -44,6 +44,7 @@
BlockLayout, // Linear ordering of blocks
Register_Allocation, // Register allocation, duh
LIVE, // Dragon-book LIVE range problem
+ StringOpts, // StringBuilder related optimizations
Interference_Graph, // Building the IFG
Coalesce, // Coalescing copies
Ideal_Loop, // Find idealized trip-counted loops
--- a/hotspot/src/share/vm/opto/phaseX.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/phaseX.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -345,7 +345,11 @@
Node *hash_find(const Node *n) { return _table.hash_find(n); }
// Used after parsing to eliminate values that are no longer in program
- void remove_useless_nodes(VectorSet &useful) { _table.remove_useless_nodes(useful); }
+ void remove_useless_nodes(VectorSet &useful) {
+ _table.remove_useless_nodes(useful);
+ // this may invalidate cached cons so reset the cache
+ init_con_caches();
+ }
virtual ConNode* uncached_makecon(const Type* t); // override from PhaseTransform
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/opto/stringopts.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,1395 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_stringopts.cpp.incl"
+
+#define __ kit.
+
+class StringConcat : public ResourceObj {
+ private:
+ PhaseStringOpts* _stringopts;
+ Node* _string_alloc;
+ AllocateNode* _begin; // The allocation the begins the pattern
+ CallStaticJavaNode* _end; // The final call of the pattern. Will either be
+ // SB.toString or or String.<init>(SB.toString)
+ bool _multiple; // indicates this is a fusion of two or more
+ // separate StringBuilders
+
+ Node* _arguments; // The list of arguments to be concatenated
+ GrowableArray<int> _mode; // into a String along with a mode flag
+ // indicating how to treat the value.
+
+ Node_List _control; // List of control nodes that will be deleted
+ Node_List _uncommon_traps; // Uncommon traps that needs to be rewritten
+ // to restart at the initial JVMState.
+ public:
+ // Mode for converting arguments to Strings
+ enum {
+ StringMode,
+ IntMode,
+ CharMode
+ };
+
+ StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end):
+ _end(end),
+ _begin(NULL),
+ _multiple(false),
+ _string_alloc(NULL),
+ _stringopts(stringopts) {
+ _arguments = new (_stringopts->C, 1) Node(1);
+ _arguments->del_req(0);
+ }
+
+ bool validate_control_flow();
+
+ void merge_add() {
+#if 0
+ // XXX This is place holder code for reusing an existing String
+ // allocation but the logic for checking the state safety is
+ // probably inadequate at the moment.
+ CallProjections endprojs;
+ sc->end()->extract_projections(&endprojs, false);
+ if (endprojs.resproj != NULL) {
+ for (SimpleDUIterator i(endprojs.resproj); i.has_next(); i.next()) {
+ CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
+ if (use != NULL && use->method() != NULL &&
+ use->method()->holder() == C->env()->String_klass() &&
+ use->method()->name() == ciSymbol::object_initializer_name() &&
+ use->in(TypeFunc::Parms + 1) == endprojs.resproj) {
+ // Found useless new String(sb.toString()) so reuse the newly allocated String
+ // when creating the result instead of allocating a new one.
+ sc->set_string_alloc(use->in(TypeFunc::Parms));
+ sc->set_end(use);
+ }
+ }
+ }
+#endif
+ }
+
+ StringConcat* merge(StringConcat* other, Node* arg);
+
+ void set_allocation(AllocateNode* alloc) {
+ _begin = alloc;
+ }
+
+ void append(Node* value, int mode) {
+ _arguments->add_req(value);
+ _mode.append(mode);
+ }
+ void push(Node* value, int mode) {
+ _arguments->ins_req(0, value);
+ _mode.insert_before(0, mode);
+ }
+ void push_string(Node* value) {
+ push(value, StringMode);
+ }
+ void push_int(Node* value) {
+ push(value, IntMode);
+ }
+ void push_char(Node* value) {
+ push(value, CharMode);
+ }
+
+ Node* argument(int i) {
+ return _arguments->in(i);
+ }
+ void set_argument(int i, Node* value) {
+ _arguments->set_req(i, value);
+ }
+ int num_arguments() {
+ return _mode.length();
+ }
+ int mode(int i) {
+ return _mode.at(i);
+ }
+ void add_control(Node* ctrl) {
+ assert(!_control.contains(ctrl), "only push once");
+ _control.push(ctrl);
+ }
+ CallStaticJavaNode* end() { return _end; }
+ AllocateNode* begin() { return _begin; }
+ Node* string_alloc() { return _string_alloc; }
+
+ void eliminate_unneeded_control();
+ void eliminate_initialize(InitializeNode* init);
+ void eliminate_call(CallNode* call);
+
+ void maybe_log_transform() {
+ CompileLog* log = _stringopts->C->log();
+ if (log != NULL) {
+ log->head("replace_string_concat arguments='%d' string_alloc='%d' multiple='%d'",
+ num_arguments(),
+ _string_alloc != NULL,
+ _multiple);
+ JVMState* p = _begin->jvms();
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail("replace_string_concat");
+ }
+ }
+
+ void convert_uncommon_traps(GraphKit& kit, const JVMState* jvms) {
+ for (uint u = 0; u < _uncommon_traps.size(); u++) {
+ Node* uct = _uncommon_traps.at(u);
+
+ // Build a new call using the jvms state of the allocate
+ address call_addr = SharedRuntime::uncommon_trap_blob()->instructions_begin();
+ const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type();
+ int size = call_type->domain()->cnt();
+ const TypePtr* no_memory_effects = NULL;
+ Compile* C = _stringopts->C;
+ CallStaticJavaNode* call = new (C, size) CallStaticJavaNode(call_type, call_addr, "uncommon_trap",
+ jvms->bci(), no_memory_effects);
+ for (int e = 0; e < TypeFunc::Parms; e++) {
+ call->init_req(e, uct->in(e));
+ }
+ // Set the trap request to record intrinsic failure if this trap
+ // is taken too many times. Ideally we would handle then traps by
+ // doing the original bookkeeping in the MDO so that if it caused
+ // the code to be thrown out we could still recompile and use the
+ // optimization. Failing the uncommon traps doesn't really mean
+ // that the optimization is a bad idea but there's no other way to
+ // do the MDO updates currently.
+ int trap_request = Deoptimization::make_trap_request(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_make_not_entrant);
+ call->init_req(TypeFunc::Parms, __ intcon(trap_request));
+ kit.add_safepoint_edges(call);
+
+ _stringopts->gvn()->transform(call);
+ C->gvn_replace_by(uct, call);
+ uct->disconnect_inputs(NULL);
+ }
+ }
+
+ void cleanup() {
+ // disconnect the hook node
+ _arguments->disconnect_inputs(NULL);
+ }
+};
+
+
+void StringConcat::eliminate_unneeded_control() {
+ eliminate_initialize(begin()->initialization());
+ for (uint i = 0; i < _control.size(); i++) {
+ Node* n = _control.at(i);
+ if (n->is_Call()) {
+ if (n != _end) {
+ eliminate_call(n->as_Call());
+ }
+ } else if (n->is_IfTrue()) {
+ Compile* C = _stringopts->C;
+ C->gvn_replace_by(n, n->in(0)->in(0));
+ C->gvn_replace_by(n->in(0), C->top());
+ }
+ }
+}
+
+
+StringConcat* StringConcat::merge(StringConcat* other, Node* arg) {
+ StringConcat* result = new StringConcat(_stringopts, _end);
+ for (uint x = 0; x < _control.size(); x++) {
+ Node* n = _control.at(x);
+ if (n->is_Call()) {
+ result->_control.push(n);
+ }
+ }
+ for (uint x = 0; x < other->_control.size(); x++) {
+ Node* n = other->_control.at(x);
+ if (n->is_Call()) {
+ result->_control.push(n);
+ }
+ }
+ assert(result->_control.contains(other->_end), "what?");
+ assert(result->_control.contains(_begin), "what?");
+ for (int x = 0; x < num_arguments(); x++) {
+ if (argument(x) == arg) {
+ // replace the toString result with the all the arguments that
+ // made up the other StringConcat
+ for (int y = 0; y < other->num_arguments(); y++) {
+ result->append(other->argument(y), other->mode(y));
+ }
+ } else {
+ result->append(argument(x), mode(x));
+ }
+ }
+ result->set_allocation(other->_begin);
+ result->_multiple = true;
+ return result;
+}
+
+
+void StringConcat::eliminate_call(CallNode* call) {
+ Compile* C = _stringopts->C;
+ CallProjections projs;
+ call->extract_projections(&projs, false);
+ if (projs.fallthrough_catchproj != NULL) {
+ C->gvn_replace_by(projs.fallthrough_catchproj, call->in(TypeFunc::Control));
+ }
+ if (projs.fallthrough_memproj != NULL) {
+ C->gvn_replace_by(projs.fallthrough_memproj, call->in(TypeFunc::Memory));
+ }
+ if (projs.catchall_memproj != NULL) {
+ C->gvn_replace_by(projs.catchall_memproj, C->top());
+ }
+ if (projs.fallthrough_ioproj != NULL) {
+ C->gvn_replace_by(projs.fallthrough_ioproj, call->in(TypeFunc::I_O));
+ }
+ if (projs.catchall_ioproj != NULL) {
+ C->gvn_replace_by(projs.catchall_ioproj, C->top());
+ }
+ if (projs.catchall_catchproj != NULL) {
+ // EA can't cope with the partially collapsed graph this
+ // creates so put it on the worklist to be collapsed later.
+ for (SimpleDUIterator i(projs.catchall_catchproj); i.has_next(); i.next()) {
+ Node *use = i.get();
+ int opc = use->Opcode();
+ if (opc == Op_CreateEx || opc == Op_Region) {
+ _stringopts->record_dead_node(use);
+ }
+ }
+ C->gvn_replace_by(projs.catchall_catchproj, C->top());
+ }
+ if (projs.resproj != NULL) {
+ C->gvn_replace_by(projs.resproj, C->top());
+ }
+ C->gvn_replace_by(call, C->top());
+}
+
+void StringConcat::eliminate_initialize(InitializeNode* init) {
+ Compile* C = _stringopts->C;
+
+ // Eliminate Initialize node.
+ assert(init->outcnt() <= 2, "only a control and memory projection expected");
+ assert(init->req() <= InitializeNode::RawStores, "no pending inits");
+ Node *ctrl_proj = init->proj_out(TypeFunc::Control);
+ if (ctrl_proj != NULL) {
+ C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
+ }
+ Node *mem_proj = init->proj_out(TypeFunc::Memory);
+ if (mem_proj != NULL) {
+ Node *mem = init->in(TypeFunc::Memory);
+ C->gvn_replace_by(mem_proj, mem);
+ }
+ C->gvn_replace_by(init, C->top());
+ init->disconnect_inputs(NULL);
+}
+
+Node_List PhaseStringOpts::collect_toString_calls() {
+ Node_List string_calls;
+ Node_List worklist;
+
+ _visited.Clear();
+
+ // Prime the worklist
+ for (uint i = 1; i < C->root()->len(); i++) {
+ Node* n = C->root()->in(i);
+ if (n != NULL && !_visited.test_set(n->_idx)) {
+ worklist.push(n);
+ }
+ }
+
+ while (worklist.size() > 0) {
+ Node* ctrl = worklist.pop();
+ if (ctrl->is_CallStaticJava()) {
+ CallStaticJavaNode* csj = ctrl->as_CallStaticJava();
+ ciMethod* m = csj->method();
+ if (m != NULL &&
+ (m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString ||
+ m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString)) {
+ string_calls.push(csj);
+ }
+ }
+ if (ctrl->in(0) != NULL && !_visited.test_set(ctrl->in(0)->_idx)) {
+ worklist.push(ctrl->in(0));
+ }
+ if (ctrl->is_Region()) {
+ for (uint i = 1; i < ctrl->len(); i++) {
+ if (ctrl->in(i) != NULL && !_visited.test_set(ctrl->in(i)->_idx)) {
+ worklist.push(ctrl->in(i));
+ }
+ }
+ }
+ }
+ return string_calls;
+}
+
+
+StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
+ ciMethod* m = call->method();
+ ciSymbol* string_sig;
+ ciSymbol* int_sig;
+ ciSymbol* char_sig;
+ if (m->holder() == C->env()->StringBuilder_klass()) {
+ string_sig = ciSymbol::String_StringBuilder_signature();
+ int_sig = ciSymbol::int_StringBuilder_signature();
+ char_sig = ciSymbol::char_StringBuilder_signature();
+ } else if (m->holder() == C->env()->StringBuffer_klass()) {
+ string_sig = ciSymbol::String_StringBuffer_signature();
+ int_sig = ciSymbol::int_StringBuffer_signature();
+ char_sig = ciSymbol::char_StringBuffer_signature();
+ } else {
+ return NULL;
+ }
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print("considering toString call in ");
+ call->jvms()->dump_spec(tty); tty->cr();
+ }
+#endif
+
+ StringConcat* sc = new StringConcat(this, call);
+
+ AllocateNode* alloc = NULL;
+ InitializeNode* init = NULL;
+
+ // possible opportunity for StringBuilder fusion
+ CallStaticJavaNode* cnode = call;
+ while (cnode) {
+ Node* recv = cnode->in(TypeFunc::Parms)->uncast();
+ if (recv->is_Proj()) {
+ recv = recv->in(0);
+ }
+ cnode = recv->isa_CallStaticJava();
+ if (cnode == NULL) {
+ alloc = recv->isa_Allocate();
+ if (alloc == NULL) {
+ break;
+ }
+ // Find the constructor call
+ Node* result = alloc->result_cast();
+ if (result == NULL || !result->is_CheckCastPP()) {
+ // strange looking allocation
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print("giving up because allocation looks strange ");
+ alloc->jvms()->dump_spec(tty); tty->cr();
+ }
+#endif
+ break;
+ }
+ Node* constructor = NULL;
+ for (SimpleDUIterator i(result); i.has_next(); i.next()) {
+ CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
+ if (use != NULL && use->method() != NULL &&
+ use->method()->name() == ciSymbol::object_initializer_name() &&
+ use->method()->holder() == m->holder()) {
+ // Matched the constructor.
+ ciSymbol* sig = use->method()->signature()->as_symbol();
+ if (sig == ciSymbol::void_method_signature() ||
+ sig == ciSymbol::int_void_signature() ||
+ sig == ciSymbol::string_void_signature()) {
+ if (sig == ciSymbol::string_void_signature()) {
+ // StringBuilder(String) so pick this up as the first argument
+ assert(use->in(TypeFunc::Parms + 1) != NULL, "what?");
+ sc->push_string(use->in(TypeFunc::Parms + 1));
+ }
+ // The int variant takes an initial size for the backing
+ // array so just treat it like the void version.
+ constructor = use;
+ } else {
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print("unexpected constructor signature: %s", sig->as_utf8());
+ }
+#endif
+ }
+ break;
+ }
+ }
+ if (constructor == NULL) {
+ // couldn't find constructor
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print("giving up because couldn't find constructor ");
+ alloc->jvms()->dump_spec(tty);
+ }
+#endif
+ break;
+ }
+
+ // Walked all the way back and found the constructor call so see
+ // if this call converted into a direct string concatenation.
+ sc->add_control(call);
+ sc->add_control(constructor);
+ sc->add_control(alloc);
+ sc->set_allocation(alloc);
+ if (sc->validate_control_flow()) {
+ return sc;
+ } else {
+ return NULL;
+ }
+ } else if (cnode->method() == NULL) {
+ break;
+ } else if (cnode->method()->holder() == m->holder() &&
+ cnode->method()->name() == ciSymbol::append_name() &&
+ (cnode->method()->signature()->as_symbol() == string_sig ||
+ cnode->method()->signature()->as_symbol() == char_sig ||
+ cnode->method()->signature()->as_symbol() == int_sig)) {
+ sc->add_control(cnode);
+ Node* arg = cnode->in(TypeFunc::Parms + 1);
+ if (cnode->method()->signature()->as_symbol() == int_sig) {
+ sc->push_int(arg);
+ } else if (cnode->method()->signature()->as_symbol() == char_sig) {
+ sc->push_char(arg);
+ } else {
+ if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
+ CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
+ if (csj->method() != NULL &&
+ csj->method()->holder() == C->env()->Integer_klass() &&
+ csj->method()->name() == ciSymbol::toString_name()) {
+ sc->add_control(csj);
+ sc->push_int(csj->in(TypeFunc::Parms));
+ continue;
+ }
+ }
+ sc->push_string(arg);
+ }
+ continue;
+ } else {
+ // some unhandled signature
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print("giving up because encountered unexpected signature ");
+ cnode->tf()->dump(); tty->cr();
+ cnode->in(TypeFunc::Parms + 1)->dump();
+ }
+#endif
+ break;
+ }
+ }
+ return NULL;
+}
+
+
+PhaseStringOpts::PhaseStringOpts(PhaseGVN* gvn, Unique_Node_List*):
+ Phase(StringOpts),
+ _gvn(gvn),
+ _visited(Thread::current()->resource_area()) {
+
+ assert(OptimizeStringConcat, "shouldn't be here");
+
+ size_table_field = C->env()->Integer_klass()->get_field_by_name(ciSymbol::make("sizeTable"),
+ ciSymbol::make("[I"), true);
+ if (size_table_field == NULL) {
+ // Something wrong so give up.
+ assert(false, "why can't we find Integer.sizeTable?");
+ return;
+ }
+
+ // Collect the types needed to talk about the various slices of memory
+ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+ false, NULL, 0);
+
+ const TypePtr* value_field_type = string_type->add_offset(java_lang_String::value_offset_in_bytes());
+ const TypePtr* offset_field_type = string_type->add_offset(java_lang_String::offset_offset_in_bytes());
+ const TypePtr* count_field_type = string_type->add_offset(java_lang_String::count_offset_in_bytes());
+
+ value_field_idx = C->get_alias_index(value_field_type);
+ count_field_idx = C->get_alias_index(count_field_type);
+ offset_field_idx = C->get_alias_index(offset_field_type);
+ char_adr_idx = C->get_alias_index(TypeAryPtr::CHARS);
+
+ // For each locally allocated StringBuffer see if the usages can be
+ // collapsed into a single String construction.
+
+ // Run through the list of allocation looking for SB.toString to see
+ // if it's possible to fuse the usage of the SB into a single String
+ // construction.
+ GrowableArray<StringConcat*> concats;
+ Node_List toStrings = collect_toString_calls();
+ while (toStrings.size() > 0) {
+ StringConcat* sc = build_candidate(toStrings.pop()->as_CallStaticJava());
+ if (sc != NULL) {
+ concats.push(sc);
+ }
+ }
+
+ // try to coalesce separate concats
+ restart:
+ for (int c = 0; c < concats.length(); c++) {
+ StringConcat* sc = concats.at(c);
+ for (int i = 0; i < sc->num_arguments(); i++) {
+ Node* arg = sc->argument(i);
+ if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
+ CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
+ if (csj->method() != NULL &&
+ (csj->method()->holder() == C->env()->StringBuffer_klass() ||
+ csj->method()->holder() == C->env()->StringBuilder_klass()) &&
+ csj->method()->name() == ciSymbol::toString_name()) {
+ for (int o = 0; o < concats.length(); o++) {
+ if (c == o) continue;
+ StringConcat* other = concats.at(o);
+ if (other->end() == csj) {
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print_cr("considering stacked concats");
+ }
+#endif
+
+ StringConcat* merged = sc->merge(other, arg);
+ if (merged->validate_control_flow()) {
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print_cr("stacking would succeed");
+ }
+#endif
+ if (c < o) {
+ concats.remove_at(o);
+ concats.at_put(c, merged);
+ } else {
+ concats.remove_at(c);
+ concats.at_put(o, merged);
+ }
+ goto restart;
+ } else {
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print_cr("stacking would fail");
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ for (int c = 0; c < concats.length(); c++) {
+ StringConcat* sc = concats.at(c);
+ replace_string_concat(sc);
+ }
+
+ remove_dead_nodes();
+}
+
+void PhaseStringOpts::record_dead_node(Node* dead) {
+ dead_worklist.push(dead);
+}
+
+void PhaseStringOpts::remove_dead_nodes() {
+ // Delete any dead nodes to make things clean enough that escape
+ // analysis doesn't get unhappy.
+ while (dead_worklist.size() > 0) {
+ Node* use = dead_worklist.pop();
+ int opc = use->Opcode();
+ switch (opc) {
+ case Op_Region: {
+ uint i = 1;
+ for (i = 1; i < use->req(); i++) {
+ if (use->in(i) != C->top()) {
+ break;
+ }
+ }
+ if (i >= use->req()) {
+ for (SimpleDUIterator i(use); i.has_next(); i.next()) {
+ Node* m = i.get();
+ if (m->is_Phi()) {
+ dead_worklist.push(m);
+ }
+ }
+ C->gvn_replace_by(use, C->top());
+ }
+ break;
+ }
+ case Op_AddP:
+ case Op_CreateEx: {
+ // Recurisvely clean up references to CreateEx so EA doesn't
+ // get unhappy about the partially collapsed graph.
+ for (SimpleDUIterator i(use); i.has_next(); i.next()) {
+ Node* m = i.get();
+ if (m->is_AddP()) {
+ dead_worklist.push(m);
+ }
+ }
+ C->gvn_replace_by(use, C->top());
+ break;
+ }
+ case Op_Phi:
+ if (use->in(0) == C->top()) {
+ C->gvn_replace_by(use, C->top());
+ }
+ break;
+ }
+ }
+}
+
+
+bool StringConcat::validate_control_flow() {
+ // We found all the calls and arguments now lets see if it's
+ // safe to transform the graph as we would expect.
+
+ // Check to see if this resulted in too many uncommon traps previously
+ if (Compile::current()->too_many_traps(_begin->jvms()->method(), _begin->jvms()->bci(),
+ Deoptimization::Reason_intrinsic)) {
+ return false;
+ }
+
+ // Walk backwards over the control flow from toString to the
+ // allocation and make sure all the control flow is ok. This
+ // means it's either going to be eliminated once the calls are
+ // removed or it can safely be transformed into an uncommon
+ // trap.
+
+ int null_check_count = 0;
+ Unique_Node_List ctrl_path;
+
+ assert(_control.contains(_begin), "missing");
+ assert(_control.contains(_end), "missing");
+
+ // Collect the nodes that we know about and will eliminate into ctrl_path
+ for (uint i = 0; i < _control.size(); i++) {
+ // Push the call and it's control projection
+ Node* n = _control.at(i);
+ if (n->is_Allocate()) {
+ AllocateNode* an = n->as_Allocate();
+ InitializeNode* init = an->initialization();
+ ctrl_path.push(init);
+ ctrl_path.push(init->as_Multi()->proj_out(0));
+ }
+ if (n->is_Call()) {
+ CallNode* cn = n->as_Call();
+ ctrl_path.push(cn);
+ ctrl_path.push(cn->proj_out(0));
+ ctrl_path.push(cn->proj_out(0)->unique_out());
+ ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
+ } else {
+ ShouldNotReachHere();
+ }
+ }
+
+ // Skip backwards through the control checking for unexpected contro flow
+ Node* ptr = _end;
+ bool fail = false;
+ while (ptr != _begin) {
+ if (ptr->is_Call() && ctrl_path.member(ptr)) {
+ ptr = ptr->in(0);
+ } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
+ ptr = ptr->in(0)->in(0)->in(0);
+ assert(ctrl_path.member(ptr), "should be a known piece of control");
+ } else if (ptr->is_IfTrue()) {
+ IfNode* iff = ptr->in(0)->as_If();
+ BoolNode* b = iff->in(1)->isa_Bool();
+ Node* cmp = b->in(1);
+ Node* v1 = cmp->in(1);
+ Node* v2 = cmp->in(2);
+ Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
+
+ // Null check of the return of append which can simply be eliminated
+ if (b->_test._test == BoolTest::ne &&
+ v2->bottom_type() == TypePtr::NULL_PTR &&
+ v1->is_Proj() && ctrl_path.member(v1->in(0))) {
+ // NULL check of the return value of the append
+ null_check_count++;
+ if (otherproj->outcnt() == 1) {
+ CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
+ if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
+ ctrl_path.push(call);
+ }
+ }
+ _control.push(ptr);
+ ptr = ptr->in(0)->in(0);
+ continue;
+ }
+
+ // A test which leads to an uncommon trap which should be safe.
+ // Later this trap will be converted into a trap that restarts
+ // at the beginning.
+ if (otherproj->outcnt() == 1) {
+ CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
+ if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
+ // control flow leads to uct so should be ok
+ _uncommon_traps.push(call);
+ ctrl_path.push(call);
+ ptr = ptr->in(0)->in(0);
+ continue;
+ }
+ }
+
+#ifndef PRODUCT
+ // Some unexpected control flow we don't know how to handle.
+ if (PrintOptimizeStringConcat) {
+ tty->print_cr("failing with unknown test");
+ b->dump();
+ cmp->dump();
+ v1->dump();
+ v2->dump();
+ tty->cr();
+ }
+#endif
+ break;
+ } else if (ptr->is_Proj() && ptr->in(0)->is_Initialize()) {
+ ptr = ptr->in(0)->in(0);
+ } else if (ptr->is_Region()) {
+ Node* copy = ptr->as_Region()->is_copy();
+ if (copy != NULL) {
+ ptr = copy;
+ continue;
+ }
+ if (ptr->req() == 3 &&
+ ptr->in(1) != NULL && ptr->in(1)->is_Proj() &&
+ ptr->in(2) != NULL && ptr->in(2)->is_Proj() &&
+ ptr->in(1)->in(0) == ptr->in(2)->in(0) &&
+ ptr->in(1)->in(0) != NULL && ptr->in(1)->in(0)->is_If()) {
+ // Simple diamond.
+ // XXX should check for possibly merging stores. simple data merges are ok.
+ ptr = ptr->in(1)->in(0)->in(0);
+ continue;
+ }
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print_cr("fusion would fail for region");
+ _begin->dump();
+ ptr->dump(2);
+ }
+#endif
+ fail = true;
+ break;
+ } else {
+ // other unknown control
+ if (!fail) {
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print_cr("fusion would fail for");
+ _begin->dump();
+ }
+#endif
+ fail = true;
+ }
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ ptr->dump();
+ }
+#endif
+ ptr = ptr->in(0);
+ }
+ }
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat && fail) {
+ tty->cr();
+ }
+#endif
+ if (fail) return !fail;
+
+ // Validate that all these results produced are contained within
+ // this cluster of objects. First collect all the results produced
+ // by calls in the region.
+ _stringopts->_visited.Clear();
+ Node_List worklist;
+ Node* final_result = _end->proj_out(TypeFunc::Parms);
+ for (uint i = 0; i < _control.size(); i++) {
+ CallNode* cnode = _control.at(i)->isa_Call();
+ if (cnode != NULL) {
+ _stringopts->_visited.test_set(cnode->_idx);
+ }
+ Node* result = cnode != NULL ? cnode->proj_out(TypeFunc::Parms) : NULL;
+ if (result != NULL && result != final_result) {
+ worklist.push(result);
+ }
+ }
+
+ Node* last_result = NULL;
+ while (worklist.size() > 0) {
+ Node* result = worklist.pop();
+ if (_stringopts->_visited.test_set(result->_idx))
+ continue;
+ for (SimpleDUIterator i(result); i.has_next(); i.next()) {
+ Node *use = i.get();
+ if (ctrl_path.member(use)) {
+ // already checked this
+ continue;
+ }
+ int opc = use->Opcode();
+ if (opc == Op_CmpP || opc == Op_Node) {
+ ctrl_path.push(use);
+ continue;
+ }
+ if (opc == Op_CastPP || opc == Op_CheckCastPP) {
+ for (SimpleDUIterator j(use); j.has_next(); j.next()) {
+ worklist.push(j.get());
+ }
+ worklist.push(use->in(1));
+ ctrl_path.push(use);
+ continue;
+ }
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ if (result != last_result) {
+ last_result = result;
+ tty->print_cr("extra uses for result:");
+ last_result->dump();
+ }
+ use->dump();
+ }
+#endif
+ fail = true;
+ break;
+ }
+ }
+
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat && !fail) {
+ ttyLocker ttyl;
+ tty->cr();
+ tty->print("fusion would succeed (%d %d) for ", null_check_count, _uncommon_traps.size());
+ _begin->jvms()->dump_spec(tty); tty->cr();
+ for (int i = 0; i < num_arguments(); i++) {
+ argument(i)->dump();
+ }
+ _control.dump();
+ tty->cr();
+ }
+#endif
+
+ return !fail;
+}
+
+Node* PhaseStringOpts::fetch_static_field(GraphKit& kit, ciField* field) {
+ const TypeKlassPtr* klass_type = TypeKlassPtr::make(field->holder());
+ Node* klass_node = __ makecon(klass_type);
+ BasicType bt = field->layout_type();
+ ciType* field_klass = field->type();
+
+ const Type *type;
+ if( bt == T_OBJECT ) {
+ if (!field->type()->is_loaded()) {
+ type = TypeInstPtr::BOTTOM;
+ } else if (field->is_constant()) {
+ // This can happen if the constant oop is non-perm.
+ ciObject* con = field->constant_value().as_object();
+ // Do not "join" in the previous type; it doesn't add value,
+ // and may yield a vacuous result if the field is of interface type.
+ type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
+ assert(type != NULL, "field singleton type must be consistent");
+ } else {
+ type = TypeOopPtr::make_from_klass(field_klass->as_klass());
+ }
+ } else {
+ type = Type::get_const_basic_type(bt);
+ }
+
+ return kit.make_load(NULL, kit.basic_plus_adr(klass_node, field->offset_in_bytes()),
+ type, T_OBJECT,
+ C->get_alias_index(klass_type->add_offset(field->offset_in_bytes())));
+}
+
+Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
+ RegionNode *final_merge = new (C, 3) RegionNode(3);
+ kit.gvn().set_type(final_merge, Type::CONTROL);
+ Node* final_size = new (C, 3) PhiNode(final_merge, TypeInt::INT);
+ kit.gvn().set_type(final_size, TypeInt::INT);
+
+ IfNode* iff = kit.create_and_map_if(kit.control(),
+ __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+ Node* is_min = __ IfFalse(iff);
+ final_merge->init_req(1, is_min);
+ final_size->init_req(1, __ intcon(11));
+
+ kit.set_control(__ IfTrue(iff));
+ if (kit.stopped()) {
+ final_merge->init_req(2, C->top());
+ final_size->init_req(2, C->top());
+ } else {
+
+ // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+ RegionNode *r = new (C, 3) RegionNode(3);
+ kit.gvn().set_type(r, Type::CONTROL);
+ Node *phi = new (C, 3) PhiNode(r, TypeInt::INT);
+ kit.gvn().set_type(phi, TypeInt::INT);
+ Node *size = new (C, 3) PhiNode(r, TypeInt::INT);
+ kit.gvn().set_type(size, TypeInt::INT);
+ Node* chk = __ CmpI(arg, __ intcon(0));
+ Node* p = __ Bool(chk, BoolTest::lt);
+ IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_FAIR, COUNT_UNKNOWN);
+ Node* lessthan = __ IfTrue(iff);
+ Node* greaterequal = __ IfFalse(iff);
+ r->init_req(1, lessthan);
+ phi->init_req(1, __ SubI(__ intcon(0), arg));
+ size->init_req(1, __ intcon(1));
+ r->init_req(2, greaterequal);
+ phi->init_req(2, arg);
+ size->init_req(2, __ intcon(0));
+ kit.set_control(r);
+ C->record_for_igvn(r);
+ C->record_for_igvn(phi);
+ C->record_for_igvn(size);
+
+ // for (int i=0; ; i++)
+ // if (x <= sizeTable[i])
+ // return i+1;
+ RegionNode *loop = new (C, 3) RegionNode(3);
+ loop->init_req(1, kit.control());
+ kit.gvn().set_type(loop, Type::CONTROL);
+
+ Node *index = new (C, 3) PhiNode(loop, TypeInt::INT);
+ index->init_req(1, __ intcon(0));
+ kit.gvn().set_type(index, TypeInt::INT);
+ kit.set_control(loop);
+ Node* sizeTable = fetch_static_field(kit, size_table_field);
+
+ Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS);
+ C->record_for_igvn(value);
+ Node* limit = __ CmpI(phi, value);
+ Node* limitb = __ Bool(limit, BoolTest::le);
+ IfNode* iff2 = kit.create_and_map_if(kit.control(), limitb, PROB_MIN, COUNT_UNKNOWN);
+ Node* lessEqual = __ IfTrue(iff2);
+ Node* greater = __ IfFalse(iff2);
+
+ loop->init_req(2, greater);
+ index->init_req(2, __ AddI(index, __ intcon(1)));
+
+ kit.set_control(lessEqual);
+ C->record_for_igvn(loop);
+ C->record_for_igvn(index);
+
+ final_merge->init_req(2, kit.control());
+ final_size->init_req(2, __ AddI(__ AddI(index, size), __ intcon(1)));
+ }
+
+ kit.set_control(final_merge);
+ C->record_for_igvn(final_merge);
+ C->record_for_igvn(final_size);
+
+ return final_size;
+}
+
+void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) {
+ RegionNode *final_merge = new (C, 4) RegionNode(4);
+ kit.gvn().set_type(final_merge, Type::CONTROL);
+ Node *final_mem = PhiNode::make(final_merge, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
+ kit.gvn().set_type(final_mem, Type::MEMORY);
+
+ // need to handle Integer.MIN_VALUE specially because negating doesn't make it positive
+ {
+ // i == MIN_VALUE
+ IfNode* iff = kit.create_and_map_if(kit.control(),
+ __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+
+ Node* old_mem = kit.memory(char_adr_idx);
+
+ kit.set_control(__ IfFalse(iff));
+ if (kit.stopped()) {
+ // Statically not equal to MIN_VALUE so this path is dead
+ final_merge->init_req(3, kit.control());
+ } else {
+ copy_string(kit, __ makecon(TypeInstPtr::make(C->env()->the_min_jint_string())),
+ char_array, start);
+ final_merge->init_req(3, kit.control());
+ final_mem->init_req(3, kit.memory(char_adr_idx));
+ }
+
+ kit.set_control(__ IfTrue(iff));
+ kit.set_memory(old_mem, char_adr_idx);
+ }
+
+
+ // Simplified version of Integer.getChars
+
+ // int q, r;
+ // int charPos = index;
+ Node* charPos = end;
+
+ // char sign = 0;
+
+ Node* i = arg;
+ Node* sign = __ intcon(0);
+
+ // if (i < 0) {
+ // sign = '-';
+ // i = -i;
+ // }
+ {
+ IfNode* iff = kit.create_and_map_if(kit.control(),
+ __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt),
+ PROB_FAIR, COUNT_UNKNOWN);
+
+ RegionNode *merge = new (C, 3) RegionNode(3);
+ kit.gvn().set_type(merge, Type::CONTROL);
+ i = new (C, 3) PhiNode(merge, TypeInt::INT);
+ kit.gvn().set_type(i, TypeInt::INT);
+ sign = new (C, 3) PhiNode(merge, TypeInt::INT);
+ kit.gvn().set_type(sign, TypeInt::INT);
+
+ merge->init_req(1, __ IfTrue(iff));
+ i->init_req(1, __ SubI(__ intcon(0), arg));
+ sign->init_req(1, __ intcon('-'));
+ merge->init_req(2, __ IfFalse(iff));
+ i->init_req(2, arg);
+ sign->init_req(2, __ intcon(0));
+
+ kit.set_control(merge);
+
+ C->record_for_igvn(merge);
+ C->record_for_igvn(i);
+ C->record_for_igvn(sign);
+ }
+
+ // for (;;) {
+ // q = i / 10;
+ // r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
+ // buf [--charPos] = digits [r];
+ // i = q;
+ // if (i == 0) break;
+ // }
+
+ {
+ RegionNode *head = new (C, 3) RegionNode(3);
+ head->init_req(1, kit.control());
+ kit.gvn().set_type(head, Type::CONTROL);
+ Node *i_phi = new (C, 3) PhiNode(head, TypeInt::INT);
+ i_phi->init_req(1, i);
+ kit.gvn().set_type(i_phi, TypeInt::INT);
+ charPos = PhiNode::make(head, charPos);
+ kit.gvn().set_type(charPos, TypeInt::INT);
+ Node *mem = PhiNode::make(head, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
+ kit.gvn().set_type(mem, Type::MEMORY);
+ kit.set_control(head);
+ kit.set_memory(mem, char_adr_idx);
+
+ Node* q = __ DivI(kit.null(), i_phi, __ intcon(10));
+ Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
+ __ LShiftI(q, __ intcon(1))));
+ Node* m1 = __ SubI(charPos, __ intcon(1));
+ Node* ch = __ AddI(r, __ intcon('0'));
+
+ Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
+ ch, T_CHAR, char_adr_idx);
+
+
+ IfNode* iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+ Node* ne = __ IfTrue(iff);
+ Node* eq = __ IfFalse(iff);
+
+ head->init_req(2, ne);
+ mem->init_req(2, st);
+ i_phi->init_req(2, q);
+ charPos->init_req(2, m1);
+
+ charPos = m1;
+
+ kit.set_control(eq);
+ kit.set_memory(st, char_adr_idx);
+
+ C->record_for_igvn(head);
+ C->record_for_igvn(mem);
+ C->record_for_igvn(i_phi);
+ C->record_for_igvn(charPos);
+ }
+
+ {
+ // if (sign != 0) {
+ // buf [--charPos] = sign;
+ // }
+ IfNode* iff = kit.create_and_map_if(kit.control(),
+ __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+
+ final_merge->init_req(2, __ IfFalse(iff));
+ final_mem->init_req(2, kit.memory(char_adr_idx));
+
+ kit.set_control(__ IfTrue(iff));
+ if (kit.stopped()) {
+ final_merge->init_req(1, C->top());
+ final_mem->init_req(1, C->top());
+ } else {
+ Node* m1 = __ SubI(charPos, __ intcon(1));
+ Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
+ sign, T_CHAR, char_adr_idx);
+
+ final_merge->init_req(1, kit.control());
+ final_mem->init_req(1, st);
+ }
+
+ kit.set_control(final_merge);
+ kit.set_memory(final_mem, char_adr_idx);
+
+ C->record_for_igvn(final_merge);
+ C->record_for_igvn(final_mem);
+ }
+}
+
+
+Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
+ Node* string = str;
+ Node* offset = kit.make_load(NULL,
+ kit.basic_plus_adr(string, string, java_lang_String::offset_offset_in_bytes()),
+ TypeInt::INT, T_INT, offset_field_idx);
+ Node* count = kit.make_load(NULL,
+ kit.basic_plus_adr(string, string, java_lang_String::count_offset_in_bytes()),
+ TypeInt::INT, T_INT, count_field_idx);
+ const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
+ TypeAry::make(TypeInt::CHAR,TypeInt::POS),
+ ciTypeArrayKlass::make(T_CHAR), true, 0);
+ Node* value = kit.make_load(NULL,
+ kit.basic_plus_adr(string, string, java_lang_String::value_offset_in_bytes()),
+ value_type, T_OBJECT, value_field_idx);
+
+ // copy the contents
+ if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
+ // For small constant strings just emit individual stores.
+ // A length of 6 seems like a good space/speed tradeof.
+ int c = count->get_int();
+ int o = offset->get_int();
+ const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
+ ciTypeArray* value_array = t->const_oop()->as_type_array();
+ for (int e = 0; e < c; e++) {
+ __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
+ __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx);
+ start = __ AddI(start, __ intcon(1));
+ }
+ } else {
+ Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
+ Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
+ Node* c = count;
+ Node* extra = NULL;
+#ifdef _LP64
+ c = __ ConvI2L(c);
+ extra = C->top();
+#endif
+ Node* call = kit.make_runtime_call(GraphKit::RC_LEAF|GraphKit::RC_NO_FP,
+ OptoRuntime::fast_arraycopy_Type(),
+ CAST_FROM_FN_PTR(address, StubRoutines::jshort_disjoint_arraycopy()),
+ "jshort_disjoint_arraycopy", TypeAryPtr::CHARS,
+ src_ptr, dst_ptr, c, extra);
+ start = __ AddI(start, count);
+ }
+ return start;
+}
+
+
+void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
+ // Log a little info about the transformation
+ sc->maybe_log_transform();
+
+ // pull the JVMState of the allocation into a SafePointNode to serve as
+ // as a shim for the insertion of the new code.
+ JVMState* jvms = sc->begin()->jvms()->clone_shallow(C);
+ uint size = sc->begin()->req();
+ SafePointNode* map = new (C, size) SafePointNode(size, jvms);
+
+ // copy the control and memory state from the final call into our
+ // new starting state. This allows any preceeding tests to feed
+ // into the new section of code.
+ for (uint i1 = 0; i1 < TypeFunc::Parms; i1++) {
+ map->init_req(i1, sc->end()->in(i1));
+ }
+ // blow away old allocation arguments
+ for (uint i1 = TypeFunc::Parms; i1 < jvms->debug_start(); i1++) {
+ map->init_req(i1, C->top());
+ }
+ // Copy the rest of the inputs for the JVMState
+ for (uint i1 = jvms->debug_start(); i1 < sc->begin()->req(); i1++) {
+ map->init_req(i1, sc->begin()->in(i1));
+ }
+ // Make sure the memory state is a MergeMem for parsing.
+ if (!map->in(TypeFunc::Memory)->is_MergeMem()) {
+ map->set_req(TypeFunc::Memory, MergeMemNode::make(C, map->in(TypeFunc::Memory)));
+ }
+
+ jvms->set_map(map);
+ map->ensure_stack(jvms, jvms->method()->max_stack());
+
+
+ // disconnect all the old StringBuilder calls from the graph
+ sc->eliminate_unneeded_control();
+
+ // At this point all the old work has been completely removed from
+ // the graph and the saved JVMState exists at the point where the
+ // final toString call used to be.
+ GraphKit kit(jvms);
+
+ // There may be uncommon traps which are still using the
+ // intermediate states and these need to be rewritten to point at
+ // the JVMState at the beginning of the transformation.
+ sc->convert_uncommon_traps(kit, jvms);
+
+ // Now insert the logic to compute the size of the string followed
+ // by all the logic to construct array and resulting string.
+
+ Node* null_string = __ makecon(TypeInstPtr::make(C->env()->the_null_string()));
+
+ // Create a region for the overflow checks to merge into.
+ int args = MAX2(sc->num_arguments(), 1);
+ RegionNode* overflow = new (C, args) RegionNode(args);
+ kit.gvn().set_type(overflow, Type::CONTROL);
+
+ // Create a hook node to hold onto the individual sizes since they
+ // are need for the copying phase.
+ Node* string_sizes = new (C, args) Node(args);
+
+ Node* length = __ intcon(0);
+ for (int argi = 0; argi < sc->num_arguments(); argi++) {
+ Node* arg = sc->argument(argi);
+ switch (sc->mode(argi)) {
+ case StringConcat::IntMode: {
+ Node* string_size = int_stringSize(kit, arg);
+
+ // accumulate total
+ length = __ AddI(length, string_size);
+
+ // Cache this value for the use by int_toString
+ string_sizes->init_req(argi, string_size);
+ break;
+ }
+ case StringConcat::StringMode: {
+ const Type* type = kit.gvn().type(arg);
+ if (type == TypePtr::NULL_PTR) {
+ // replace the argument with the null checked version
+ arg = null_string;
+ sc->set_argument(argi, arg);
+ } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
+ // s = s != null ? s : "null";
+ // length = length + (s.count - s.offset);
+ RegionNode *r = new (C, 3) RegionNode(3);
+ kit.gvn().set_type(r, Type::CONTROL);
+ Node *phi = new (C, 3) PhiNode(r, type->join(TypeInstPtr::NOTNULL));
+ kit.gvn().set_type(phi, phi->bottom_type());
+ Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
+ IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
+ Node* notnull = __ IfTrue(iff);
+ Node* isnull = __ IfFalse(iff);
+ r->init_req(1, notnull);
+ phi->init_req(1, arg);
+ r->init_req(2, isnull);
+ phi->init_req(2, null_string);
+ kit.set_control(r);
+ C->record_for_igvn(r);
+ C->record_for_igvn(phi);
+ // replace the argument with the null checked version
+ arg = phi;
+ sc->set_argument(argi, arg);
+ }
+ // Node* offset = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, offset_offset),
+ // TypeInt::INT, T_INT, offset_field_idx);
+ Node* count = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, java_lang_String::count_offset_in_bytes()),
+ TypeInt::INT, T_INT, count_field_idx);
+ length = __ AddI(length, count);
+ string_sizes->init_req(argi, NULL);
+ break;
+ }
+ case StringConcat::CharMode: {
+ // one character only
+ length = __ AddI(length, __ intcon(1));
+ break;
+ }
+ default:
+ ShouldNotReachHere();
+ }
+ if (argi > 0) {
+ // Check that the sum hasn't overflowed
+ IfNode* iff = kit.create_and_map_if(kit.control(),
+ __ Bool(__ CmpI(length, __ intcon(0)), BoolTest::lt),
+ PROB_MIN, COUNT_UNKNOWN);
+ kit.set_control(__ IfFalse(iff));
+ overflow->set_req(argi, __ IfTrue(iff));
+ }
+ }
+
+ {
+ // Hook
+ PreserveJVMState pjvms(&kit);
+ kit.set_control(overflow);
+ kit.uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_make_not_entrant);
+ }
+
+ // length now contains the number of characters needed for the
+ // char[] so create a new AllocateArray for the char[]
+ Node* char_array = NULL;
+ {
+ PreserveReexecuteState preexecs(&kit);
+ // The original jvms is for an allocation of either a String or
+ // StringBuffer so no stack adjustment is necessary for proper
+ // reexecution. If we deoptimize in the slow path the bytecode
+ // will be reexecuted and the char[] allocation will be thrown away.
+ kit.jvms()->set_should_reexecute(true);
+ char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
+ length, 1);
+ }
+
+ // Mark the allocation so that zeroing is skipped since the code
+ // below will overwrite the entire array
+ AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
+ char_alloc->maybe_set_complete(_gvn);
+
+ // Now copy the string representations into the final char[]
+ Node* start = __ intcon(0);
+ for (int argi = 0; argi < sc->num_arguments(); argi++) {
+ Node* arg = sc->argument(argi);
+ switch (sc->mode(argi)) {
+ case StringConcat::IntMode: {
+ Node* end = __ AddI(start, string_sizes->in(argi));
+ // getChars words backwards so pass the ending point as well as the start
+ int_getChars(kit, arg, char_array, start, end);
+ start = end;
+ break;
+ }
+ case StringConcat::StringMode: {
+ start = copy_string(kit, arg, char_array, start);
+ break;
+ }
+ case StringConcat::CharMode: {
+ __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
+ arg, T_CHAR, char_adr_idx);
+ start = __ AddI(start, __ intcon(1));
+ break;
+ }
+ default:
+ ShouldNotReachHere();
+ }
+ }
+
+ // If we're not reusing an existing String allocation then allocate one here.
+ Node* result = sc->string_alloc();
+ if (result == NULL) {
+ PreserveReexecuteState preexecs(&kit);
+ // The original jvms is for an allocation of either a String or
+ // StringBuffer so no stack adjustment is necessary for proper
+ // reexecution.
+ kit.jvms()->set_should_reexecute(true);
+ result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
+ }
+
+ // Intialize the string
+ kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::offset_offset_in_bytes()),
+ __ intcon(0), T_INT, offset_field_idx);
+ kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::count_offset_in_bytes()),
+ length, T_INT, count_field_idx);
+ kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::value_offset_in_bytes()),
+ char_array, T_OBJECT, value_field_idx);
+
+ // hook up the outgoing control and result
+ kit.replace_call(sc->end(), result);
+
+ // Unhook any hook nodes
+ string_sizes->disconnect_inputs(NULL);
+ sc->cleanup();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/opto/stringopts.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+class StringConcat;
+
+class PhaseStringOpts : public Phase {
+ friend class StringConcat;
+
+ private:
+ PhaseGVN* _gvn;
+
+ // List of dead nodes to clean up aggressively at the end
+ Unique_Node_List dead_worklist;
+
+ // Memory slices needed for code gen
+ int char_adr_idx;
+ int value_field_idx;
+ int count_field_idx;
+ int offset_field_idx;
+
+ // Integer.sizeTable - used for int to String conversion
+ ciField* size_table_field;
+
+ // A set for use by various stages
+ VectorSet _visited;
+
+ // Collect a list of all SB.toString calls
+ Node_List collect_toString_calls();
+
+ // Examine the use of the SB alloc to see if it can be replace with
+ // a single string construction.
+ StringConcat* build_candidate(CallStaticJavaNode* call);
+
+ // Replace all the SB calls in concat with an optimization String allocation
+ void replace_string_concat(StringConcat* concat);
+
+ // Load the value of a static field, performing any constant folding.
+ Node* fetch_static_field(GraphKit& kit, ciField* field);
+
+ // Compute the number of characters required to represent the int value
+ Node* int_stringSize(GraphKit& kit, Node* value);
+
+ // Copy the characters representing value into char_array starting at start
+ void int_getChars(GraphKit& kit, Node* value, Node* char_array, Node* start, Node* end);
+
+ // Copy of the contents of the String str into char_array starting at index start.
+ Node* copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start);
+
+ // Clean up any leftover nodes
+ void record_dead_node(Node* node);
+ void remove_dead_nodes();
+
+ PhaseGVN* gvn() { return _gvn; }
+
+ enum {
+ // max length of constant string copy unrolling in copy_string
+ unroll_string_copy_length = 6
+ };
+
+ public:
+ PhaseStringOpts(PhaseGVN* gvn, Unique_Node_List* worklist);
+};
--- a/hotspot/src/share/vm/opto/superword.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/superword.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1921,6 +1921,11 @@
}
// Match AddP(base, AddP(ptr, k*iv [+ invariant]), constant)
Node* base = adr->in(AddPNode::Base);
+ //unsafe reference could not be aligned appropriately without runtime checking
+ if (base == NULL || base->bottom_type() == Type::TOP) {
+ assert(!valid(), "unsafe access");
+ return;
+ }
for (int i = 0; i < 3; i++) {
if (!scaled_iv_plus_offset(adr->in(AddPNode::Offset))) {
assert(!valid(), "too complex");
--- a/hotspot/src/share/vm/opto/type.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/opto/type.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -847,9 +847,6 @@
// Constant pointer to array
static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
- // Convenience
- static const TypeAryPtr *make(ciObject* o);
-
// Return a 'ptr' version of this type
virtual const Type *cast_to_ptr_type(PTR ptr) const;
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -3231,6 +3231,21 @@
jint result = JNI_ERR;
DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
+ // We're about to use Atomic::xchg for synchronization. Some Zero
+ // platforms use the GCC builtin __sync_lock_test_and_set for this,
+ // but __sync_lock_test_and_set is not guaranteed to do what we want
+ // on all architectures. So we check it works before relying on it.
+#if defined(ZERO) && defined(ASSERT)
+ {
+ jint a = 0xcafebabe;
+ jint b = Atomic::xchg(0xdeadbeef, &a);
+ void *c = &a;
+ void *d = Atomic::xchg_ptr(&b, &c);
+ assert(a == 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
+ assert(c == &b && d == &a, "Atomic::xchg_ptr() works");
+ }
+#endif // ZERO && ASSERT
+
// At the moment it's only possible to have one Java VM,
// since some of the runtime state is in global variables.
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1318,19 +1318,20 @@
return NULL;
}
- symbolOop simple_name = NULL;
+ bool inner_is_member = false;
klassOop outer_klass
= instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass))
- )->compute_enclosing_class(simple_name, CHECK_NULL);
+ )->compute_enclosing_class(&inner_is_member, CHECK_NULL);
if (outer_klass == NULL) return NULL; // already a top-level class
- if (simple_name == NULL) return NULL; // an anonymous class (inside a method)
+ if (!inner_is_member) return NULL; // an anonymous class (inside a method)
return (jclass) JNIHandles::make_local(env, Klass::cast(outer_klass)->java_mirror());
}
JVM_END
// should be in instanceKlass.cpp, but is here for historical reasons
klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k,
- symbolOop& simple_name_result, TRAPS) {
+ bool* inner_is_member,
+ TRAPS) {
Thread* thread = THREAD;
const int inner_class_info_index = inner_class_inner_class_info_offset;
const int outer_class_info_index = inner_class_outer_class_info_offset;
@@ -1347,8 +1348,7 @@
bool found = false;
klassOop ok;
instanceKlassHandle outer_klass;
- bool inner_is_member = false;
- int simple_name_index = 0;
+ *inner_is_member = false;
// Find inner_klass attribute
for (int i = 0; i < i_length && !found; i += inner_class_next_offset) {
@@ -1364,8 +1364,7 @@
if (found && ooff != 0) {
ok = i_cp->klass_at(ooff, CHECK_NULL);
outer_klass = instanceKlassHandle(thread, ok);
- simple_name_index = noff;
- inner_is_member = true;
+ *inner_is_member = true;
}
}
}
@@ -1377,7 +1376,7 @@
if (encl_method_class_idx != 0) {
ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);
outer_klass = instanceKlassHandle(thread, ok);
- inner_is_member = false;
+ *inner_is_member = false;
}
}
@@ -1387,9 +1386,7 @@
// Throws an exception if outer klass has not declared k as an inner klass
// We need evidence that each klass knows about the other, or else
// the system could allow a spoof of an inner class to gain access rights.
- Reflection::check_for_inner_class(outer_klass, k, inner_is_member, CHECK_NULL);
-
- simple_name_result = (inner_is_member ? i_cp->symbol_at(simple_name_index) : symbolOop(NULL));
+ Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL);
return outer_klass();
}
@@ -2257,10 +2254,8 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
+ case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_name_ref_at(cp_index)->as_utf8();
- case JVM_CONSTANT_NameAndType:
- // for invokedynamic
- return cp->nt_name_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodNameUTF: illegal constant");
}
@@ -2277,10 +2272,8 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
+ case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_signature_ref_at(cp_index)->as_utf8();
- case JVM_CONSTANT_NameAndType:
- // for invokedynamic
- return cp->nt_signature_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodSignatureUTF: illegal constant");
}
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. 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,15 +32,15 @@
// FIXLATER: hook into JvmtiTrace
#define TraceJVMTICalls false
-JvmtiEnv::JvmtiEnv() : JvmtiEnvBase() {
+JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
}
JvmtiEnv::~JvmtiEnv() {
}
JvmtiEnv*
-JvmtiEnv::create_a_jvmti() {
- return new JvmtiEnv();
+JvmtiEnv::create_a_jvmti(jint version) {
+ return new JvmtiEnv(version);
}
// VM operation class to copy jni function table at safepoint.
@@ -411,8 +411,15 @@
if (phase == JVMTI_PHASE_ONLOAD) {
Arguments::append_sysclasspath(segment);
return JVMTI_ERROR_NONE;
- } else {
- assert(phase == JVMTI_PHASE_LIVE, "sanity check");
+ } else if (use_version_1_0_semantics()) {
+ // This JvmtiEnv requested version 1.0 semantics and this function
+ // is only allowed in the ONLOAD phase in version 1.0 so we need to
+ // return an error here.
+ return JVMTI_ERROR_WRONG_PHASE;
+ } else if (phase == JVMTI_PHASE_LIVE) {
+ // The phase is checked by the wrapper that called this function,
+ // but this thread could be racing with the thread that is
+ // terminating the VM so we check one more time.
// create the zip entry
ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
@@ -433,6 +440,8 @@
}
ClassLoader::add_to_list(zip_entry);
return JVMTI_ERROR_NONE;
+ } else {
+ return JVMTI_ERROR_WRONG_PHASE;
}
} /* end AddToBootstrapClassLoaderSearch */
@@ -451,11 +460,12 @@
}
}
return JVMTI_ERROR_NONE;
- } else {
+ } else if (phase == JVMTI_PHASE_LIVE) {
+ // The phase is checked by the wrapper that called this function,
+ // but this thread could be racing with the thread that is
+ // terminating the VM so we check one more time.
HandleMark hm;
- assert(phase == JVMTI_PHASE_LIVE, "sanity check");
-
// create the zip entry (which will open the zip file and hence
// check that the segment is indeed a zip file).
ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
@@ -504,6 +514,8 @@
}
return JVMTI_ERROR_NONE;
+ } else {
+ return JVMTI_ERROR_WRONG_PHASE;
}
} /* end AddToSystemClassLoaderSearch */
@@ -2863,6 +2875,14 @@
// is_obsolete_ptr - pre-checked for NULL
jvmtiError
JvmtiEnv::IsMethodObsolete(methodOop method_oop, jboolean* is_obsolete_ptr) {
+ if (use_version_1_0_semantics() &&
+ get_capabilities()->can_redefine_classes == 0) {
+ // This JvmtiEnv requested version 1.0 semantics and this function
+ // requires the can_redefine_classes capability in version 1.0 so
+ // we need to return an error here.
+ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+ }
+
if (method_oop == NULL || method_oop->is_obsolete()) {
*is_obsolete_ptr = true;
} else {
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -123,7 +123,26 @@
}
-JvmtiEnvBase::JvmtiEnvBase() : _env_event_enable() {
+bool
+JvmtiEnvBase::use_version_1_0_semantics() {
+ int major, minor, micro;
+
+ JvmtiExport::decode_version_values(_version, &major, &minor, µ);
+ return major == 1 && minor == 0; // micro version doesn't matter here
+}
+
+
+bool
+JvmtiEnvBase::use_version_1_1_semantics() {
+ int major, minor, micro;
+
+ JvmtiExport::decode_version_values(_version, &major, &minor, µ);
+ return major == 1 && minor == 1; // micro version doesn't matter here
+}
+
+
+JvmtiEnvBase::JvmtiEnvBase(jint version) : _env_event_enable() {
+ _version = version;
_env_local_storage = NULL;
_tag_map = NULL;
_native_method_prefix_count = 0;
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,6 +76,7 @@
jvmtiEnv _jvmti_external;
jint _magic;
+ jint _version; // version value passed to JNI GetEnv()
JvmtiEnvBase* _next;
bool _is_retransformable;
const void *_env_local_storage; // per env agent allocated data.
@@ -91,7 +92,7 @@
int _native_method_prefix_count;
protected:
- JvmtiEnvBase();
+ JvmtiEnvBase(jint version);
~JvmtiEnvBase();
void dispose();
void env_dispose();
@@ -122,6 +123,9 @@
bool is_valid();
+ bool use_version_1_0_semantics(); // agent asked for version 1.0
+ bool use_version_1_1_semantics(); // agent asked for version 1.1
+
bool is_retransformable() { return _is_retransformable; }
static ByteSize jvmti_external_offset() {
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -319,7 +319,27 @@
jint
JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
- /* To Do: add version checks */
+ // The JVMTI_VERSION_INTERFACE_JVMTI part of the version number
+ // has already been validated in JNI GetEnv().
+ int major, minor, micro;
+
+ // micro version doesn't matter here (yet?)
+ decode_version_values(version, &major, &minor, µ);
+ switch (major) {
+ case 1:
+ switch (minor) {
+ case 0: // version 1.0.<micro> is recognized
+ case 1: // version 1.1.<micro> is recognized
+ break;
+
+ default:
+ return JNI_EVERSION; // unsupported minor version number
+ }
+ break;
+
+ default:
+ return JNI_EVERSION; // unsupported major version number
+ }
if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {
JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread();
@@ -328,13 +348,13 @@
__ENTRY(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
debug_only(VMNativeEntryWrapper __vew;)
- JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti();
+ JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);
*penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv*
return JNI_OK;
} else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) {
// not live, no thread to transition
- JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti();
+ JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);
*penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv*
return JNI_OK;
@@ -345,6 +365,15 @@
}
}
+
+void
+JvmtiExport::decode_version_values(jint version, int * major, int * minor,
+ int * micro) {
+ *major = (version & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR;
+ *minor = (version & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR;
+ *micro = (version & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO;
+}
+
void JvmtiExport::enter_primordial_phase() {
JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL);
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc. 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
@@ -236,6 +236,8 @@
static bool is_jvmti_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMTI_VERSION_VALUE; }
static bool is_jvmdi_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE; }
static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version);
+ static void decode_version_values(jint version, int * major, int * minor,
+ int * micro);
// single stepping management methods
static void at_single_stepping_point(JavaThread *thread, methodOop method, address location) KERNEL_RETURN;
--- a/hotspot/src/share/vm/prims/jvmtiHpp.xsl Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiHpp.xsl Wed Jul 05 17:04:56 2017 +0200
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
- Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
+ Copyright 2002-2009 Sun Microsystems, Inc. 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,12 +48,12 @@
private:
- JvmtiEnv();
+ JvmtiEnv(jint version);
~JvmtiEnv();
public:
- static JvmtiEnv* create_a_jvmti();
+ static JvmtiEnv* create_a_jvmti(jint version);
</xsl:text>
<xsl:apply-templates select="functionsection"/>
--- a/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -115,8 +115,10 @@
jvmtiCapabilities jc;
memset(&jc, 0, sizeof(jc));
+#ifndef CC_INTERP
jc.can_pop_frame = 1;
jc.can_force_early_return = 1;
+#endif // !CC_INTERP
jc.can_get_source_debug_extension = 1;
jc.can_access_local_variables = 1;
jc.can_maintain_original_method_order = 1;
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -2347,9 +2347,9 @@
JVM_ENTRY(void, MH_linkCallSite(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
// No special action required, yet.
oop site_oop = JNIHandles::resolve(site_jh);
- if (site_oop == NULL || site_oop->klass() != SystemDictionary::CallSiteImpl_klass())
+ if (site_oop == NULL || site_oop->klass() != SystemDictionary::CallSite_klass())
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "call site");
- sun_dyn_CallSiteImpl::set_target(site_oop, JNIHandles::resolve(target_jh));
+ java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
}
JVM_END
@@ -2365,6 +2365,7 @@
#define OBJ LANG"Object;"
#define CLS LANG"Class;"
#define STRG LANG"String;"
+#define CST JDYN"CallSite;"
#define MT JDYN"MethodType;"
#define MH JDYN"MethodHandle;"
#define MHI IDYN"MethodHandleImpl;"
@@ -2372,7 +2373,6 @@
#define AMH IDYN"AdapterMethodHandle;"
#define BMH IDYN"BoundMethodHandle;"
#define DMH IDYN"DirectMethodHandle;"
-#define CSTI IDYN"CallSiteImpl;"
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -2398,7 +2398,7 @@
// More entry points specifically for EnableInvokeDynamic.
static JNINativeMethod methods2[] = {
- {CC"linkCallSite", CC"("CSTI MH")V", FN_PTR(MH_linkCallSite)}
+ {CC"linkCallSite", CC"("CST MH")V", FN_PTR(MH_linkCallSite)}
};
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -37,7 +37,6 @@
const char* Arguments::_gc_log_filename = NULL;
bool Arguments::_has_profile = false;
bool Arguments::_has_alloc_profile = false;
-uintx Arguments::_initial_heap_size = 0;
uintx Arguments::_min_heap_size = 0;
Arguments::Mode Arguments::_mode = _mixed;
bool Arguments::_java_compiler = false;
@@ -182,6 +181,9 @@
{ "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) },
{ "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) },
{ "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) },
+ { "DefaultMaxRAM", JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) },
+ { "DefaultInitialRAMFraction",
+ JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) },
{ NULL, JDK_Version(0), JDK_Version(0) }
};
@@ -555,6 +557,10 @@
if (!is_neg && CommandLineFlags::uintxAtPut(name, &uintx_v, origin)) {
return true;
}
+ uint64_t uint64_t_v = (uint64_t) v;
+ if (!is_neg && CommandLineFlags::uint64_tAtPut(name, &uint64_t_v, origin)) {
+ return true;
+ }
return false;
}
@@ -947,7 +953,7 @@
// UseParNewGC and not explicitly set ParallelGCThreads we
// set it, unless this is a single cpu machine.
void Arguments::set_parnew_gc_flags() {
- assert(!UseSerialGC && !UseParallelGC && !UseG1GC,
+ assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC && !UseG1GC,
"control point invariant");
assert(UseParNewGC, "Error");
@@ -960,13 +966,13 @@
if (ParallelGCThreads == 0) {
FLAG_SET_DEFAULT(ParallelGCThreads,
Abstract_VM_Version::parallel_worker_threads());
- if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
+ if (ParallelGCThreads == 1) {
FLAG_SET_DEFAULT(UseParNewGC, false);
+ FLAG_SET_DEFAULT(ParallelGCThreads, 0);
}
}
- if (!UseParNewGC) {
- FLAG_SET_DEFAULT(ParallelGCThreads, 0);
- } else {
+ if (UseParNewGC) {
+ // CDS doesn't work with ParNew yet
no_shared_spaces();
// By default YoungPLABSize and OldPLABSize are set to 4096 and 1024 respectively,
@@ -980,7 +986,7 @@
FLAG_SET_DEFAULT(OldPLABSize, (intx)1024);
}
- // AlwaysTenure flag should make ParNew to promote all at first collection.
+ // AlwaysTenure flag should make ParNew promote all at first collection.
// See CR 6362902.
if (AlwaysTenure) {
FLAG_SET_CMDLINE(intx, MaxTenuringThreshold, 0);
@@ -1003,7 +1009,7 @@
// further optimization and tuning efforts, and would almost
// certainly gain from analysis of platform and environment.
void Arguments::set_cms_and_parnew_gc_flags() {
- assert(!UseSerialGC && !UseParallelGC, "Error");
+ assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC, "Error");
assert(UseConcMarkSweepGC, "CMS is expected to be on here");
// If we are using CMS, we prefer to UseParNewGC,
@@ -1068,7 +1074,7 @@
} else {
FLAG_SET_ERGO(uintx, MaxNewSize, preferred_max_new_size);
}
- if(PrintGCDetails && Verbose) {
+ if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
tty->print_cr("Ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
}
@@ -1097,15 +1103,15 @@
} else {
min_new = NewSize;
}
- size_t prev_initial_size = initial_heap_size();
- if (prev_initial_size != 0 && prev_initial_size < min_new+OldSize) {
- set_initial_heap_size(min_new+OldSize);
+ size_t prev_initial_size = InitialHeapSize;
+ if (prev_initial_size != 0 && prev_initial_size < min_new + OldSize) {
+ FLAG_SET_ERGO(uintx, InitialHeapSize, min_new + OldSize);
// Currently minimum size and the initial heap sizes are the same.
- set_min_heap_size(initial_heap_size());
+ set_min_heap_size(InitialHeapSize);
if (PrintGCDetails && Verbose) {
warning("Initial heap size increased to " SIZE_FORMAT " M from "
SIZE_FORMAT " M; use -XX:NewSize=... for finer control.",
- initial_heap_size()/M, prev_initial_size/M);
+ InitialHeapSize/M, prev_initial_size/M);
}
}
@@ -1114,12 +1120,12 @@
align_size_down(MaxHeapSize,
CardTableRS::ct_max_alignment_constraint());
- if(PrintGCDetails && Verbose) {
+ if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT
" initial_heap_size: " SIZE_FORMAT
" max_heap: " SIZE_FORMAT,
- min_heap_size(), initial_heap_size(), max_heap);
+ min_heap_size(), InitialHeapSize, max_heap);
}
if (max_heap > min_new) {
// Unless explicitly requested otherwise, make young gen
@@ -1127,7 +1133,7 @@
if (FLAG_IS_DEFAULT(NewSize)) {
FLAG_SET_ERGO(uintx, NewSize, MAX2(NewSize, min_new));
FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize));
- if(PrintGCDetails && Verbose) {
+ if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
tty->print_cr("Ergo set NewSize: " SIZE_FORMAT, NewSize);
}
@@ -1137,8 +1143,8 @@
// later NewRatio will decide how it grows; see above.
if (FLAG_IS_DEFAULT(OldSize)) {
if (max_heap > NewSize) {
- FLAG_SET_ERGO(uintx, OldSize, MIN2(3*NewSize, max_heap - NewSize));
- if(PrintGCDetails && Verbose) {
+ FLAG_SET_ERGO(uintx, OldSize, MIN2(3*NewSize, max_heap - NewSize));
+ if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
tty->print_cr("Ergo set OldSize: " SIZE_FORMAT, OldSize);
}
@@ -1186,7 +1192,7 @@
inline uintx max_heap_for_compressed_oops() {
LP64_ONLY(return oopDesc::OopEncodingHeapMax - MaxPermSize - os::vm_page_size());
- NOT_LP64(return DefaultMaxRAM);
+ NOT_LP64(ShouldNotReachHere(); return 0);
}
bool Arguments::should_auto_select_low_pause_collector() {
@@ -1205,7 +1211,7 @@
void Arguments::set_ergonomics_flags() {
// Parallel GC is not compatible with sharing. If one specifies
- // that they want sharing explicitly, do not set ergonmics flags.
+ // that they want sharing explicitly, do not set ergonomics flags.
if (DumpSharedSpaces || ForceSharedSpaces) {
return;
}
@@ -1234,9 +1240,11 @@
// Check that UseCompressedOops can be set with the max heap size allocated
// by ergonomics.
if (MaxHeapSize <= max_heap_for_compressed_oops()) {
+#ifndef COMPILER1
if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {
FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
+#endif
#ifdef _WIN64
if (UseLargePages && UseCompressedOops) {
// Cannot allocate guard pages for implicit checks in indexed addressing
@@ -1271,8 +1279,6 @@
FLAG_SET_ERGO(uintx, ParallelGCThreads,
Abstract_VM_Version::parallel_worker_threads());
- // PS is a server collector, setup the heap sizes accordingly.
- set_server_heap_size();
// If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the
// SurvivorRatio has been set, reset their default values to SurvivorRatio +
// 2. By doing this we make SurvivorRatio also work for Parallel Scavenger.
@@ -1302,8 +1308,6 @@
void Arguments::set_g1_gc_flags() {
assert(UseG1GC, "Error");
- // G1 is a server collector, setup the heap sizes accordingly.
- set_server_heap_size();
#ifdef COMPILER1
FastTLABRefill = false;
#endif
@@ -1321,50 +1325,79 @@
}
}
-void Arguments::set_server_heap_size() {
+void Arguments::set_heap_size() {
+ if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
+ // Deprecated flag
+ FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction);
+ }
+
+ const julong phys_mem =
+ FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
+ : (julong)MaxRAM;
+
+ // If the maximum heap size has not been set with -Xmx,
+ // then set it as fraction of the size of physical memory,
+ // respecting the maximum and minimum sizes of the heap.
if (FLAG_IS_DEFAULT(MaxHeapSize)) {
- const uint64_t reasonable_fraction =
- os::physical_memory() / DefaultMaxRAMFraction;
- const uint64_t maximum_size = (uint64_t)
- (FLAG_IS_DEFAULT(DefaultMaxRAM) && UseCompressedOops ?
- MIN2(max_heap_for_compressed_oops(), DefaultMaxRAM) :
- DefaultMaxRAM);
- size_t reasonable_max =
- (size_t) os::allocatable_physical_memory(reasonable_fraction);
- if (reasonable_max > maximum_size) {
- reasonable_max = maximum_size;
+ julong reasonable_max = phys_mem / MaxRAMFraction;
+
+ if (phys_mem <= MaxHeapSize * MinRAMFraction) {
+ // Small physical memory, so use a minimum fraction of it for the heap
+ reasonable_max = phys_mem / MinRAMFraction;
+ } else {
+ // Not-small physical memory, so require a heap at least
+ // as large as MaxHeapSize
+ reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize);
+ }
+ if (!FLAG_IS_DEFAULT(ErgoHeapSizeLimit) && ErgoHeapSizeLimit != 0) {
+ // Limit the heap size to ErgoHeapSizeLimit
+ reasonable_max = MIN2(reasonable_max, (julong)ErgoHeapSizeLimit);
}
+ if (UseCompressedOops) {
+ // Limit the heap size to the maximum possible when using compressed oops
+ reasonable_max = MIN2(reasonable_max, (julong)max_heap_for_compressed_oops());
+ }
+ reasonable_max = os::allocatable_physical_memory(reasonable_max);
+
+ if (!FLAG_IS_DEFAULT(InitialHeapSize)) {
+ // An initial heap size was specified on the command line,
+ // so be sure that the maximum size is consistent. Done
+ // after call to allocatable_physical_memory because that
+ // method might reduce the allocation size.
+ reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize);
+ }
+
if (PrintGCDetails && Verbose) {
// Cannot use gclog_or_tty yet.
- tty->print_cr(" Max heap size for server class platform "
- SIZE_FORMAT, reasonable_max);
+ tty->print_cr(" Maximum heap size " SIZE_FORMAT, reasonable_max);
}
- // If the initial_heap_size has not been set with -Xms,
- // then set it as fraction of size of physical memory
- // respecting the maximum and minimum sizes of the heap.
- if (initial_heap_size() == 0) {
- const uint64_t reasonable_initial_fraction =
- os::physical_memory() / DefaultInitialRAMFraction;
- const size_t reasonable_initial =
- (size_t) os::allocatable_physical_memory(reasonable_initial_fraction);
- const size_t minimum_size = NewSize + OldSize;
- set_initial_heap_size(MAX2(MIN2(reasonable_initial, reasonable_max),
- minimum_size));
- // Currently the minimum size and the initial heap sizes are the same.
- set_min_heap_size(initial_heap_size());
- if (PrintGCDetails && Verbose) {
- // Cannot use gclog_or_tty yet.
- tty->print_cr(" Initial heap size for server class platform "
- SIZE_FORMAT, initial_heap_size());
- }
- } else {
- // A minimum size was specified on the command line. Be sure
- // that the maximum size is consistent.
- if (initial_heap_size() > reasonable_max) {
- reasonable_max = initial_heap_size();
- }
+ FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max);
+ }
+
+ // If the initial_heap_size has not been set with InitialHeapSize
+ // or -Xms, then set it as fraction of the size of physical memory,
+ // respecting the maximum and minimum sizes of the heap.
+ if (FLAG_IS_DEFAULT(InitialHeapSize)) {
+ julong reasonable_minimum = (julong)(OldSize + NewSize);
+
+ reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);
+
+ reasonable_minimum = os::allocatable_physical_memory(reasonable_minimum);
+
+ julong reasonable_initial = phys_mem / InitialRAMFraction;
+
+ reasonable_initial = MAX2(reasonable_initial, reasonable_minimum);
+ reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
+
+ reasonable_initial = os::allocatable_physical_memory(reasonable_initial);
+
+ if (PrintGCDetails && Verbose) {
+ // Cannot use gclog_or_tty yet.
+ tty->print_cr(" Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial);
+ tty->print_cr(" Minimum heap size " SIZE_FORMAT, (uintx)reasonable_minimum);
}
- FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx) reasonable_max);
+ FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial);
+ set_min_heap_size((uintx)reasonable_minimum);
}
}
@@ -1448,7 +1481,7 @@
return false;
}
-static void set_serial_gc_flags() {
+static void force_serial_gc() {
FLAG_SET_DEFAULT(UseSerialGC, true);
FLAG_SET_DEFAULT(UseParNewGC, false);
FLAG_SET_DEFAULT(UseConcMarkSweepGC, false);
@@ -1584,15 +1617,15 @@
// force sharing off.
if (DumpSharedSpaces || ForceSharedSpaces) {
jio_fprintf(defaultStream::error_stream(),
- "Reverting to Serial GC because of %s \n",
+ "Reverting to Serial GC because of %s\n",
ForceSharedSpaces ? " -Xshare:on" : "-Xshare:dump");
- set_serial_gc_flags();
+ force_serial_gc();
FLAG_SET_DEFAULT(SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages), false);
} else {
- if (UseSharedSpaces) {
+ if (UseSharedSpaces && Verbose) {
jio_fprintf(defaultStream::error_stream(),
"Turning off use of shared archive because of "
- "choice of garbage collector or large pages \n");
+ "choice of garbage collector or large pages\n");
}
no_shared_spaces();
}
@@ -1925,8 +1958,8 @@
describe_range_error(errcode);
return JNI_EINVAL;
}
- FLAG_SET_CMDLINE(uintx, MaxNewSize, (size_t) long_initial_eden_size);
- FLAG_SET_CMDLINE(uintx, NewSize, (size_t) long_initial_eden_size);
+ FLAG_SET_CMDLINE(uintx, MaxNewSize, (uintx)long_initial_eden_size);
+ FLAG_SET_CMDLINE(uintx, NewSize, (uintx)long_initial_eden_size);
// -Xms
} else if (match_option(option, "-Xms", &tail)) {
julong long_initial_heap_size = 0;
@@ -1937,9 +1970,9 @@
describe_range_error(errcode);
return JNI_EINVAL;
}
- set_initial_heap_size((size_t) long_initial_heap_size);
+ FLAG_SET_CMDLINE(uintx, InitialHeapSize, (uintx)long_initial_heap_size);
// Currently the minimum size and the initial heap sizes are the same.
- set_min_heap_size(initial_heap_size());
+ set_min_heap_size(InitialHeapSize);
// -Xmx
} else if (match_option(option, "-Xmx", &tail)) {
julong long_max_heap_size = 0;
@@ -1950,7 +1983,7 @@
describe_range_error(errcode);
return JNI_EINVAL;
}
- FLAG_SET_CMDLINE(uintx, MaxHeapSize, (size_t) long_max_heap_size);
+ FLAG_SET_CMDLINE(uintx, MaxHeapSize, (uintx)long_max_heap_size);
// Xmaxf
} else if (match_option(option, "-Xmaxf", &tail)) {
int maxf = (int)(atof(tail) * 100);
@@ -2196,9 +2229,9 @@
if (FLAG_IS_DEFAULT(MaxHeapSize)) {
FLAG_SET_CMDLINE(uintx, MaxHeapSize, initHeapSize);
- set_initial_heap_size(MaxHeapSize);
+ FLAG_SET_CMDLINE(uintx, InitialHeapSize, initHeapSize);
// Currently the minimum size and the initial heap sizes are the same.
- set_min_heap_size(initial_heap_size());
+ set_min_heap_size(initHeapSize);
}
if (FLAG_IS_DEFAULT(NewSize)) {
// Make the young generation 3/8ths of the total heap.
@@ -2675,8 +2708,12 @@
}
}
+#if defined(_LP64) && defined(COMPILER1)
+ UseCompressedOops = false;
+#endif
+
#ifdef SERIALGC
- set_serial_gc_flags();
+ force_serial_gc();
#endif // SERIALGC
#ifdef KERNEL
no_shared_spaces();
@@ -2690,18 +2727,22 @@
return JNI_EINVAL;
}
- if (UseParallelGC || UseParallelOldGC) {
- // Set some flags for ParallelGC if needed.
- set_parallel_gc_flags();
- } else if (UseConcMarkSweepGC) {
- // Set some flags for CMS
+ if (UseConcMarkSweepGC) {
+ // Set flags for CMS and ParNew. Check UseConcMarkSweep first
+ // to ensure that when both UseConcMarkSweepGC and UseParNewGC
+ // are true, we don't call set_parnew_gc_flags() as well.
set_cms_and_parnew_gc_flags();
- } else if (UseParNewGC) {
- // Set some flags for ParNew
- set_parnew_gc_flags();
- } else if (UseG1GC) {
- // Set some flags for garbage-first, if needed.
- set_g1_gc_flags();
+ } else {
+ // Set heap size based on available physical memory
+ set_heap_size();
+ // Set per-collector flags
+ if (UseParallelGC || UseParallelOldGC) {
+ set_parallel_gc_flags();
+ } else if (UseParNewGC) {
+ set_parnew_gc_flags();
+ } else if (UseG1GC) {
+ set_g1_gc_flags();
+ }
}
#ifdef SERIALGC
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -254,7 +254,6 @@
static bool _has_profile;
static bool _has_alloc_profile;
static const char* _gc_log_filename;
- static uintx _initial_heap_size;
static uintx _min_heap_size;
// -Xrun arguments
@@ -300,8 +299,8 @@
static void set_g1_gc_flags();
// GC ergonomics
static void set_ergonomics_flags();
- // Setup heap size for a server platform
- static void set_server_heap_size();
+ // Setup heap size
+ static void set_heap_size();
// Based on automatic selection criteria, should the
// low pause collector be used.
static bool should_auto_select_low_pause_collector();
@@ -434,9 +433,7 @@
static bool has_profile() { return _has_profile; }
static bool has_alloc_profile() { return _has_alloc_profile; }
- // -Xms , -Xmx
- static uintx initial_heap_size() { return _initial_heap_size; }
- static void set_initial_heap_size(uintx v) { _initial_heap_size = v; }
+ // -Xms, -Xmx
static uintx min_heap_size() { return _min_heap_size; }
static void set_min_heap_size(uintx v) { _min_heap_size = v; }
--- a/hotspot/src/share/vm/runtime/frame.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/frame.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -1190,9 +1190,19 @@
void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
- if (is_interpreted_frame()) { oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
- } else if (is_entry_frame()) { oops_entry_do (f, map);
- } else if (CodeCache::contains(pc())) { oops_code_blob_do (f, cf, map);
+#ifndef PRODUCT
+ // simulate GC crash here to dump java thread in error report
+ if (CrashGCForDumpingJavaThread) {
+ char *t = NULL;
+ *t = 'c';
+ }
+#endif
+ if (is_interpreted_frame()) {
+ oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
+ } else if (is_entry_frame()) {
+ oops_entry_do(f, map);
+ } else if (CodeCache::contains(pc())) {
+ oops_code_blob_do(f, cf, map);
} else {
ShouldNotReachHere();
}
--- a/hotspot/src/share/vm/runtime/globals.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/globals.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -46,7 +46,8 @@
bool Flag::is_unlocked() const {
if (strcmp(kind, "{diagnostic}") == 0) {
return UnlockDiagnosticVMOptions;
- } else if (strcmp(kind, "{experimental}") == 0) {
+ } else if (strcmp(kind, "{experimental}") == 0 ||
+ strcmp(kind, "{C2 experimental}") == 0) {
return UnlockExperimentalVMOptions;
} else {
return true;
@@ -69,9 +70,10 @@
void Flag::print_on(outputStream* st) {
st->print("%5s %-35s %c= ", type, name, (origin != DEFAULT ? ':' : ' '));
- if (is_bool()) st->print("%-16s", get_bool() ? "true" : "false");
- if (is_intx()) st->print("%-16ld", get_intx());
- if (is_uintx()) st->print("%-16lu", get_uintx());
+ if (is_bool()) st->print("%-16s", get_bool() ? "true" : "false");
+ if (is_intx()) st->print("%-16ld", get_intx());
+ if (is_uintx()) st->print("%-16lu", get_uintx());
+ if (is_uint64_t()) st->print("%-16lu", get_uint64_t());
if (is_ccstr()) {
const char* cp = get_ccstr();
if (cp != NULL) {
@@ -100,6 +102,8 @@
st->print("-XX:%s=" INTX_FORMAT, name, get_intx());
} else if (is_uintx()) {
st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx());
+ } else if (is_uint64_t()) {
+ st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t());
} else if (is_ccstr()) {
st->print("-XX:%s=", name);
const char* cp = get_ccstr();
@@ -166,6 +170,7 @@
#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 product}", DEFAULT },
#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{C2 pd product}", DEFAULT },
#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 diagnostic}", DEFAULT },
+#define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 experimental}", DEFAULT },
#ifdef PRODUCT
#define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
#define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */
@@ -187,7 +192,7 @@
C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
#endif
#ifdef COMPILER2
- C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
+ C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
#endif
{0, NULL, NULL}
};
@@ -324,6 +329,32 @@
faddr->origin = origin;
}
+bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_uint64_t()) return false;
+ *value = result->get_uint64_t();
+ return true;
+}
+
+bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_uint64_t()) return false;
+ uint64_t old_value = result->get_uint64_t();
+ result->set_uint64_t(*value);
+ *value = old_value;
+ result->origin = origin;
+ return true;
+}
+
+void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin) {
+ Flag* faddr = address_of_flag(flag);
+ guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
+ faddr->set_uint64_t(value);
+ faddr->origin = origin;
+}
+
bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return false;
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -47,8 +47,8 @@
define_pd_global(intx, OnStackReplacePercentage, 0);
define_pd_global(bool, ResizeTLAB, false);
define_pd_global(intx, FreqInlineSize, 0);
+define_pd_global(intx, InlineSmallCode, 0);
define_pd_global(intx, NewSizeThreadIncrease, 4*K);
-define_pd_global(intx, NewRatio, 4);
define_pd_global(intx, InlineClassNatives, true);
define_pd_global(intx, InlineUnsafeOps, true);
define_pd_global(intx, InitialCodeCacheSize, 160*K);
@@ -58,7 +58,7 @@
define_pd_global(uintx,PermSize, ScaleForWordSize(4*M));
define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
define_pd_global(bool, NeverActAsServerClassMachine, true);
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 1ULL*G);
#define CI_COMPILER_COUNT 0
#else
@@ -113,6 +113,10 @@
uintx get_uintx() const { return *((uintx*) addr); }
void set_uintx(uintx value) { *((uintx*) addr) = value; }
+ bool is_uint64_t() const { return strcmp(type, "uint64_t") == 0; }
+ uint64_t get_uint64_t() const { return *((uint64_t*) addr); }
+ void set_uint64_t(uint64_t value) { *((uint64_t*) addr) = value; }
+
bool is_double() const { return strcmp(type, "double") == 0; }
double get_double() const { return *((double*) addr); }
void set_double(double value) { *((double*) addr) = value; }
@@ -188,6 +192,11 @@
static bool uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin);
static bool uintxAtPut(char* name, uintx* value, FlagValueOrigin origin) { return uintxAtPut(name, strlen(name), value, origin); }
+ static bool uint64_tAt(char* name, size_t len, uint64_t* value);
+ static bool uint64_tAt(char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
+ static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin);
+ static bool uint64_tAtPut(char* name, uint64_t* value, FlagValueOrigin origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
+
static bool doubleAt(char* name, size_t len, double* value);
static bool doubleAt(char* name, double* value) { return doubleAt(name, strlen(name), value); }
static bool doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin);
@@ -785,7 +794,7 @@
product(bool, ProfilerRecordPC, false, \
"Collects tick for each 16 byte interval of compiled code") \
\
- product(bool, ProfileVM, false, \
+ product(bool, ProfileVM, false, \
"Profiles ticks that fall within VM (either in the VM Thread " \
"or VM code called through stubs)") \
\
@@ -815,7 +824,7 @@
\
product(bool, RegisterFinalizersAtInit, true, \
"Register finalizable objects at end of Object.<init> or " \
- "after allocation.") \
+ "after allocation") \
\
develop(bool, RegisterReferences, true, \
"Tells whether the VM should register soft/weak/final/phantom " \
@@ -862,14 +871,14 @@
product(bool, AlwaysLockClassLoader, false, \
"Require the VM to acquire the class loader lock before calling " \
"loadClass() even for class loaders registering " \
- "as parallel capable. Default false. ") \
+ "as parallel capable") \
\
product(bool, AllowParallelDefineClass, false, \
"Allow parallel defineClass requests for class loaders " \
- "registering as parallel capable. Default false") \
+ "registering as parallel capable") \
\
product(bool, MustCallLoadClassInternal, false, \
- "Call loadClassInternal() rather than loadClass().Default false") \
+ "Call loadClassInternal() rather than loadClass()") \
\
product_pd(bool, DontYieldALot, \
"Throw away obvious excess yield calls (for SOLARIS only)") \
@@ -921,9 +930,9 @@
"(Unstable, Linux-specific)" \
" avoid NPTL-FUTEX hang pthread_cond_timedwait" ) \
\
- product(bool, FilterSpuriousWakeups , true, \
- "Prevent spurious or premature wakeups from object.wait" \
- "(Solaris only)") \
+ product(bool, FilterSpuriousWakeups, true, \
+ "Prevent spurious or premature wakeups from object.wait " \
+ "(Solaris only)") \
\
product(intx, NativeMonitorTimeout, -1, "(Unstable)" ) \
product(intx, NativeMonitorFlags, 0, "(Unstable)" ) \
@@ -973,7 +982,7 @@
\
product(bool, UseAltSigs, false, \
"Use alternate signals instead of SIGUSR1 & SIGUSR2 for VM " \
- "internal signals. (Solaris only)") \
+ "internal signals (Solaris only)") \
\
product(bool, UseSpinning, false, \
"Use spinning in monitor inflation and before entry") \
@@ -1265,12 +1274,12 @@
"Always tenure objects in eden. (ParallelGC only)") \
\
product(bool, NeverTenure, false, \
- "Never tenure objects in eden, May tenure on overflow" \
- " (ParallelGC only)") \
+ "Never tenure objects in eden, May tenure on overflow " \
+ "(ParallelGC only)") \
\
product(bool, ScavengeBeforeFullGC, true, \
- "Scavenge youngest generation before each full GC," \
- " used with UseParallelGC") \
+ "Scavenge youngest generation before each full GC, " \
+ "used with UseParallelGC") \
\
develop(bool, ScavengeWithObjectsInToSpace, false, \
"Allow scavenges to occur when to_space contains objects.") \
@@ -1283,9 +1292,9 @@
" (effective only when UseConcMarkSweepGC)") \
\
product(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false, \
- "A System.gc() request invokes a concurrent collection and" \
- " also unloads classes during such a concurrent gc cycle " \
- " (effective only when UseConcMarkSweepGC)") \
+ "A System.gc() request invokes a concurrent collection and " \
+ "also unloads classes during such a concurrent gc cycle " \
+ "(effective only when UseConcMarkSweepGC)") \
\
develop(bool, UseCMSAdaptiveFreeLists, true, \
"Use Adaptive Free Lists in the CMS generation") \
@@ -1340,8 +1349,8 @@
"Whether we should simulate work queue overflow in ParNew") \
\
notproduct(uintx, ParGCWorkQueueOverflowInterval, 1000, \
- "An `interval' counter that determines how frequently" \
- " we simulate overflow; a smaller number increases frequency") \
+ "An `interval' counter that determines how frequently " \
+ "we simulate overflow; a smaller number increases frequency") \
\
product(uintx, ParGCDesiredObjsFromOverflowList, 20, \
"The desired number of objects to claim from the overflow list") \
@@ -1354,12 +1363,12 @@
"It forces all freshly committed pages to be pre-touched.") \
\
product(bool, CMSUseOldDefaults, false, \
- "A flag temporarily introduced to allow reverting to some older" \
- "default settings; older as of 6.0 ") \
+ "A flag temporarily introduced to allow reverting to some " \
+ "older default settings; older as of 6.0") \
\
product(intx, CMSYoungGenPerWorker, 16*M, \
"The amount of young gen chosen by default per GC worker " \
- "thread available ") \
+ "thread available") \
\
product(bool, GCOverheadReporting, false, \
"Enables the GC overhead reporting facility") \
@@ -1380,43 +1389,44 @@
"automatically adjusted") \
\
product(uintx, CMSIncrementalDutyCycleMin, 0, \
- "Lower bound on the duty cycle when CMSIncrementalPacing is" \
- "enabled (a percentage, 0-100).") \
+ "Lower bound on the duty cycle when CMSIncrementalPacing is " \
+ "enabled (a percentage, 0-100)") \
\
product(uintx, CMSIncrementalSafetyFactor, 10, \
- "Percentage (0-100) used to add conservatism when computing the" \
- "duty cycle.") \
+ "Percentage (0-100) used to add conservatism when computing the " \
+ "duty cycle") \
\
product(uintx, CMSIncrementalOffset, 0, \
"Percentage (0-100) by which the CMS incremental mode duty cycle" \
- "is shifted to the right within the period between young GCs") \
+ " is shifted to the right within the period between young GCs") \
\
product(uintx, CMSExpAvgFactor, 25, \
- "Percentage (0-100) used to weight the current sample when" \
- "computing exponential averages for CMS statistics.") \
+ "Percentage (0-100) used to weight the current sample when " \
+ "computing exponential averages for CMS statistics") \
\
product(uintx, CMS_FLSWeight, 50, \
- "Percentage (0-100) used to weight the current sample when" \
- "computing exponentially decating averages for CMS FLS statistics.") \
+ "Percentage (0-100) used to weight the current sample when " \
+ "computing exponentially decating averages for CMS FLS statistics") \
\
product(uintx, CMS_FLSPadding, 2, \
- "The multiple of deviation from mean to use for buffering" \
+ "The multiple of deviation from mean to use for buffering " \
"against volatility in free list demand.") \
\
product(uintx, FLSCoalescePolicy, 2, \
"CMS: Aggression level for coalescing, increasing from 0 to 4") \
\
product(uintx, CMS_SweepWeight, 50, \
- "Percentage (0-100) used to weight the current sample when" \
- "computing exponentially decaying average for inter-sweep duration.") \
+ "Percentage (0-100) used to weight the current sample when " \
+ "computing exponentially decaying average for inter-sweep " \
+ "duration") \
\
product(uintx, CMS_SweepPadding, 2, \
- "The multiple of deviation from mean to use for buffering" \
+ "The multiple of deviation from mean to use for buffering " \
"against volatility in inter-sweep duration.") \
\
product(uintx, CMS_SweepTimerThresholdMillis, 10, \
"Skip block flux-rate sampling for an epoch unless inter-sweep " \
- " duration exceeds this threhold in milliseconds") \
+ "duration exceeds this threhold in milliseconds") \
\
develop(bool, CMSTraceIncrementalMode, false, \
"Trace CMS incremental mode") \
@@ -1617,35 +1627,36 @@
\
product(intx, CMSTriggerRatio, 80, \
"Percentage of MinHeapFreeRatio in CMS generation that is " \
- " allocated before a CMS collection cycle commences") \
+ "allocated before a CMS collection cycle commences") \
\
product(intx, CMSTriggerPermRatio, 80, \
- "Percentage of MinHeapFreeRatio in the CMS perm generation that" \
- " is allocated before a CMS collection cycle commences, that " \
- " also collects the perm generation") \
+ "Percentage of MinHeapFreeRatio in the CMS perm generation that " \
+ "is allocated before a CMS collection cycle commences, that " \
+ "also collects the perm generation") \
\
product(uintx, CMSBootstrapOccupancy, 50, \
"Percentage CMS generation occupancy at which to " \
- " initiate CMS collection for bootstrapping collection stats") \
+ "initiate CMS collection for bootstrapping collection stats") \
\
product(intx, CMSInitiatingOccupancyFraction, -1, \
"Percentage CMS generation occupancy to start a CMS collection " \
- " cycle (A negative value means that CMSTriggerRatio is used)") \
+ "cycle. A negative value means that CMSTriggerRatio is used") \
\
product(intx, CMSInitiatingPermOccupancyFraction, -1, \
- "Percentage CMS perm generation occupancy to start a CMScollection"\
- " cycle (A negative value means that CMSTriggerPermRatio is used)")\
+ "Percentage CMS perm generation occupancy to start a " \
+ "CMScollection cycle. A negative value means that " \
+ "CMSTriggerPermRatio is used") \
\
product(bool, UseCMSInitiatingOccupancyOnly, false, \
"Only use occupancy as a crierion for starting a CMS collection") \
\
product(intx, CMSIsTooFullPercentage, 98, \
- "An absolute ceiling above which CMS will always consider the" \
- " perm gen ripe for collection") \
+ "An absolute ceiling above which CMS will always consider the " \
+ "perm gen ripe for collection") \
\
develop(bool, CMSTestInFreeList, false, \
"Check if the coalesced range is already in the " \
- "free lists as claimed.") \
+ "free lists as claimed") \
\
notproduct(bool, CMSVerifyReturnedBytes, false, \
"Check that all the garbage collected was returned to the " \
@@ -1663,8 +1674,8 @@
"Enforce ScavengeALot/GCALot at all potential safepoints") \
\
product(bool, HandlePromotionFailure, true, \
- "The youngest generation collection does not require" \
- " a guarantee of full promotion of all live objects.") \
+ "The youngest generation collection does not require " \
+ "a guarantee of full promotion of all live objects.") \
\
notproduct(bool, PromotionFailureALot, false, \
"Use promotion failure handling on every youngest generation " \
@@ -1692,7 +1703,7 @@
"Ratio of hard spins to calls to yield") \
\
product(uintx, PreserveMarkStackSize, 1024, \
- "Size for stack used in promotion failure handling") \
+ "Size for stack used in promotion failure handling") \
\
product_pd(bool, UseTLAB, "Use thread-local object allocation") \
\
@@ -1720,14 +1731,27 @@
product(bool, AlwaysActAsServerClassMachine, false, \
"Always act like a server-class machine") \
\
- product_pd(uintx, DefaultMaxRAM, \
- "Maximum real memory size for setting server class heap size") \
+ product_pd(uint64_t, MaxRAM, \
+ "Real memory size (in bytes) used to set maximum heap size") \
+ \
+ product(uintx, ErgoHeapSizeLimit, 0, \
+ "Maximum ergonomically set heap size (in bytes); zero means use " \
+ "MaxRAM / MaxRAMFraction") \
+ \
+ product(uintx, MaxRAMFraction, 4, \
+ "Maximum fraction (1/n) of real memory used for maximum heap " \
+ "size") \
\
product(uintx, DefaultMaxRAMFraction, 4, \
- "Fraction (1/n) of real memory used for server class max heap") \
- \
- product(uintx, DefaultInitialRAMFraction, 64, \
- "Fraction (1/n) of real memory used for server class initial heap") \
+ "Maximum fraction (1/n) of real memory used for maximum heap " \
+ "size; deprecated: to be renamed to MaxRAMFraction") \
+ \
+ product(uintx, MinRAMFraction, 2, \
+ "Minimum fraction (1/n) of real memory used for maxmimum heap " \
+ "size on systems with small physical memory size") \
+ \
+ product(uintx, InitialRAMFraction, 64, \
+ "Fraction (1/n) of real memory used for initial heap size") \
\
product(bool, UseAutoGCSelectPolicy, false, \
"Use automatic collection selection policy") \
@@ -1778,7 +1802,7 @@
"Number of collections before the adaptive sizing is started") \
\
product(uintx, AdaptiveSizePolicyOutputInterval, 0, \
- "Collecton interval for printing information, zero => never") \
+ "Collecton interval for printing information; zero => never") \
\
product(bool, UseAdaptiveSizePolicyFootprintGoal, true, \
"Use adaptive minimum footprint as a goal") \
@@ -1808,7 +1832,8 @@
"Allowed collection cost difference between generations") \
\
product(uintx, AdaptiveSizePolicyCollectionCostMargin, 50, \
- "If collection costs are within margin, reduce both by full delta") \
+ "If collection costs are within margin, reduce both by full " \
+ "delta") \
\
product(uintx, YoungGenerationSizeIncrement, 20, \
"Adaptive size percentage change in young generation") \
@@ -2527,8 +2552,11 @@
\
develop(bool, VerifyCompiledCode, false, \
"Include miscellaneous runtime verifications in nmethod code; " \
- "off by default because it disturbs nmethod size heuristics.") \
- \
+ "default off because it disturbs nmethod size heuristics") \
+ \
+ notproduct(bool, CrashGCForDumpingJavaThread, false, \
+ "Manually make GC thread crash then dump java stack trace; " \
+ "Test only") \
\
/* compilation */ \
product(bool, UseCompiler, true, \
@@ -2789,20 +2817,28 @@
"an OS lock") \
\
/* gc parameters */ \
- product(uintx, MaxHeapSize, ScaleForWordSize(64*M), \
- "Default maximum size for object heap (in bytes)") \
- \
- product_pd(uintx, NewSize, \
- "Default size of new generation (in bytes)") \
+ product(uintx, InitialHeapSize, 0, \
+ "Initial heap size (in bytes); zero means OldSize + NewSize") \
+ \
+ product(uintx, MaxHeapSize, ScaleForWordSize(96*M), \
+ "Maximum heap size (in bytes)") \
+ \
+ product(uintx, OldSize, ScaleForWordSize(4*M), \
+ "Initial tenured generation size (in bytes)") \
+ \
+ product(uintx, NewSize, ScaleForWordSize(4*M), \
+ "Initial new generation size (in bytes)") \
\
product(uintx, MaxNewSize, max_uintx, \
- "Maximum size of new generation (in bytes)") \
+ "Maximum new generation size (in bytes), max_uintx means set " \
+ "ergonomically") \
\
product(uintx, PretenureSizeThreshold, 0, \
- "Max size in bytes of objects allocated in DefNew generation") \
- \
- product_pd(uintx, TLABSize, \
- "Default (or starting) size of TLAB (in bytes)") \
+ "Maximum size in bytes of objects allocated in DefNew " \
+ "generation; zero means no maximum") \
+ \
+ product(uintx, TLABSize, 0, \
+ "Starting TLAB size (in bytes); zero means set ergonomically") \
\
product(uintx, MinTLABSize, 2*K, \
"Minimum allowed TLAB size (in bytes)") \
@@ -2819,10 +2855,10 @@
product(uintx, TLABWasteIncrement, 4, \
"Increment allowed waste at slow allocation") \
\
- product_pd(intx, SurvivorRatio, \
+ product(intx, SurvivorRatio, 8, \
"Ratio of eden/survivor space size") \
\
- product_pd(intx, NewRatio, \
+ product(intx, NewRatio, 2, \
"Ratio of new/old generation sizes") \
\
product(uintx, MaxLiveObjectEvacuationRatio, 100, \
@@ -2832,11 +2868,8 @@
"Additional size added to desired new generation size per " \
"non-daemon thread (in bytes)") \
\
- product(uintx, OldSize, ScaleForWordSize(4096*K), \
- "Default size of tenured generation (in bytes)") \
- \
product_pd(uintx, PermSize, \
- "Default size of permanent generation (in bytes)") \
+ "Initial size of permanent generation (in bytes)") \
\
product_pd(uintx, MaxPermSize, \
"Maximum size of permanent generation (in bytes)") \
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -64,6 +64,7 @@
#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#ifdef PRODUCT
#define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
#define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc) /* flag is constant */
@@ -84,7 +85,7 @@
C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER)
#endif
#ifdef COMPILER2
- C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
+ C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
#endif
NUM_CommandLineFlag
} CommandLineFlag;
@@ -130,6 +131,7 @@
#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+#define C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#ifdef PRODUCT
#define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
#define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) /* flag is constant */
@@ -181,6 +183,7 @@
C2_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
+ C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
#endif
NUM_CommandLineFlagWithType
@@ -202,6 +205,7 @@
static void boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin);
static void intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin);
static void uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin);
+ static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin);
static void doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin);
static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin);
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -60,24 +60,26 @@
typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
class os: AllStatic {
- private:
+ public:
enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)
+ private:
static OSThread* _starting_thread;
static address _polling_page;
static volatile int32_t * _mem_serialize_page;
static uintptr_t _serialize_page_mask;
+ public:
static size_t _page_sizes[page_sizes_max];
+ private:
static void init_page_sizes(size_t default_page_size) {
_page_sizes[0] = default_page_size;
_page_sizes[1] = 0; // sentinel
}
public:
-
- static void init(void); // Called before command line parsing
- static jint init_2(void); // Called after command line parsing
+ static void init(void); // Called before command line parsing
+ static jint init_2(void); // Called after command line parsing
// File names are case-insensitive on windows only
// Override me as needed
@@ -141,6 +143,7 @@
static int processor_count() {
return _processor_count;
}
+ static void set_processor_count(int count) { _processor_count = count; }
// Returns the number of CPUs this process is currently allowed to run on.
// Note that on some OSes this can change dynamically.
@@ -294,19 +297,16 @@
}
static bool is_memory_serialize_page(JavaThread *thread, address addr) {
- address thr_addr;
if (UseMembar) return false;
- // Calculate thread specific address
+ // Previously this function calculated the exact address of this
+ // thread's serialize page, and checked if the faulting address
+ // was equal. However, some platforms mask off faulting addresses
+ // to the page size, so now we just check that the address is
+ // within the page. This makes the thread argument unnecessary,
+ // but we retain the NULL check to preserve existing behaviour.
if (thread == NULL) return false;
- // TODO-FIXME: some platforms mask off faulting addresses to the base pagesize.
- // Instead of using a test for equality we should probably use something
- // of the form:
- // return ((_mem_serialize_page ^ addr) & -pagesize) == 0
- //
- thr_addr = (address)(((uintptr_t)thread >>
- get_serialize_page_shift_count()) &
- get_serialize_page_mask()) + (uintptr_t)_mem_serialize_page;
- return (thr_addr == addr);
+ address page = (address) _mem_serialize_page;
+ return addr >= page && addr < (page + os::vm_page_size());
}
static void block_on_serialize_page_trap();
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -884,6 +884,22 @@
vmSymbolHandles::void_method_signature(), CHECK);
}
+#ifdef KERNEL
+static void set_jkernel_boot_classloader_hook(TRAPS) {
+ klassOop k = SystemDictionary::sun_jkernel_DownloadManager_klass();
+ instanceKlassHandle klass (THREAD, k);
+
+ if (k == NULL) {
+ // sun.jkernel.DownloadManager may not present in the JDK; just return
+ return;
+ }
+
+ JavaValue result(T_VOID);
+ JavaCalls::call_static(&result, klass, vmSymbolHandles::setBootClassLoaderHook_name(),
+ vmSymbolHandles::void_method_signature(), CHECK);
+}
+#endif // KERNEL
+
static void reset_vm_info_property(TRAPS) {
// the vm info string
ResourceMark rm(THREAD);
@@ -975,6 +991,7 @@
// uniquely named instances should derive from this.
NamedThread::NamedThread() : Thread() {
_name = NULL;
+ _processed_thread = NULL;
}
NamedThread::~NamedThread() {
@@ -2317,6 +2334,27 @@
frames_do(frame_gc_prologue);
}
+// If the caller is a NamedThread, then remember, in the current scope,
+// the given JavaThread in its _processed_thread field.
+class RememberProcessedThread: public StackObj {
+ NamedThread* _cur_thr;
+public:
+ RememberProcessedThread(JavaThread* jthr) {
+ Thread* thread = Thread::current();
+ if (thread->is_Named_thread()) {
+ _cur_thr = (NamedThread *)thread;
+ _cur_thr->set_processed_thread(jthr);
+ } else {
+ _cur_thr = NULL;
+ }
+ }
+
+ ~RememberProcessedThread() {
+ if (_cur_thr) {
+ _cur_thr->set_processed_thread(NULL);
+ }
+ }
+};
void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
// Flush deferred store-barriers, if any, associated with
@@ -2333,6 +2371,8 @@
(has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
if (has_last_Java_frame()) {
+ // Record JavaThread to GC thread
+ RememberProcessedThread rpt(this);
// Traverse the privileged stack
if (_privileged_stack_top != NULL) {
@@ -3102,6 +3142,12 @@
vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
}
+#ifdef KERNEL
+ if (JDK_Version::is_gte_jdk17x_version()) {
+ set_jkernel_boot_classloader_hook(THREAD);
+ }
+#endif // KERNEL
+
#ifndef SERIALGC
// Support for ConcurrentMarkSweep. This should be cleaned up
// and better encapsulated. The ugly nested if test would go away
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -48,7 +48,12 @@
// Class hierarchy
// - Thread
-// - VMThread
+// - NamedThread
+// - VMThread
+// - ConcurrentGCThread
+// - WorkerThread
+// - GangWorker
+// - GCTaskThread
// - JavaThread
// - WatcherThread
@@ -249,6 +254,7 @@
virtual bool is_GC_task_thread() const { return false; }
virtual bool is_Watcher_thread() const { return false; }
virtual bool is_ConcurrentGC_thread() const { return false; }
+ virtual bool is_Named_thread() const { return false; }
virtual char* name() const { return (char*)"Unknown thread"; }
@@ -568,12 +574,18 @@
};
private:
char* _name;
+ // log JavaThread being processed by oops_do
+ JavaThread* _processed_thread;
+
public:
NamedThread();
~NamedThread();
// May only be called once per thread.
void set_name(const char* format, ...);
+ virtual bool is_Named_thread() const { return true; }
virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; }
+ JavaThread *processed_thread() { return _processed_thread; }
+ void set_processed_thread(JavaThread *thread) { _processed_thread = thread; }
};
// Worker threads are named and have an id of an assigned work.
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -666,6 +666,7 @@
nonstatic_field(Thread, _current_pending_monitor_is_from_java, bool) \
nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \
nonstatic_field(NamedThread, _name, char*) \
+ nonstatic_field(NamedThread, _processed_thread, JavaThread*) \
nonstatic_field(JavaThread, _next, JavaThread*) \
nonstatic_field(JavaThread, _threadObj, oop) \
nonstatic_field(JavaThread, _anchor, JavaFrameAnchor) \
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -204,8 +204,8 @@
}
-VMThread::VMThread() : Thread() {
- // nothing to do
+VMThread::VMThread() : NamedThread() {
+ set_name("VM Thread");
}
void VMThread::destroy() {
--- a/hotspot/src/share/vm/runtime/vmThread.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -83,7 +83,7 @@
// like scavenge, garbage_collect etc.
//
-class VMThread: public Thread {
+class VMThread: public NamedThread {
private:
static ThreadPriority _current_priority;
@@ -101,8 +101,6 @@
bool is_VM_thread() const { return true; }
bool is_GC_thread() const { return true; }
- char* name() const { return (char*)"VM Thread"; }
-
// The ever running loop for the VMThread
void loop();
--- a/hotspot/src/share/vm/services/attachListener.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/services/attachListener.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -207,7 +207,7 @@
int tmp;
int n = sscanf(arg1, "%d", &tmp);
if (n != 1) {
- out->print_cr("flag value has to be boolean (1 or 0)");
+ out->print_cr("flag value must be a boolean (1 or 0)");
return JNI_ERR;
}
value = (tmp != 0);
@@ -226,11 +226,11 @@
if ((arg1 = op->arg(1)) != NULL) {
int n = sscanf(arg1, INTX_FORMAT, &value);
if (n != 1) {
- out->print_cr("flag value has to be integer");
+ out->print_cr("flag value must be an integer");
return JNI_ERR;
}
}
- bool res = CommandLineFlags::intxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
+ bool res = CommandLineFlags::intxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
if (! res) {
out->print_cr("setting flag %s failed", name);
}
@@ -245,11 +245,30 @@
if ((arg1 = op->arg(1)) != NULL) {
int n = sscanf(arg1, UINTX_FORMAT, &value);
if (n != 1) {
- out->print_cr("flag value has to be integer");
+ out->print_cr("flag value must be an unsigned integer");
return JNI_ERR;
}
}
- bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
+ bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
+ if (! res) {
+ out->print_cr("setting flag %s failed", name);
+ }
+
+ return res? JNI_OK : JNI_ERR;
+}
+
+// set a uint64_t global flag using value from AttachOperation
+static jint set_uint64_t_flag(const char* name, AttachOperation* op, outputStream* out) {
+ uint64_t value;
+ const char* arg1;
+ if ((arg1 = op->arg(1)) != NULL) {
+ int n = sscanf(arg1, UINT64_FORMAT, &value);
+ if (n != 1) {
+ out->print_cr("flag value must be an unsigned 64-bit integer");
+ return JNI_ERR;
+ }
+ }
+ bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, ATTACH_ON_DEMAND);
if (! res) {
out->print_cr("setting flag %s failed", name);
}
@@ -261,10 +280,10 @@
static jint set_ccstr_flag(const char* name, AttachOperation* op, outputStream* out) {
const char* value;
if ((value = op->arg(1)) == NULL) {
- out->print_cr("flag value has to be a string");
+ out->print_cr("flag value must be a string");
return JNI_ERR;
}
- bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND);
+ bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND);
if (res) {
FREE_C_HEAP_ARRAY(char, value);
} else {
@@ -291,6 +310,8 @@
return set_intx_flag(name, op, out);
} else if (f->is_uintx()) {
return set_uintx_flag(name, op, out);
+ } else if (f->is_uint64_t()) {
+ return set_uint64_t_flag(name, op, out);
} else if (f->is_ccstr()) {
return set_ccstr_flag(name, op, out);
} else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/services/g1MemoryPool.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+# include "incls/_precompiled.incl"
+# include "incls/_g1MemoryPool.cpp.incl"
+
+G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
+ const char* name,
+ size_t init_size,
+ size_t max_size,
+ bool support_usage_threshold) :
+ _g1h(g1h), CollectedMemoryPool(name,
+ MemoryPool::Heap,
+ init_size,
+ max_size,
+ support_usage_threshold) {
+ assert(UseG1GC, "sanity");
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::eden_space_committed(G1CollectedHeap* g1h) {
+ return MAX2(eden_space_used(g1h), (size_t) HeapRegion::GrainBytes);
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::eden_space_used(G1CollectedHeap* g1h) {
+ size_t young_list_length = g1h->young_list_length();
+ size_t eden_used = young_list_length * HeapRegion::GrainBytes;
+ size_t survivor_used = survivor_space_used(g1h);
+ eden_used = subtract_up_to_zero(eden_used, survivor_used);
+ return eden_used;
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::eden_space_max(G1CollectedHeap* g1h) {
+ // This should ensure that it returns a value no smaller than the
+ // region size. Currently, eden_space_committed() guarantees that.
+ return eden_space_committed(g1h);
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::survivor_space_committed(G1CollectedHeap* g1h) {
+ return MAX2(survivor_space_used(g1h), (size_t) HeapRegion::GrainBytes);
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::survivor_space_used(G1CollectedHeap* g1h) {
+ size_t survivor_num = g1h->g1_policy()->recorded_survivor_regions();
+ size_t survivor_used = survivor_num * HeapRegion::GrainBytes;
+ return survivor_used;
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::survivor_space_max(G1CollectedHeap* g1h) {
+ // This should ensure that it returns a value no smaller than the
+ // region size. Currently, survivor_space_committed() guarantees that.
+ return survivor_space_committed(g1h);
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::old_space_committed(G1CollectedHeap* g1h) {
+ size_t committed = overall_committed(g1h);
+ size_t eden_committed = eden_space_committed(g1h);
+ size_t survivor_committed = survivor_space_committed(g1h);
+ committed = subtract_up_to_zero(committed, eden_committed);
+ committed = subtract_up_to_zero(committed, survivor_committed);
+ committed = MAX2(committed, (size_t) HeapRegion::GrainBytes);
+ return committed;
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::old_space_used(G1CollectedHeap* g1h) {
+ size_t used = overall_used(g1h);
+ size_t eden_used = eden_space_used(g1h);
+ size_t survivor_used = survivor_space_used(g1h);
+ used = subtract_up_to_zero(used, eden_used);
+ used = subtract_up_to_zero(used, survivor_used);
+ return used;
+}
+
+// See the comment at the top of g1MemoryPool.hpp
+size_t G1MemoryPoolSuper::old_space_max(G1CollectedHeap* g1h) {
+ size_t max = overall_max(g1h);
+ size_t eden_max = eden_space_max(g1h);
+ size_t survivor_max = survivor_space_max(g1h);
+ max = subtract_up_to_zero(max, eden_max);
+ max = subtract_up_to_zero(max, survivor_max);
+ max = MAX2(max, (size_t) HeapRegion::GrainBytes);
+ return max;
+}
+
+G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
+ G1MemoryPoolSuper(g1h,
+ "G1 Eden",
+ eden_space_committed(g1h), /* init_size */
+ eden_space_max(g1h), /* max_size */
+ false /* support_usage_threshold */) {
+}
+
+MemoryUsage G1EdenPool::get_memory_usage() {
+ size_t initial_sz = initial_size();
+ size_t max_sz = max_size();
+ size_t used = used_in_bytes();
+ size_t committed = eden_space_committed(_g1h);
+
+ return MemoryUsage(initial_sz, used, committed, max_sz);
+}
+
+G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
+ G1MemoryPoolSuper(g1h,
+ "G1 Survivor",
+ survivor_space_committed(g1h), /* init_size */
+ survivor_space_max(g1h), /* max_size */
+ false /* support_usage_threshold */) {
+}
+
+MemoryUsage G1SurvivorPool::get_memory_usage() {
+ size_t initial_sz = initial_size();
+ size_t max_sz = max_size();
+ size_t used = used_in_bytes();
+ size_t committed = survivor_space_committed(_g1h);
+
+ return MemoryUsage(initial_sz, used, committed, max_sz);
+}
+
+G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
+ G1MemoryPoolSuper(g1h,
+ "G1 Old Gen",
+ old_space_committed(g1h), /* init_size */
+ old_space_max(g1h), /* max_size */
+ true /* support_usage_threshold */) {
+}
+
+MemoryUsage G1OldGenPool::get_memory_usage() {
+ size_t initial_sz = initial_size();
+ size_t max_sz = max_size();
+ size_t used = used_in_bytes();
+ size_t committed = old_space_committed(_g1h);
+
+ return MemoryUsage(initial_sz, used, committed, max_sz);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/services/g1MemoryPool.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+class G1CollectedHeap;
+
+// This file contains the three classes that represent the memory
+// pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and
+// G1OldGenPool. In G1, unlike our other GCs, we do not have a
+// physical space for each of those spaces. Instead, we allocate
+// regions for all three spaces out of a single pool of regions (that
+// pool basically covers the entire heap). As a result, the eden,
+// survivor, and old gen are considered logical spaces in G1, as each
+// is a set of non-contiguous regions. This is also reflected in the
+// way we map them to memory pools here. The easiest way to have done
+// this would have been to map the entire G1 heap to a single memory
+// pool. However, it's helpful to show how large the eden and survivor
+// get, as this does affect the performance and behavior of G1. Which
+// is why we introduce the three memory pools implemented here.
+//
+// The above approach inroduces a couple of challenging issues in the
+// implementation of the three memory pools:
+//
+// 1) The used space calculation for a pool is not necessarily
+// independent of the others. We can easily get from G1 the overall
+// used space in the entire heap, the number of regions in the young
+// generation (includes both eden and survivors), and the number of
+// survivor regions. So, from that we calculate:
+//
+// survivor_used = survivor_num * region_size
+// eden_used = young_region_num * region_size - survivor_used
+// old_gen_used = overall_used - eden_used - survivor_used
+//
+// Note that survivor_used and eden_used are upper bounds. To get the
+// actual value we would have to iterate over the regions and add up
+// ->used(). But that'd be expensive. So, we'll accept some lack of
+// accuracy for those two. But, we have to be careful when calculating
+// old_gen_used, in case we subtract from overall_used more then the
+// actual number and our result goes negative.
+//
+// 2) Calculating the used space is straightforward, as described
+// above. However, how do we calculate the committed space, given that
+// we allocate space for the eden, survivor, and old gen out of the
+// same pool of regions? One way to do this is to use the used value
+// as also the committed value for the eden and survivor spaces and
+// then calculate the old gen committed space as follows:
+//
+// old_gen_committed = overall_committed - eden_committed - survivor_committed
+//
+// Maybe a better way to do that would be to calculate used for eden
+// and survivor as a sum of ->used() over their regions and then
+// calculate committed as region_num * region_size (i.e., what we use
+// to calculate the used space now). This is something to consider
+// in the future.
+//
+// 3) Another decision that is again not straightforward is what is
+// the max size that each memory pool can grow to. Right now, we set
+// that the committed size for the eden and the survivors and
+// calculate the old gen max as follows (basically, it's a similar
+// pattern to what we use for the committed space, as described
+// above):
+//
+// old_gen_max = overall_max - eden_max - survivor_max
+//
+// 4) Now, there is a very subtle issue with all the above. The
+// framework will call get_memory_usage() on the three pools
+// asynchronously. As a result, each call might get a different value
+// for, say, survivor_num which will yield inconsistent values for
+// eden_used, survivor_used, and old_gen_used (as survivor_num is used
+// in the calculation of all three). This would normally be
+// ok. However, it's possible that this might cause the sum of
+// eden_used, survivor_used, and old_gen_used to go over the max heap
+// size and this seems to sometimes cause JConsole (and maybe other
+// clients) to get confused. There's not a really an easy / clean
+// solution to this problem, due to the asynchrounous nature of the
+// framework.
+
+
+// This class is shared by the three G1 memory pool classes
+// (G1EdenPool, G1SurvivorPool, G1OldGenPool). Given that the way we
+// calculate used / committed bytes for these three pools is related
+// (see comment above), we put the calculations in this class so that
+// we can easily share them among the subclasses.
+class G1MemoryPoolSuper : public CollectedMemoryPool {
+private:
+ // It returns x - y if x > y, 0 otherwise.
+ // As described in the comment above, some of the inputs to the
+ // calculations we have to do are obtained concurrently and hence
+ // may be inconsistent with each other. So, this provides a
+ // defensive way of performing the subtraction and avoids the value
+ // going negative (which would mean a very large result, given that
+ // the parameter are size_t).
+ static size_t subtract_up_to_zero(size_t x, size_t y) {
+ if (x > y) {
+ return x - y;
+ } else {
+ return 0;
+ }
+ }
+
+protected:
+ G1CollectedHeap* _g1h;
+
+ // Would only be called from subclasses.
+ G1MemoryPoolSuper(G1CollectedHeap* g1h,
+ const char* name,
+ size_t init_size,
+ size_t max_size,
+ bool support_usage_threshold);
+
+ // The reason why all the code is in static methods is so that it
+ // can be safely called from the constructors of the subclasses.
+
+ static size_t overall_committed(G1CollectedHeap* g1h) {
+ return g1h->capacity();
+ }
+ static size_t overall_used(G1CollectedHeap* g1h) {
+ return g1h->used_unlocked();
+ }
+ static size_t overall_max(G1CollectedHeap* g1h) {
+ return g1h->g1_reserved_obj_bytes();
+ }
+
+ static size_t eden_space_committed(G1CollectedHeap* g1h);
+ static size_t eden_space_used(G1CollectedHeap* g1h);
+ static size_t eden_space_max(G1CollectedHeap* g1h);
+
+ static size_t survivor_space_committed(G1CollectedHeap* g1h);
+ static size_t survivor_space_used(G1CollectedHeap* g1h);
+ static size_t survivor_space_max(G1CollectedHeap* g1h);
+
+ static size_t old_space_committed(G1CollectedHeap* g1h);
+ static size_t old_space_used(G1CollectedHeap* g1h);
+ static size_t old_space_max(G1CollectedHeap* g1h);
+};
+
+// Memory pool that represents the G1 eden.
+class G1EdenPool : public G1MemoryPoolSuper {
+public:
+ G1EdenPool(G1CollectedHeap* g1h);
+
+ size_t used_in_bytes() {
+ return eden_space_used(_g1h);
+ }
+ size_t max_size() const {
+ return eden_space_max(_g1h);
+ }
+ MemoryUsage get_memory_usage();
+};
+
+// Memory pool that represents the G1 survivor.
+class G1SurvivorPool : public G1MemoryPoolSuper {
+public:
+ G1SurvivorPool(G1CollectedHeap* g1h);
+
+ size_t used_in_bytes() {
+ return survivor_space_used(_g1h);
+ }
+ size_t max_size() const {
+ return survivor_space_max(_g1h);
+ }
+ MemoryUsage get_memory_usage();
+};
+
+// Memory pool that represents the G1 old gen.
+class G1OldGenPool : public G1MemoryPoolSuper {
+public:
+ G1OldGenPool(G1CollectedHeap* g1h);
+
+ size_t used_in_bytes() {
+ return old_space_used(_g1h);
+ }
+ size_t max_size() const {
+ return old_space_max(_g1h);
+ }
+ MemoryUsage get_memory_usage();
+};
--- a/hotspot/src/share/vm/services/management.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/services/management.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -790,7 +790,7 @@
assert(!has_undefined_init_size, "Undefined init size");
assert(!has_undefined_max_size, "Undefined max size");
- MemoryUsage usage((heap ? Arguments::initial_heap_size() : total_init),
+ MemoryUsage usage((heap ? InitialHeapSize : total_init),
total_used,
total_committed,
(heap ? Universe::heap()->max_capacity() : total_max));
@@ -1507,16 +1507,17 @@
return (jobjectArray)JNIHandles::make_local(env, flags_ah());
JVM_END
-// utility function used by jmm_GetVMGlobals
-void add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) {
+// Utility function used by jmm_GetVMGlobals. Returns false if flag type
+// can't be determined, true otherwise. If false is returned, then *global
+// will be incomplete and invalid.
+bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) {
Handle flag_name;
if (name() == NULL) {
- flag_name = java_lang_String::create_from_str(flag->name, CHECK);
+ flag_name = java_lang_String::create_from_str(flag->name, CHECK_false);
} else {
flag_name = name;
}
global->name = (jstring)JNIHandles::make_local(env, flag_name());
- global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
if (flag->is_bool()) {
global->value.z = flag->get_bool() ? JNI_TRUE : JNI_FALSE;
@@ -1527,10 +1528,17 @@
} else if (flag->is_uintx()) {
global->value.j = (jlong)flag->get_uintx();
global->type = JMM_VMGLOBAL_TYPE_JLONG;
+ } else if (flag->is_uint64_t()) {
+ global->value.j = (jlong)flag->get_uint64_t();
+ global->type = JMM_VMGLOBAL_TYPE_JLONG;
} else if (flag->is_ccstr()) {
- Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK);
+ Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false);
global->value.l = (jobject)JNIHandles::make_local(env, str());
global->type = JMM_VMGLOBAL_TYPE_JSTRING;
+ } else {
+ global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
+ assert(false, "Unsupported VMGlobal Type");
+ return false;
}
global->writeable = flag->is_writeable();
@@ -1557,6 +1565,8 @@
default:
global->origin = JMM_VMGLOBAL_ORIGIN_OTHER;
}
+
+ return true;
}
// Fill globals array of count length with jmmVMGlobal entries
@@ -1599,8 +1609,8 @@
Handle sh(THREAD, s);
char* str = java_lang_String::as_utf8_string(s);
Flag* flag = Flag::find_flag(str, strlen(str));
- if (flag != NULL) {
- add_global_entry(env, sh, &globals[i], flag, THREAD);
+ if (flag != NULL &&
+ add_global_entry(env, sh, &globals[i], flag, THREAD)) {
num_entries++;
} else {
globals[i].name = NULL;
@@ -1617,8 +1627,8 @@
for (int i = 0; i < nFlags && num_entries < count; i++) {
Flag* flag = &Flag::flags[i];
// Exclude the locked (diagnostic, experimental) flags
- if (flag->is_unlocked() || flag->is_unlocker()) {
- add_global_entry(env, null_h, &globals[num_entries], flag, THREAD);
+ if ((flag->is_unlocked() || flag->is_unlocker()) &&
+ add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) {
num_entries++;
}
}
@@ -1650,11 +1660,14 @@
bool bvalue = (new_value.z == JNI_TRUE ? true : false);
succeed = CommandLineFlags::boolAtPut(name, &bvalue, MANAGEMENT);
} else if (flag->is_intx()) {
- intx ivalue = new_value.j;
+ intx ivalue = (intx)new_value.j;
succeed = CommandLineFlags::intxAtPut(name, &ivalue, MANAGEMENT);
} else if (flag->is_uintx()) {
- uintx uvalue = new_value.j;
+ uintx uvalue = (uintx)new_value.j;
succeed = CommandLineFlags::uintxAtPut(name, &uvalue, MANAGEMENT);
+ } else if (flag->is_uint64_t()) {
+ uint64_t uvalue = (uint64_t)new_value.j;
+ succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, MANAGEMENT);
} else if (flag->is_ccstr()) {
oop str = JNIHandles::resolve_external_guard(new_value.l);
if (str == NULL) {
--- a/hotspot/src/share/vm/services/memoryManager.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/services/memoryManager.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -72,6 +72,14 @@
return (GCMemoryManager*) new PSMarkSweepMemoryManager();
}
+GCMemoryManager* MemoryManager::get_g1YoungGen_memory_manager() {
+ return (GCMemoryManager*) new G1YoungGenMemoryManager();
+}
+
+GCMemoryManager* MemoryManager::get_g1OldGen_memory_manager() {
+ return (GCMemoryManager*) new G1OldGenMemoryManager();
+}
+
instanceOop MemoryManager::get_memory_manager_instance(TRAPS) {
// Must do an acquire so as to force ordering of subsequent
// loads from anything _memory_mgr_obj points to or implies.
--- a/hotspot/src/share/vm/services/memoryManager.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/services/memoryManager.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -54,7 +54,9 @@
ParNew,
ConcurrentMarkSweep,
PSScavenge,
- PSMarkSweep
+ PSMarkSweep,
+ G1YoungGen,
+ G1OldGen
};
MemoryManager();
@@ -85,6 +87,8 @@
static GCMemoryManager* get_cms_memory_manager();
static GCMemoryManager* get_psScavenge_memory_manager();
static GCMemoryManager* get_psMarkSweep_memory_manager();
+ static GCMemoryManager* get_g1YoungGen_memory_manager();
+ static GCMemoryManager* get_g1OldGen_memory_manager();
};
@@ -231,3 +235,21 @@
MemoryManager::Name kind() { return MemoryManager::PSMarkSweep; }
const char* name() { return "PS MarkSweep"; }
};
+
+class G1YoungGenMemoryManager : public GCMemoryManager {
+private:
+public:
+ G1YoungGenMemoryManager() : GCMemoryManager() {}
+
+ MemoryManager::Name kind() { return MemoryManager::G1YoungGen; }
+ const char* name() { return "G1 Young Generation"; }
+};
+
+class G1OldGenMemoryManager : public GCMemoryManager {
+private:
+public:
+ G1OldGenMemoryManager() : GCMemoryManager() {}
+
+ MemoryManager::Name kind() { return MemoryManager::G1OldGen; }
+ const char* name() { return "G1 Old Generation"; }
+};
--- a/hotspot/src/share/vm/services/memoryService.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/services/memoryService.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -60,8 +60,8 @@
break;
}
case CollectedHeap::G1CollectedHeap : {
- G1CollectedHeap::g1_unimplemented();
- return;
+ add_g1_heap_info(G1CollectedHeap::heap());
+ break;
}
#endif // SERIALGC
default: {
@@ -164,6 +164,19 @@
add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
add_psPerm_memory_pool(heap->perm_gen(), _major_gc_manager);
}
+
+void MemoryService::add_g1_heap_info(G1CollectedHeap* g1h) {
+ assert(UseG1GC, "sanity");
+
+ _minor_gc_manager = MemoryManager::get_g1YoungGen_memory_manager();
+ _major_gc_manager = MemoryManager::get_g1OldGen_memory_manager();
+ _managers_list->append(_minor_gc_manager);
+ _managers_list->append(_major_gc_manager);
+
+ add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
+ add_g1OldGen_memory_pool(g1h, _major_gc_manager);
+ add_g1PermGen_memory_pool(g1h, _major_gc_manager);
+}
#endif // SERIALGC
MemoryPool* MemoryService::add_gen(Generation* gen,
@@ -384,6 +397,64 @@
mgr->add_pool(perm_gen);
_pools_list->append(perm_gen);
}
+
+void MemoryService::add_g1YoungGen_memory_pool(G1CollectedHeap* g1h,
+ MemoryManager* major_mgr,
+ MemoryManager* minor_mgr) {
+ assert(major_mgr != NULL && minor_mgr != NULL, "should have two managers");
+
+ G1EdenPool* eden = new G1EdenPool(g1h);
+ G1SurvivorPool* survivor = new G1SurvivorPool(g1h);
+
+ major_mgr->add_pool(eden);
+ major_mgr->add_pool(survivor);
+ minor_mgr->add_pool(eden);
+ minor_mgr->add_pool(survivor);
+ _pools_list->append(eden);
+ _pools_list->append(survivor);
+}
+
+void MemoryService::add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
+ MemoryManager* mgr) {
+ assert(mgr != NULL, "should have one manager");
+
+ G1OldGenPool* old_gen = new G1OldGenPool(g1h);
+ mgr->add_pool(old_gen);
+ _pools_list->append(old_gen);
+}
+
+void MemoryService::add_g1PermGen_memory_pool(G1CollectedHeap* g1h,
+ MemoryManager* mgr) {
+ assert(mgr != NULL, "should have one manager");
+
+ CompactingPermGenGen* perm_gen = (CompactingPermGenGen*) g1h->perm_gen();
+ PermanentGenerationSpec* spec = perm_gen->spec();
+ size_t max_size = spec->max_size() - spec->read_only_size()
+ - spec->read_write_size();
+ MemoryPool* pool = add_space(perm_gen->unshared_space(),
+ "G1 Perm Gen",
+ false, /* is_heap */
+ max_size,
+ true /* support_usage_threshold */);
+ mgr->add_pool(pool);
+
+ // in case we support CDS in G1
+ if (UseSharedSpaces) {
+ pool = add_space(perm_gen->ro_space(),
+ "G1 Perm Gen [shared-ro]",
+ false, /* is_heap */
+ spec->read_only_size(),
+ true /* support_usage_threshold */);
+ mgr->add_pool(pool);
+
+ pool = add_space(perm_gen->rw_space(),
+ "G1 Perm Gen [shared-rw]",
+ false, /* is_heap */
+ spec->read_write_size(),
+ true /* support_usage_threshold */);
+ mgr->add_pool(pool);
+ }
+}
#endif // SERIALGC
void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) {
--- a/hotspot/src/share/vm/services/memoryService.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/services/memoryService.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -40,6 +40,7 @@
class ParallelScavengeHeap;
class CompactingPermGenGen;
class CMSPermGenGen;
+class G1CollectedHeap;
// VM Monitoring and Management Support
@@ -88,6 +89,13 @@
static void add_psPerm_memory_pool(PSPermGen* perm,
MemoryManager* mgr);
+ static void add_g1YoungGen_memory_pool(G1CollectedHeap* g1h,
+ MemoryManager* major_mgr,
+ MemoryManager* minor_mgr);
+ static void add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
+ MemoryManager* mgr);
+ static void add_g1PermGen_memory_pool(G1CollectedHeap* g1h,
+ MemoryManager* mgr);
static MemoryPool* add_space(ContiguousSpace* space,
const char* name,
@@ -111,6 +119,7 @@
static void add_gen_collected_heap_info(GenCollectedHeap* heap);
static void add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap);
+ static void add_g1_heap_info(G1CollectedHeap* g1h);
public:
static void set_universe_heap(CollectedHeap* heap);
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -278,6 +278,17 @@
_len--;
}
+ // inserts the given element before the element at index i
+ void insert_before(const int idx, const E& elem) {
+ check_nesting();
+ if (_len == _max) grow(_len);
+ for (int j = _len - 1; j >= idx; j--) {
+ _data[j + 1] = _data[j];
+ }
+ _len++;
+ _data[idx] = elem;
+ }
+
void appendAll(const GrowableArray<E>* l) {
for (int i = 0; i < l->_len; i++) {
raw_at_put_grow(_len, l->_data[i], 0);
--- a/hotspot/src/share/vm/utilities/numberSeq.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/utilities/numberSeq.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -241,3 +241,33 @@
return b0 + b1 * num;
}
+
+
+// Printing/Debugging Support
+
+void AbsSeq::dump() { dump_on(gclog_or_tty); }
+
+void AbsSeq::dump_on(outputStream* s) {
+ s->print_cr("\t _num = %d, _sum = %7.3f, _sum_of_squares = %7.3f",
+ _num, _sum, _sum_of_squares);
+ s->print_cr("\t _davg = %7.3f, _dvariance = %7.3f, _alpha = %7.3f",
+ _davg, _dvariance, _alpha);
+}
+
+void NumberSeq::dump_on(outputStream* s) {
+ AbsSeq::dump_on(s);
+ s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f");
+}
+
+void TruncatedSeq::dump_on(outputStream* s) {
+ AbsSeq::dump_on(s);
+ s->print_cr("\t\t _length = %d, _next = %d", _length, _next);
+ for (int i = 0; i < _length; i++) {
+ if (i%5 == 0) {
+ s->cr();
+ s->print("\t");
+ }
+ s->print("\t[%d]=%7.3f", i, _sequence[i]);
+ }
+ s->print_cr("");
+}
--- a/hotspot/src/share/vm/utilities/numberSeq.hpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/utilities/numberSeq.hpp Wed Jul 05 17:04:56 2017 +0200
@@ -74,6 +74,10 @@
double davg() const; // decaying average
double dvariance() const; // decaying variance
double dsd() const; // decaying "standard deviation"
+
+ // Debugging/Printing
+ virtual void dump();
+ virtual void dump_on(outputStream* s);
};
class NumberSeq: public AbsSeq {
@@ -91,6 +95,9 @@
virtual void add(double val);
virtual double maximum() const { return _maximum; }
virtual double last() const { return _last; }
+
+ // Debugging/Printing
+ virtual void dump_on(outputStream* s);
};
class TruncatedSeq: public AbsSeq {
@@ -114,4 +121,7 @@
double oldest() const; // the oldest valid value in the sequence
double predict_next() const; // prediction based on linear regression
+
+ // Debugging/Printing
+ virtual void dump_on(outputStream* s);
};
--- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Dec 17 14:10:20 2009 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 05 17:04:56 2017 +0200
@@ -502,6 +502,23 @@
#endif // ZERO
}
+ STEP(135, "(printing target Java thread stack)" )
+
+ // printing Java thread stack trace if it is involved in GC crash
+ if (_verbose && (_thread->is_Named_thread())) {
+ JavaThread* jt = ((NamedThread *)_thread)->processed_thread();
+ if (jt != NULL) {
+ st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id());
+ if (jt->has_last_Java_frame()) {
+ st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)");
+ for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) {
+ sfs.current()->print_on_error(st, buf, sizeof(buf), true);
+ st->cr();
+ }
+ }
+ }
+ }
+
STEP(140, "(printing VM operation)" )
if (_verbose && _thread && _thread->is_VM_thread()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6769124/TestArrayCopy6769124.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6769124
+ * @summary arraycopy may crash the VM with c1 on 64 bit
+ */
+
+public class TestArrayCopy6769124 {
+
+ public static void main(String[] args) {
+
+ int k = 1 << 31;
+
+
+ for(int j = 0; j <1000000; j++) {
+ int i = -1;
+ while(i < 10) {
+ i++;
+ }
+
+ int m = k * i;
+
+ int[] O1 = new int[20];
+ int[] O2 = new int[20];
+
+ System.arraycopy(O1, i, O2, i, 1); //will crash on amd64
+ System.arraycopy(O1, m, O2, m, 1); //will crash on sparcv9
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6769124/TestDeoptInt6769124.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6769124
+ * @summary int value might not be correctly decoded on deopt with c1 on 64 bit
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=TestDeoptInt6769124.m TestDeoptInt6769124
+ */
+
+public class TestDeoptInt6769124 {
+
+ static class A {
+ volatile int vl;
+ A(int v) {
+ vl = v;
+ }
+ }
+
+ static void m(int b) {
+ A a = new A(10);
+ int c;
+ c = b + a.vl; //accessing volatile field of class not loaded at compile time forces a deopt
+ if(c != 20) {
+ System.out.println("a (= " + a.vl + ") + b (= " + b + ") = c (= " + c + ") != 20");
+ throw new InternalError();
+ }
+ }
+
+ public static void main(String[] args) {
+ m(10);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6769124/TestUnalignedLoad6769124.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6769124
+ * @summary unaligned load may fail with c1 on 64 bit
+ */
+
+public class TestUnalignedLoad6769124 {
+
+ static long l1v = 0x200000003L;
+ static long l2v = 0x400000005L;
+ static double d1v = Double.MAX_VALUE;
+ static double d2v = Double.MIN_VALUE;
+
+ public static void main(String[] args) {
+ long l1 = l1v;
+ double d1 = d1v;
+ long l2 = l2v;
+ double d2 = d2v;
+
+ // Run long enough to induce an OSR
+ for (int i = 0; i < 10000000; i++) {
+ }
+ boolean error = false;
+
+ if (l1 != l1v) {
+ System.out.println(l1 + " != " + l1v);
+ error = true;
+ }
+ if (l2 != l2v) {
+ System.out.println(l2 + " != " + l2v);
+ error = true;
+ }
+ if (d1 != d1v) {
+ System.out.println(d1 + " != " + d1v);
+ error = true;
+ }
+ if (d2 != d2v) {
+ System.out.println(d2 + " != " + d2v);
+ error = true;
+ }
+ if (error) {
+ throw new InternalError();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6852078/Test6852078.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6852078
+ * @summary Disable SuperWord optimization for unsafe read/write
+ *
+ * @run main/othervm Test6852078
+ */
+
+import java.util.*;
+import java.nio.ByteBuffer;
+import com.sun.corba.se.impl.encoding.ByteBufferWithInfo;
+import com.sun.jndi.toolkit.corba.CorbaUtils;
+
+public class Test6852078 {
+
+ public Test6852078(String [] args) {
+
+ int capacity = 128;
+ ByteBuffer bb = ByteBuffer.allocateDirect(capacity);
+ ByteBufferWithInfo bbwi = new ByteBufferWithInfo( CorbaUtils.getOrb(null, -1, new Hashtable()), bb);
+ byte[] tmpBuf;
+ tmpBuf = new byte[bbwi.buflen];
+
+ for (int i = 0; i < capacity; i++)
+ tmpBuf[i] = bbwi.byteBuffer.get(i);
+ }
+
+ public static void main(String [] args) {
+ for (int i=0; i<2000; i++) {
+ Test6852078 t = new Test6852078(args);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6895383/Test.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6895383
+ * @summary JCK test throws NPE for method compiled with Escape Analysis
+ *
+ * @run main/othervm -Xcomp Test
+ */
+
+public class Test {
+ public static void main(String argv[]) {
+ Test test = new Test();
+ test.testRemove1_IndexOutOfBounds();
+ test.testAddAll1_IndexOutOfBoundsException();
+ }
+
+ public void testRemove1_IndexOutOfBounds() {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ }
+
+ public void testAddAll1_IndexOutOfBoundsException() {
+ try {
+ CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+ c.addAll(-1, new LinkedList()); // should throw IndexOutOfBoundsException
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6896727/Test.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6896727
+ * @summary nsk/logging/LoggingPermission/LoggingPermission/logperm002 fails with G1, EscapeAnalisys w/o COOPs
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:+DoEscapeAnalysis -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC Test
+ */
+
+public class Test {
+
+ final static String testString = "abracadabra";
+ public static void main(String args[]) {
+ String params[][] = {
+ {"control", testString}
+ };
+ for (int i=0; i<params.length; i++) {
+ try {
+ System.out.println("Params :" + testString + " and " + params[i][0] + ", " + params[i][1]);
+ if (params[i][1] == null) {
+ System.exit(97);
+ }
+ } catch (Exception e) {}
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6901572/Test.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6901572
+ * @summary JVM 1.6.16 crash on loops: assert(has_node(i),"")
+ *
+ * @run main/othervm Test
+ */
+
+
+public class Test {
+
+ public static void main(String[] args) {
+ for (int i = 0; i < 2; i++)
+ NestedLoop();
+ }
+
+ public static long NestedLoop() {
+ final int n = 50;
+ long startTime = System.currentTimeMillis();
+ int x = 0;
+ for(int a = 0; a < n; a++)
+ for(int b = 0; b < n; b++)
+ for(int c = 0; c < n; c++)
+ for(int d = 0; d < n; d++)
+ for(int e = 0; e < n; e++)
+ for(int f = 0; f < n; f++)
+ x++;
+ long stopTime = System.currentTimeMillis();
+
+ return stopTime - startTime;
+ }
+}
--- a/jdk/.hgtags Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/.hgtags Wed Jul 05 17:04:56 2017 +0200
@@ -52,3 +52,4 @@
8885b22565077236a927e824ef450742e434a230 jdk7-b75
8fb602395be0f7d5af4e7e93b7df2d960faf9d17 jdk7-b76
e6a5d095c356a547cf5b3c8885885aca5e91e09b jdk7-b77
+1143e498f813b8223b5e3a696d79da7ff7c25354 jdk7-b78
--- a/jdk/make/Makefile Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/Makefile Wed Jul 05 17:04:56 2017 +0200
@@ -74,6 +74,7 @@
import_product -- copy in the product components \n\
import_fastdebug -- copy in the fastdebug components \n\
import_debug -- copy in the debug components \n\
+modules -- build the jdk and jre module images (experimental) \n\
sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\
create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\
"
@@ -257,6 +258,7 @@
# Release engineering targets.
#
include $(BUILDDIR)/common/Release.gmk
+include $(BUILDDIR)/common/Modules.gmk
#
# Cscope targets.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/common/Modules.gmk Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,442 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+JDK_MODULE_IMAGE_DIR = $(ABS_OUTPUTDIR)/jdk-module-image
+JRE_MODULE_IMAGE_DIR = $(ABS_OUTPUTDIR)/jre-module-image
+
+#
+# modules Target to build jdk and jre module image
+#
+# There is one jar file per module containing classes only.
+# All module jars are currently placed under jre/lib directory.
+#
+# Open issues that need further investigation:
+# 1. Classes in jre/lib/ext/dnsns.jar are currently put in jre/lib/jndi-dns
+# module.
+# 2. Signed jars
+# For JDK build, signed jars are copied to the build.
+# All jars in the module image are unsigned.
+# 3. jre/lib/security/US_export_policy.jar and local_policy.jar
+# are not included in the module image yet.
+
+MODULE_IMAGEBINDIR = bin
+
+#
+# Targets.
+#
+INITIAL_MODULE_IMAGE_JRE=initial-module-image-jre
+INITIAL_MODULE_IMAGE_JDK=initial-module-image-jdk
+ifeq ($(PLATFORM), solaris)
+ ifeq ($(ARCH_DATA_MODEL), 64)
+ INITIAL_MODULE_IMAGE_JRE=initial-module-image-jre-sol64
+ INITIAL_MODULE_IMAGE_JDK=initial-module-image-jdk-sol64
+ endif
+endif
+
+modules modules-clobber \
+initial-module-image-jre initial-module-image-jdk \
+initial-module-image-jre-sol64 initial-module-image-jdk-sol64 \
+trim-module-image-jre trim-module-image-jdk \
+process-module-image-jre process-module-image-jdk ::
+ @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
+
+# Order is important here, trim jre after jdk image is created
+modules:: sanity-module-images post-sanity-module-images \
+ $(INITIAL_MODULE_IMAGE_JRE) $(INITIAL_MODULE_IMAGE_JDK) \
+ trim-module-image-jre trim-module-image-jdk \
+ process-module-image-jre process-module-image-jdk
+
+# Don't use these
+module-image-jre:: initial-module-image-jre trim-module-image-jre process-module-image-jre
+module-image-jdk:: initial-module-image-jdk trim-module-image-jdk process-module-image-jdk
+
+#
+# Paths to these files we need
+JDK_MODULE_LICENSES = $(LICENSE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%)
+JDK_MODULE_64_LICENSES = $(LICENSE_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%64)
+JDK_MODULE_DOCFILES = $(OTHER_DOCLIST_JDK:%=$(JDK_MODULE_IMAGE_DIR)/%)
+
+JRE_MODULE_LICENSES = $(LICENSE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%)
+JRE_MODULE_64_LICENSES = $(LICENSE_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%64)
+JRE_MODULE_DOCFILES = $(OTHER_DOCLIST_JRE:%=$(JRE_MODULE_IMAGE_DIR)/%)
+JRE_MODULE_DOCFILES += $(JRE_NAMECHANGE_DOCLIST:%=$(JRE_MODULE_IMAGE_DIR)/%$(TEXT_SUFFIX))
+
+###### RULES
+
+# JDK files
+$(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%
+ $(process-doc-file)
+# Removes LICENSE_VERSION or not
+ifdef LICENSE_VERSION
+$(JDK_MODULE_IMAGE_DIR)/%: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION)
+ $(process-doc-file)
+$(JDK_MODULE_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%$(LICENSE_VERSION)
+ $(process-doc-file)
+else
+$(JDK_MODULE_IMAGE_DIR)/%64: $(SHARE_JDK_DOC_SRC)/%
+ $(process-doc-file)
+endif
+
+# JRE files
+$(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%
+ $(process-doc-file)
+# Add $(TEXT_SUFFIX) suffix
+ifdef TEXT_SUFFIX
+$(JRE_MODULE_IMAGE_DIR)/%$(TEXT_SUFFIX): $(SHARE_JRE_DOC_SRC)/%
+ $(process-doc-file)
+endif
+# Removes LICENSE_VERSION or not
+ifdef LICENSE_VERSION
+$(JRE_MODULE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION)
+ $(process-doc-file)
+$(JRE_MODULE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%$(LICENSE_VERSION)
+ $(process-doc-file)
+else
+$(JRE_MODULE_IMAGE_DIR)/%64: $(SHARE_JRE_DOC_SRC)/%
+ $(process-doc-file)
+endif
+
+######################################################
+# JRE Image
+######################################################
+
+MODULES_TEMPDIR=$(ABS_TEMPDIR)/modules
+MODULES_LIB = $(ABS_OUTPUTDIR)/modules
+
+gen-modules:
+ $(CD) modules; $(MAKE) all
+
+initial-module-image-jre-setup:
+ $(RM) -r $(JRE_MODULE_IMAGE_DIR)
+ $(MKDIR) -p $(JRE_MODULE_IMAGE_DIR)
+
+# 64-bit solaris jre image contains only the 64-bit add-on files.
+initial-module-image-jre-sol64:: initial-module-image-jre-setup \
+ $(JRE_MODULE_LICENSES) $(JRE_MODULE_64_LICENSES)
+ @# Use tar instead of cp to preserve the symbolic links
+ for dir in bin lib ; do \
+ ( $(CD) $(OUTPUTDIR) && \
+ $(TAR) cf - `$(FIND) $$dir -name '$(ARCH)' -print` | \
+ ($(CD) $(JRE_MODULE_IMAGE_DIR) && $(TAR) xf -) ) ; \
+ done
+ @# Remove some files from the jre area
+ for t in $(NOTJRETOOLS) ; do \
+ $(RM) $(JRE_MODULE_IMAGE_DIR)/bin$(ISA_DIR)/$$t ; \
+ done
+ $(RM) `$(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'orb.idl'`
+ $(RM) `$(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'ir.idl'`
+
+# Construct an initial jre image (initial jdk jre) no trimming or stripping
+initial-module-image-jre:: initial-module-image-jre-setup \
+ $(JRE_LICENSES) $(JRE_MODULE_DOCFILES) \
+ gen-modules \
+ $(BUILDMETAINDEX_JARFILE)
+ @# Copy in bin directory
+ $(CD) $(OUTPUTDIR) && $(FIND) bin -depth | $(CPIO) -pdum $(JRE_MODULE_IMAGE_DIR)
+ @# CTE plugin security change require new empty directory lib/applet
+ $(MKDIR) -p $(JRE_MODULE_IMAGE_DIR)/lib/applet
+ @# Copy files but not .jar in lib directory
+ $(CD) $(OUTPUTDIR) && $(FIND) lib -depth | $(EGREP) -v ".jar$$" | $(CPIO) -pdum $(JRE_MODULE_IMAGE_DIR)
+ @#
+ @# copy modules to jre/lib
+ @#
+ $(CP) -rf $(MODULES_LIB)/jre/lib/* $(JRE_MODULE_IMAGE_DIR)/lib
+ @# Make sure all directories are read/execute for everyone
+ $(CHMOD) a+rx `$(FIND) $(JRE_MODULE_IMAGE_DIR) -type d`
+ @# Remove some files from the jre area
+ for t in $(NOTJRETOOLS) ; do \
+ $(RM) $(JRE_MODULE_IMAGE_DIR)/bin$(ISA_DIR)/$$t ; \
+ done
+ @# Remove orb.idl and ir.idl from jre
+ $(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'orb.idl' -exec $(RM) \{} \;
+ $(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -name 'ir.idl' -exec $(RM) \{} \;
+ @# Generate meta-index to make boot and extension class loaders lazier
+ $(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \
+ $(BOOT_JAVA_CMD) -jar $(BUILDMETAINDEX_JARFILE) \
+ -o meta-index *.jar
+ @$(CD) $(JRE_MODULE_IMAGE_DIR)/lib && $(java-vm-cleanup)
+ $(CD) $(JRE_MODULE_IMAGE_DIR)/lib/ext && \
+ $(BOOT_JAVA_CMD) -jar $(BUILDMETAINDEX_JARFILE) \
+ -o meta-index *.jar
+ @$(CD) $(JRE_MODULE_IMAGE_DIR)/lib/ext && $(java-vm-cleanup)
+ifeq ($(PLATFORM), windows)
+ @# Remove certain *.lib files
+ $(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \
+ $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \
+ hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ @# The Java Kernel JRE image ships with a special VM. It is not included
+ @# in the full JRE image, so remove it. Also, is it only for 32-bit windows.
+ $(CD) $(JRE_MODULE_IMAGE_DIR)/bin && $(RM) -r kernel
+ endif
+endif # Windows
+ifneq ($(PLATFORM), windows)
+ $(call copy-man-pages,$(JRE_MODULE_IMAGE_DIR),$(JRE_MAN_PAGES))
+endif # !windows
+
+# Trim out any extra files not for the jre shipment but wanted in the jdk jre.
+# (Note the jdk WILL want the jre image before this trimming)
+# Removes server VM on Windows 32bit.
+# Remove certain shared libraries that should not be in the jre image
+# but should be in the jdk jre image.
+trim-module-image-jre::
+ifeq ($(PLATFORM), windows)
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ $(RM) -r $(JRE_MODULE_IMAGE_DIR)/bin/server
+ endif
+ ifdef NOTJRE_SHARED_LIBS
+ for l in $(NOTJRE_SHARED_LIBS) ; do \
+ $(RM) $(JRE_MODULE_IMAGE_DIR)/bin/$$l ; \
+ done ;
+ endif
+else # PLATFORM
+ ifdef NOTJRE_SHARED_LIBS
+ for l in $(NOTJRE_SHARED_LIBS) ; do \
+ $(RM) $(JRE_MODULE_IMAGE_DIR)/lib/$(LIBARCH)/$$l ; \
+ done ;
+ endif
+endif # PLATFORM
+
+# Get list of all Elf files in the jre
+JRE_MODULE_ELF_LIST=$(MODULES_TEMPDIR)/jre-elf-files.list
+$(JRE_MODULE_ELF_LIST):
+ @$(prep-target)
+ifneq ($(PLATFORM), windows)
+ $(RM) $@
+ $(FIND) $(JRE_MODULE_IMAGE_DIR)/lib -type f -name \*.$(LIB_SUFFIX) >> $@
+ $(FILE) `$(FIND) $(JRE_MODULE_IMAGE_DIR)/bin -type f -name \*$(EXE_SUFFIX)` \
+ | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@
+endif
+
+# Post process the image (strips and mcs on Elf files we are shipping)
+# (Note the jdk WILL want the jre image before this processing)
+process-module-image-jre:: $(JRE_MODULE_ELF_LIST)
+ifneq ($(POST_STRIP_PROCESS), )
+ for f in `$(CAT) $(JRE_MODULE_ELF_LIST)`; do \
+ $(CHMOD) u+w $${f}; \
+ $(ECHO) $(POST_STRIP_PROCESS) $${f}; \
+ $(POST_STRIP_PROCESS) $${f}; \
+ $(CHMOD) go-w $${f}; \
+ done
+endif
+ifneq ($(POST_MCS_PROCESS), )
+ for f in `$(CAT) $(JRE_MODULE_ELF_LIST)`; do \
+ $(CHMOD) u+w $${f}; \
+ $(ECHO) $(POST_MCS_PROCESS) $${f}; \
+ $(POST_MCS_PROCESS) $${f}; \
+ $(CHMOD) go-w $${f}; \
+ done
+endif
+ $(RM) $(JRE_MODULE_ELF_LIST)
+
+######################################################
+# JDK Image
+######################################################
+# Note: cpio ($(CPIO)) sometimes leaves directories without rx access.
+
+initial-module-image-jdk-setup:
+ $(RM) -r $(JDK_MODULE_IMAGE_DIR)
+ $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/jre
+ ($(CD) $(JRE_MODULE_IMAGE_DIR) && $(FIND) . -depth -print \
+ | $(CPIO) -pdum $(JDK_MODULE_IMAGE_DIR)/jre )
+ $(RM) -rf $(JDK_MODULE_IMAGE_DIR)/jre/man
+ $(CHMOD) a+rx `$(FIND) $(JDK_MODULE_IMAGE_DIR) -type d`
+
+initial-module-image-jdk64-bindemos:
+ for dir in bin demo ; do \
+ ( $(CD) $(OUTPUTDIR) && \
+ $(TAR) cf - `$(FIND) $$dir -name '$(LIBARCH)' -print` | \
+ ($(CD) $(JDK_MODULE_IMAGE_DIR) && $(TAR) xf -) ) ; \
+ done
+
+# Solaris 64 bit image is special
+initial-module-image-jdk-sol64:: initial-module-image-jdk-setup \
+ initial-module-image-jdk64-bindemos \
+ $(JDK_MODULE_LICENSES) $(JDK_MODULARLIZED_64_LICENSES)
+
+# DB files to add
+ifeq ($(OPENJDK),true)
+
+initial-module-image-jdk-db:
+
+else
+
+# Create the list of db *.zip files to bundle with jdk
+ABS_DB_PATH :=$(call FullPath,$(CLOSED_SHARE_SRC)/db)
+DB_ZIP_LIST = $(shell $(LS) $(ABS_DB_PATH)/*.zip 2>/dev/null)
+
+initial-module-image-jdk-db: $(DB_ZIP_LIST)
+ $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/db
+ for d in $(DB_ZIP_LIST); do \
+ ($(CD) $(JDK_MODULE_IMAGE_DIR)/db && $(UNZIP) -o $$d); \
+ done
+
+endif
+
+# Standard jdk image
+initial-module-image-jdk:: initial-module-image-jdk-setup \
+ initial-module-image-jdk-db \
+ $(JDK_MODULE_LICENSES) $(JDK_MODULE_DOCFILES)
+ $(MKDIR) $(JDK_MODULE_IMAGE_DIR)/lib
+ @#
+ @# copy jdk modules to jdk/lib
+ @#
+ $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/lib
+ $(CP) -rf $(MODULES_LIB)/lib/* $(JDK_MODULE_IMAGE_DIR)/lib
+ ifeq ($(PLATFORM), windows)
+ @#
+ @# lib/
+ @#
+ $(CP) $(LIBDIR)/$(LIB_PREFIX)jvm.$(LIB_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/lib
+ $(CP) $(LIBDIR)/$(LIB_PREFIX)jawt.$(LIB_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/lib
+ @#
+ @# bin/
+ @#
+ @# copy all EXE files and only certain DLL files from BINDIR
+ $(MKDIR) -p $(JDK_MODULE_IMAGE_DIR)/bin
+ $(CP) $(BINDIR)/*$(EXE_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin
+ $(CP) $(BINDIR)/jli.$(LIBRARY_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ ifeq ($(COMPILER_VERSION), VS2003)
+ $(CP) $(BINDIR)/msvc*71.$(LIBRARY_SUFFIX) $(JDK_MODULE_IMAGE_DIR)/bin
+ endif
+ endif
+ else # PLATFORM
+ @#
+ @# bin/
+ @#
+ ($(CD) $(BINDIR)/.. && $(TAR) cf - \
+ `$(FIND) bin \( -type f -o -type l \) -print `) | \
+ ($(CD) $(JDK_MODULE_IMAGE_DIR) && $(TAR) xf -)
+ endif # PLATFORM
+ @#
+ @# lib/ct.sym
+ @#
+ $(MKDIR) -p $(OUTPUTDIR)/symbols/META-INF/sym
+ $(JAVAC_CMD) -XDprocess.packages -proc:only \
+ -processor com.sun.tools.javac.sym.CreateSymbols \
+ -Acom.sun.tools.javac.sym.Jar=$(RT_JAR) \
+ -Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \
+ $(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS)
+ $(BOOT_JAR_CMD) c0f $(LIBDIR)/ct.sym \
+ -C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS)
+ @$(java-vm-cleanup)
+ $(CP) $(LIBDIR)/ct.sym $(JDK_MODULE_IMAGE_DIR)/lib/ct.sym
+ @#
+ @# CORBA supported orb.idl and ir.idl should be copied to lib
+ @#
+ $(CP) $(LIBDIR)/orb.idl $(JDK_MODULE_IMAGE_DIR)/lib/orb.idl
+ $(CP) $(LIBDIR)/ir.idl $(JDK_MODULE_IMAGE_DIR)/lib/ir.idl
+ ifeq ($(PLATFORM), linux)
+ @#
+ @# on Linux copy jexec from jre/lib to /lib
+ @#
+ $(CP) $(LIBDIR)/jexec $(JDK_MODULE_IMAGE_DIR)/lib/jexec
+ endif # PLATFORM
+ @#
+ @# demo, include
+ @#
+ $(CP) -r -f $(DEMODIR) $(JDK_MODULE_IMAGE_DIR)
+ $(CP) -r -f $(SAMPLEDIR) $(JDK_MODULE_IMAGE_DIR)
+ $(CP) -r $(INCLUDEDIR) $(JDK_MODULE_IMAGE_DIR)
+ @#
+ @# Swing BeanInfo generation
+ @#
+ $(CD) javax/swing/beaninfo && $(MAKE) JDK_IMAGE_DIR=$(JDK_MODULE_IMAGE_DIR) swing-1.2-beans
+ifneq ($(PLATFORM), windows)
+ $(call copy-man-pages,$(JDK_MODULE_IMAGE_DIR),$(JDK_MAN_PAGES))
+endif # !windows
+
+# Trim out files we don't want to ship
+trim-module-image-jdk::
+ @# Remove tools that should not be part of SDK.
+ for t in $(NOTJDKTOOLS); do \
+ $(RM) $(JDK_MODULE_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX) \
+ $(JDK_MODULE_IMAGE_DIR)/bin/*/native_threads/$${t}$(EXE_SUFFIX); \
+ done
+
+# Get list of Elf files in the jdk
+JDK_MODULE_ELF_LIST=$(MODULES_TEMPDIR)/jdk-elf-files.list
+$(JDK_MODULE_ELF_LIST):
+ @$(prep-target)
+ifneq ($(PLATFORM), windows)
+ $(RM) $@
+ $(FIND) $(JDK_MODULE_IMAGE_DIR)/jre/lib -type f -name \*.$(LIB_SUFFIX) >> $@
+ $(FILE) `$(FIND) $(JDK_MODULE_IMAGE_DIR)/jre/bin -type f -name \*$(EXE_SUFFIX)` \
+ | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@
+ file `$(FIND) $(JDK_MODULE_IMAGE_DIR)/bin -type f -name \*$(EXE_SUFFIX)` \
+ | $(EGREP) 'ELF' | $(CUT) -d':' -f1 >> $@
+endif
+
+# Post process the image (strips and mcs on files we are shipping)
+process-module-image-jdk:: $(JDK_MODULE_ELF_LIST)
+ifneq ($(POST_STRIP_PROCESS), )
+ for f in `$(CAT) $(JDK_MODULE_ELF_LIST)`; do \
+ $(CHMOD) u+w $${f}; \
+ $(ECHO) $(POST_STRIP_PROCESS) $${f}; \
+ $(POST_STRIP_PROCESS) $${f}; \
+ $(CHMOD) go-w $${f}; \
+ done
+endif
+ifneq ($(POST_MCS_PROCESS), )
+ for f in `$(CAT) $(JDK_MODULE_ELF_LIST)`; do \
+ $(CHMOD) u+w $${f}; \
+ $(ECHO) $(POST_MCS_PROCESS) $${f}; \
+ $(POST_MCS_PROCESS) $${f}; \
+ $(CHMOD) go-w $${f}; \
+ done
+endif
+ $(RM) $(JDK_MODULE_ELF_LIST)
+
+######################################################
+# clobber
+######################################################
+modules-clobber::
+ $(RM) -r $(JDK_MODULE_IMAGE_DIR)
+ $(RM) -r $(JRE_MODULE_IMAGE_DIR)
+
+#
+# TODO - nop for now
+sanity-module-images post-sanity-module-images:
+
+modules modules-clobber::
+ @$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
+ @$(java-vm-cleanup)
+
+.PHONY: modules module-image-jre module-image-jdk \
+ initial-module-image-jre initial-module-image-jdk \
+ initial-module-image-jre-sol64 initial-module-image-jdk-sol64 \
+ initial-module-image-jdk-setup \
+ initial-module-image-jdk-db \
+ initial-module-image-jdk64-bindemos \
+ initial-module-image-jre-setup \
+ trim-module-image-jre trim-module-image-jdk \
+ process-module-image-jre process-module-image-jdk \
+ install-previous-jre install-previous-jdk \
+ modules-clobber
+
+# Force rule
+FRC:
+
--- a/jdk/make/java/java/mapfile-vers Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/java/mapfile-vers Wed Jul 05 17:04:56 2017 +0200
@@ -150,10 +150,8 @@
Java_java_lang_StrictMath_asin;
Java_java_lang_StrictMath_atan;
Java_java_lang_StrictMath_atan2;
- Java_java_lang_StrictMath_ceil;
Java_java_lang_StrictMath_cos;
Java_java_lang_StrictMath_exp;
- Java_java_lang_StrictMath_floor;
Java_java_lang_StrictMath_log;
Java_java_lang_StrictMath_log10;
Java_java_lang_StrictMath_pow;
--- a/jdk/make/java/java/reorder-i586 Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/java/reorder-i586 Wed Jul 05 17:04:56 2017 +0200
@@ -107,4 +107,3 @@
text: .text%Java_java_util_TimeZone_getSystemTimeZoneID;
text: .text%findJavaTZ_md;
text: .text%Java_java_lang_StrictMath_log;
-text: .text%Java_java_lang_StrictMath_floor;
--- a/jdk/make/java/java/reorder-sparc Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/java/reorder-sparc Wed Jul 05 17:04:56 2017 +0200
@@ -105,4 +105,3 @@
text: .text%findJavaTZ_md;
text: .text%Java_java_lang_StrictMath_log;
text: .text%Java_java_lang_StrictMath_sqrt;
-text: .text%Java_java_lang_StrictMath_floor;
--- a/jdk/make/java/java/reorder-sparcv9 Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/java/reorder-sparcv9 Wed Jul 05 17:04:56 2017 +0200
@@ -101,4 +101,3 @@
text: .text%findJavaTZ_md;
text: .text%Java_java_lang_StrictMath_log;
text: .text%Java_java_lang_StrictMath_sqrt;
-text: .text%Java_java_lang_StrictMath_floor;
--- a/jdk/make/java/jli/Makefile Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/jli/Makefile Wed Jul 05 17:04:56 2017 +0200
@@ -152,7 +152,6 @@
STATIC_LIBRARY = $(STATIC_LIBRARY_DIR)/$(STATIC_LIBRARY_NAME)
$(STATIC_LIBRARY_DIR): $(OBJDIR)
- @$(prep-target)
@$(MKDIR) $(STATIC_LIBRARY_DIR)
$(STATIC_LIBRARY): $(STATIC_LIBRARY_DIR)
--- a/jdk/make/java/nio/FILES_java.gmk Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/nio/FILES_java.gmk Wed Jul 05 17:04:56 2017 +0200
@@ -234,6 +234,7 @@
sun/nio/cs/UTF_16BE.java \
sun/nio/cs/UTF_16LE.java \
sun/nio/cs/UTF_8.java \
+ sun/nio/cs/Unicode.java \
sun/nio/cs/UnicodeDecoder.java \
sun/nio/cs/UnicodeEncoder.java \
sun/nio/cs/UTF_32.java \
--- a/jdk/make/java/nio/genBuffer.sh Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/make/java/nio/genBuffer.sh Wed Jul 05 17:04:56 2017 +0200
@@ -44,6 +44,7 @@
case $type in
char) fulltype=character;;
+ int) fulltype=integer;;
*) fulltype=$type;;
esac
@@ -54,6 +55,11 @@
long | double) LBPV=3;;
esac
+case $type in
+ float|double) floatingPointOrIntegralType=floatingPointType;;
+ *) floatingPointOrIntegralType=integralType;;
+esac
+
typesAndBits() {
type="$1"; BO="$2"
@@ -101,6 +107,7 @@
$SPP <$SRC >$DST \
-K$type \
+ -K$floatingPointOrIntegralType \
-Dtype=$type \
-DType=$Type \
-Dfulltype=$fulltype \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/Makefile Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,145 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# Modularizing the JDK
+#
+
+BUILDDIR = ..
+include $(BUILDDIR)/common/Defs.gmk
+
+CLASSANALYZER_JAR=$(BUILDTOOLJARDIR)/classanalyzer.jar
+JAVA_FLAGS=$(JAVA_TOOLS_FLAGS) -Xbootclasspath:$(CLASSBINDIR)
+
+MODULE_LIB = $(ABS_OUTPUTDIR)/modules
+MAINMANIFEST=$(JDK_TOPDIR)/make/tools/manifest.mf
+MODULE_JAR_MANIFEST_FILE=$(ABS_TEMPDIR)/manifest.tmp
+
+TMP=$(ABS_TEMPDIR)/modules
+MODULE_CLASSLIST = $(TMP)/classlist
+MODULE_CLASSES = $(TMP)/classes
+MODULE_LIST = $(MODULE_CLASSLIST)/modules.list
+
+# Modules in the modules/ext directory
+EXT_MODULES = localedata security-sunec security-sunjce
+
+# Build PKCS#11 on all platforms except 64-bit Windows.
+# We exclude windows-amd64 because we don't have any
+# 64-bit PKCS#11 implementations to test with on that platform.
+PKCS11 = security-sunpkcs11
+ifeq ($(ARCH_DATA_MODEL), 64)
+ ifeq ($(PLATFORM), windows)
+ PKCS11 =
+ endif
+endif
+
+EXT_MODULES += $(PKCS11)
+
+# Build Microsoft CryptoAPI provider only on (non-64-bit) Windows platform.
+ifeq ($(PLATFORM), windows)
+ ifneq ($(ARCH_DATA_MODEL), 64)
+ EXT_MODULES += security-sunmscapi
+ endif
+endif
+
+
+JDK_MODULES = tools
+
+SUBDIRS = tools
+all build clean clobber::
+ $(SUBDIRS-loop)
+
+all:: unpack-jars gen-classlist modularize
+
+$(CLASSANALYZER_JAR):
+ $(CD) tools && $(MAKE) all
+
+JAR_LIST := $(shell $(FIND) $(ABS_OUTPUTDIR)/lib -name \*.jar -depth)
+unpack-jars:
+ $(RM) -rf $(MODULE_CLASSES)
+ $(MKDIR) -p $(MODULE_CLASSES)
+ $(CP) -rf $(CLASSBINDIR)/* $(MODULE_CLASSES)
+ for jf in $(JAR_LIST) ; do \
+ $(CD) $(MODULE_CLASSES) && $(BOOT_JAR_CMD) xf $$jf $(BOOT_JAR_JFLAGS);\
+ done
+
+gen-classlist: $(CLASSANALYZER_JAR)
+ @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
+ @$(RM) -rf $(MODULE_CLASSLIST)
+ @$(MKDIR) -p $(MODULE_CLASSLIST)
+
+ @# Use java in the default tool directory.
+ @# OUTPUTDIR for solaris 64-bit doesn't have the tools.
+ $(JAVA_TOOLS_DIR)/java $(JAVA_FLAGS) \
+ -Dclassanalyzer.debug \
+ -jar $(CLASSANALYZER_JAR) \
+ -jdkhome $(OUTPUTDIR) \
+ -config modules.config \
+ -config modules.group \
+ -depconfig jdk7.depconfig \
+ -depconfig optional.depconfig \
+ -showdynamic \
+ -output $(MODULE_CLASSLIST)
+ @$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
+
+modularize: $(MODULE_JAR_MANIFEST_FILE)
+ @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
+ @$(RM) -rf $(MODULE_LIB)
+ @$(MKDIR) -p $(MODULE_LIB)/lib
+ @$(MKDIR) -p $(MODULE_LIB)/jre/lib/ext
+
+ @# create modules
+ for m in `$(NAWK) '{print $$1}' $(MODULE_LIST)` ; do \
+ $(ECHO) "Creating module $$m" ; \
+ $(SED) -e 's%\\%\/%g' < $(MODULE_CLASSLIST)/$$m.classlist > $(TMP)/tmp.cf ; \
+ if [ -f $(MODULE_CLASSLIST)/$$m.resources ] ; then \
+ $(SED) -e 's%\\%\/%g' < $(MODULE_CLASSLIST)/$$m.resources >> $(TMP)/tmp.cf ; \
+ fi ; \
+ $(CD) $(MODULE_CLASSES) && \
+ $(BOOT_JAR_CMD) c0mf $(MODULE_JAR_MANIFEST_FILE) \
+ $(MODULE_LIB)/$$m.jar \
+ @$(TMP)/tmp.cf \
+ $(BOOT_JAR_JFLAGS) ; \
+ done
+ @$(CD) $(MODULE_CLASSES) && $(java-vm-cleanup)
+ @# move modules to lib, jre/lib, or jre/lib/ext
+ for m in $(EXT_MODULES) ; do \
+ $(MV) $(MODULE_LIB)/$$m.jar $(MODULE_LIB)/jre/lib/ext ; \
+ done
+ for m in $(JDK_MODULES) ; do \
+ $(MV) $(MODULE_LIB)/$$m.jar $(MODULE_LIB)/lib ; \
+ done
+ $(MV) $(MODULE_LIB)/*.jar $(MODULE_LIB)/jre/lib
+ @$(ECHO) ">>>Finished making "$@" @ `$(DATE)` ..."
+
+$(MODULE_JAR_MANIFEST_FILE):
+ $(SED) -e "s/@@RELEASE@@/$(RELEASE)/" $(MAINMANIFEST) > $@
+
+clean clobber::
+ $(RM) -rf $(MODULE_CLASSLIST)
+ $(RM) -rf $(MODULE_LIB)
+ $(RM) -f $(MODULE_JAR_MANIFEST_FILE)
+ $(RM) -f $(CLASSANALYZER_JAR)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/bootmodule.roots Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,199 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# List of root classes/methods, each line of the following syntax:
+# <class name>
+# <method name> <signature>|*
+# exclude <class>|<method>
+
+# The boot module generated based on this rootset does not support
+# - security permission check
+# - non-standard charset
+# - logging output
+# - resource bundles
+# including error output from the launcher
+
+# VM preloaded classes
+java.lang.Object
+java.lang.String
+java.lang.Class
+java.lang.Cloneable
+java.lang.ClassLoader
+java.lang.System
+java.lang.Throwable
+java.lang.Error
+java.lang.ThreadDeath
+java.lang.Exception
+java.lang.RuntimeException
+java.security.ProtectionDomain
+java.security.AccessControlContext
+java.lang.ClassNotFoundException
+java.lang.NoClassDefFoundError
+java.lang.ClassCastException
+java.lang.ArrayStoreException
+java.lang.VirtualMachineError
+java.lang.OutOfMemoryError
+java.lang.StackOverflowError
+java.lang.IllegalMonitorStateException
+java.lang.ref.Reference
+java.lang.ref.SoftReference
+java.lang.ref.WeakReference
+java.lang.ref.FinalReference
+java.lang.ref.PhantomReference
+java.lang.ref.Finalizer
+java.lang.Runnable
+java.lang.Thread
+java.lang.ThreadGroup
+java.util.Properties
+java.lang.reflect.AccessibleObject
+java.lang.reflect.Member
+java.lang.reflect.Field
+java.lang.reflect.Method
+java.lang.reflect.Constructor
+java.lang.reflect.Type
+sun.reflect.MagicAccessorImpl
+sun.reflect.MethodAccessorImpl
+sun.reflect.ConstructorAccessorImpl
+sun.reflect.DelegatingClassLoader
+sun.reflect.ConstantPool
+sun.reflect.UnsafeStaticFieldAccessorImpl
+java.util.Vector
+java.lang.StringBuffer
+java.lang.StackTraceElement
+java.nio.Buffer
+java.lang.Boolean
+java.lang.Character
+java.lang.Float
+java.lang.Double
+java.lang.Byte
+java.lang.Short
+java.lang.Integer
+java.lang.Long
+java.lang.NullPointerException
+java.lang.ArithmeticException
+java.lang.Compiler
+
+
+# Root methods
+java.lang.ClassLoader.getSystemClassLoader ()Ljava/lang/ClassLoader;
+java.lang.System.initializeSystemClass ()V
+sun.launcher.LauncherHelper.checkAndLoadMain (ZZLjava/lang/String;)Ljava/lang/Object;
+
+# The tool doesn't automatically find superclasses and parse the method
+# if overridden as it tries to reduce unnecessary classes being pulled in.
+# The following forces the dependency to be included the result.
+sun.net.www.protocol.file.Handler.<init> ()V
+sun.net.www.protocol.jar.Handler.<init> ()V
+sun.net.www.protocol.file.Handler.openConnection *
+sun.net.www.protocol.jar.Handler.openConnection *
+sun.misc.URLClassPath$JarLoader.<init> (Ljava/net/URL;Ljava/net/URLStreamHandler;Ljava/util/HashMap;)V
+sun.misc.URLClassPath$FileLoader.<init> (Ljava/net/URL;)V
+sun.misc.URLClassPath$FileLoader.getClassPath *
+sun.misc.URLClassPath$FileLoader.getResource *
+sun.misc.URLClassPath$JarLoader.getResource *
+sun.misc.URLClassPath$JarLoader.getClassPath *
+
+# permission collections
+java.io.FilePermission.newPermissionCollection ()Ljava/security/PermissionCollection;
+java.security.BasicPermission.newPermissionCollection ()Ljava/security/PermissionCollection;
+
+# native
+java.io.UnixFileSystem
+java.io.UnixFileSystem.<init> ()V
+java.io.UnixFileSystem.canonicalize *
+java.io.Win32FileSystem
+java.io.Win32FileSystem.<init> ()V
+java.io.Win32FileSystem.canonicalize *
+java.io.WinNTFileSystem
+java.io.WinNTFileSystem.<init> ()V
+java.io.WinNTFileSystem.canonicalize *
+
+# missing
+java.util.HashMap.<init> ()V
+java.util.HashMap$EntrySet.iterator *
+
+# Called from native GetStringPlatformChars (jni_util.c)
+java.lang.String.getBytes *
+
+# charset
+sun.nio.cs.US_ASCII.newEncoder ()Ljava/nio/charset/CharsetEncoder;
+sun.nio.cs.UTF_8.newEncoder ()Ljava/nio/charset/CharsetEncoder;
+sun.nio.cs.UTF_8.newDecoder *
+sun.nio.cs.UTF_16.newEncoder ()Ljava/nio/charset/CharsetEncoder;
+sun.nio.cs.UTF_16.newDecoder *
+sun.nio.cs.UTF_32.newEncoder ()Ljava/nio/charset/CharsetEncoder;
+sun.nio.cs.UTF_32.newDecoder *
+
+# hashcode
+java.util.jar.Attributes$Name.hashCode *
+
+# nio
+sun.nio.ByteBuffered
+sun.nio.ch.DirectBuffer
+java.nio.DirectByteBuffer
+java.nio.MappedByteBuffer
+java.nio.DirectLongBufferU
+
+# resource files
+sun.launcher.resources.launcher
+
+sun.misc.Launcher$AppClassLoader.getPermissions *
+sun.misc.Launcher$AppClassLoader.loadClass (Ljava/lang/String;)Ljava/lang/Class;
+sun.misc.Launcher$AppClassLoader.findClass (Ljava/lang/String;)Ljava/lang/Class;
+sun.misc.Launcher$ExtClassLoader.getPermissions *
+sun.misc.Launcher$ExtClassLoader.loadClass (Ljava/lang/String;)Ljava/lang/Class;
+sun.misc.Launcher$ExtClassLoader.findClass (Ljava/lang/String;)Ljava/lang/Class;
+java.lang.ClassLoader.checkPackageAccess *
+java.lang.ClassLoader.findClass *
+java.lang.ClassLoader.defineClass *
+java.net.URLClassLoader.getPermissions *
+java.net.URLClassLoader.findClass *
+java.net.URLClassLoader.defineClass *
+java.security.SecureClassLoader.defineClass *
+# need to parse superclasses <init>
+java.security.SecureClassLoader.<init> ()V
+
+exclude sun.security.provider.PolicyFile.<init>
+exclude java.lang.ClassLoader.compareCerts
+exclude java.security.cert.Certificate.equals
+# unsigned jars - no verifier
+exclude java.util.jar.JarFile.initializeVerifier
+exclude java.util.jar.JarVerifier
+exclude sun.security.util.SignatureFileVerifier.<init>
+
+
+# what about other charset
+exclude sun.misc.Service
+exclude java.util.ServiceLoader
+
+# exclude support for localized messages
+exclude java.util.ResourceBundle.getBundle
+exclude java.text.MessageFormat
+exclude sun.util.logging.PlatformLogger$LoggerProxy.format *
+
+# exclude nio and miscellaneous classes
+exclude java.nio.channels.**
+exclude sun.misc.FloatingDecimal
+exclude sun.misc.FormattedFloatingDecimal
+exclude sun.misc.FDBigInt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/jdk7.depconfig Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,473 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# private java.lang.Object createInetSocketAddress(java.lang.String, int)
+@ClassForName
+ com.sun.jndi.ldap.Connection -> java.net.InetSocketAddress
+ com.sun.jndi.ldap.Connection -> java.net.SocketAddress
+
+# com.sun.jndi.ldap.VersionHelper
+@ClassForName(optional)
+ com.sun.jndi.ldap.VersionHelper -> com.sun.jndi.ldap.VersionHelper*
+
+# private static void initMethodHandles()
+@ClassForName
+ com.sun.jndi.toolkit.corba.CorbaUtils -> javax.rmi.CORBA.Stub
+ com.sun.jndi.toolkit.corba.CorbaUtils -> javax.rmi.PortableRemoteObject
+
+# com.sun.naming.internal.ResourceManager$AppletParameter
+@ClassForName(optional)
+ com.sun.naming.internal.ResourceManager$AppletParameter -> java.applet.Applet
+
+# private static boolean loadProviderAsService()
+@Provider
+ com.sun.net.httpserver.spi.HttpServerProvider -> META-INF/services/com.sun.net.httpserver.spi.HttpServerProvider
+
+# com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT
+@ClassForName
+ com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT -> javax.xml.XMLConstants
+
+# public static java.beans.PersistenceDelegate getPersistenceDelegate(java.lang.Class)
+@ClassForName
+ java.beans.MetaData -> java.beans.*_PersistenceDelegate
+
+# private static java.lang.reflect.Method getNanosMethod()
+@ClassForName(optional)
+ java.beans.java_sql_Timestamp_PersistenceDelegate -> java.sql.Timestamp
+
+# java.beans.java_util_Collections$CheckedCollection_PersistenceDelegate
+@ClassForName
+ java.beans.java_util_Collections$CheckedCollection_PersistenceDelegate -> java.util.Collections$CheckedCollection
+
+# java.beans.java_util_Collections$CheckedMap_PersistenceDelegate
+@ClassForName
+ java.beans.java_util_Collections$CheckedMap_PersistenceDelegate -> java.util.Collections$CheckedMap
+
+# private static java.lang.Object getType(java.lang.Object)
+@ClassForName
+ java.beans.java_util_EnumMap_PersistenceDelegate -> java.util.EnumMap
+
+# private java.lang.Integer getAxis(java.lang.Object)
+@ClassForName
+ java.beans.javax_swing_Box_PersistenceDelegate -> javax.swing.BoxLayout
+
+# java.lang.Double
+@Inline
+ java.lang.Double -> sun.misc.FloatConsts
+ java.lang.Double -> sun.misc.DoubleConsts
+
+# java.lang.Float
+@Inline
+ java.lang.Float -> sun.misc.FloatConsts
+ java.lang.Float -> sun.misc.DoubleConsts
+
+# java.net.DefaultDatagramSocketImplFactory
+@ClassForName(optional)
+ java.net.DefaultDatagramSocketImplFactory -> java.net.*DatagramSocketImpl
+
+# private static sun.net.spi.nameservice.NameService createNSProvider(java.lang.String)
+@Provider
+ java.net.InetAddress -> META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
+
+# static java.net.InetAddressImpl create()
+@ClassForName
+ java.net.InetAddressImplFactory -> java.net.*Inet[46]AddressImpl
+
+# private static void init()
+@NativeFindClass
+ java.net.PlainDatagramSocketImpl -> java.io.FileDescriptor
+
+# java.net.ProxySelector
+@ClassForName
+ java.net.ProxySelector -> sun.net.spi.DefaultProxySelector
+
+# static java.net.URLStreamHandler getURLStreamHandler(java.lang.String)
+@ClassForName(optional)
+ java.net.URL -> sun.net.www.protocol.*.Handler
+
+# private java.net.ContentHandler lookupContentHandlerClassFor(java.lang.String)
+@ClassForName
+ java.net.URLConnection -> sun.net.www.content.*
+
+# private static java.nio.channels.spi.AsynchronousChannelProvider loadProviderAsService()
+@Provider
+ java.nio.channels.spi.AsynchronousChannelProvider$ProviderHolder -> META-INF/services/java.nio.channels.spi.AsynchronousChannelProvider
+
+# private static boolean loadProviderFromProperty()
+@ClassForName
+ java.nio.channels.spi.SelectorProvider -> sun.nio.ch.DefaultSelectorProvider
+
+# private static boolean loadProviderAsService()
+@Provider
+ java.nio.channels.spi.SelectorProvider -> META-INF/services/java.nio.channels.spi.SelectorProvider
+
+# private static java.util.Iterator providers()
+@Provider
+ java.nio.charset.Charset -> META-INF/services/java.nio.charset.spi.CharsetProvider
+
+# private static void probeExtendedProvider()
+@ClassForName(optional)
+ java.nio.charset.Charset -> sun.nio.cs.ext.ExtendedCharsets
+
+# public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>, java.lang.ClassLoader)
+@Provider
+ java.nio.file.FileSystems -> META-INF/services/java.nio.file.FileSystemProvider
+
+# private static java.util.List<java.nio.file.spi.FileTypeDetector> loadInstalledDetectors()
+@Provider
+ java.nio.file.Files$DefaultFileTypeDetectorHolder -> META-INF/services/java.nio.file.spi.FileTypeDetector
+
+# public static java.util.List<java.nio.file.spi.FileSystemProvider> installedProviders()
+@Provider
+ java.nio.file.spi.FileSystemProvider -> META-INF/services/java.nio.file.FileSystemProvider
+
+# private static java.rmi.server.RMIClassLoaderSpi initializeProvider()
+@Provider
+ java.rmi.server.RMIClassLoader -> META-INF/services/java.rmi.server.RMIClassLoaderSpi
+
+# private static void initializeSystemScope()
+@ClassForName(optional)
+ java.security.IdentityScope -> sun.security.provider.IdentityDatabase
+
+# static java.security.Policy getPolicyNoCheck()
+@ClassForName
+ java.security.Policy -> sun.security.provider.PolicyFile
+
+# private static java.lang.Class getSpiClass(java.lang.String)
+@ClassForName
+ java.security.Security -> java.security.*Spi
+
+# private static void invalidateSMCache(java.lang.String)
+@ClassForName
+ java.security.Security -> java.lang.SecurityManager
+
+# private static void loadInitialDrivers()
+@Provider
+ java.sql.DriverManager -> META-INF/services/java.sql.Driver
+
+# private static java.text.BreakIterator createBreakInstance(java.util.Locale, int, java.lang.String, java.lang.String)
+@Provider
+ java.text.BreakIterator -> META-INF/services/java.util.spi.BreakIteratorProvider
+
+# public static java.text.Collator getInstance(java.util.Locale)
+@Provider
+ java.text.Collator -> META-INF/services/java.util.spi.CollatorProvider
+
+# private static java.text.DateFormat get(int, int, int, java.util.Locale)
+@Provider
+ java.text.DateFormat -> META-INF/services/java.util.spi.DateNameProvider
+
+# public static java.util.Locale[] getAvailableLocales()
+@Provider
+ java.text.DateFormatSymbols -> META-INF/services/java.util.spi.DateFormatSymbolsProvider
+
+# public static java.util.Locale[] getAvailableLocales()
+@Provider
+ java.text.DecimalFormatSymbols -> META-INF/services/java.util.spi.DecimalFormatSymbolsProvider
+
+# public static java.util.Locale[] getAvailableLocales()
+@Provider
+ java.text.NumberFormat -> META-INF/services/java.util.spi.NumberFormatProvider
+
+# public java.lang.String getDisplayName(java.util.Locale)
+@Provider
+ java.util.Currency -> META-INF/services/java.util.spi.CurrencyNameProvider
+
+# java.util.Formatter
+@Inline
+ java.util.Formatter -> sun.misc.DoubleConsts
+
+# java.util.Locale
+@Inline
+ java.util.Locale -> java.util.LocaleISOData
+
+# private java.lang.String getDisplayString(java.lang.String, java.util.Locale, int)
+@Provider
+ java.util.Locale -> META-INF/services/java.util.spi.LocaleNameProvider
+
+# private static java.util.prefs.PreferencesFactory factory1()
+@ClassForName
+ java.util.prefs.Preferences -> java.util.prefs.WindowsPreferencesFactory
+ java.util.prefs.Preferences -> java.util.prefs.FileSystemPreferencesFactory
+
+# private static java.util.prefs.PreferencesFactory factory1()
+@Provider
+ java.util.prefs.Preferences -> META-INF/services/java.util.prefs.PreferencesFactory
+
+# public void registerApplicationClasspathSpis()
+@Provider
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.IIOServiceProvider
+
+# private void registerInstalledProviders()
+@Provider
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageReaderSpi
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageWriterSpi
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageReaderWriterSpi
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageTranscoderSpi
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageInputStreamSpi
+ javax.imageio.spi.IIORegistry -> META-INF/services/javax.imageio.spi.ImageOutputStreamSpi
+
+# public javax.naming.ldap.ExtendedResponse createExtendedResponse(java.lang.String, byte[], int, int)
+@Provider
+ javax.naming.ldap.StartTlsRequest -> META-INF/services/javax.naming.ldap.StartTlsResponse
+
+# private static java.util.ArrayList getAllLookupServices()
+@Provider
+ javax.print.PrintServiceLookup -> META-INF/services/javax.print.PrintServiceLookup
+
+# private static java.util.ArrayList getAllFactories()
+@Provider
+ javax.print.StreamPrintServiceFactory -> META-INF/services/javax.print.StreamPrintServiceFactory
+
+# private void initEngines(java.lang.ClassLoader)
+@Provider
+ javax.script.ScriptEngineManager -> META-INF/services/javax.script.ScriptEngineFactory
+
+# private void initializeInputMethodLocatorList()
+@Provider
+ sun.awt.im.ExecutableInputMethodManager -> META-INF/services/java.awt.im.spi.InputMethodDescriptor
+
+# private static java.lang.Class getConverterClass(int, java.lang.String)
+@ClassForName(optional)
+ sun.io.Converters -> sun.io.*
+
+# public static sun.java2d.cmm.PCMM getModule()
+@Provider
+ sun.java2d.cmm.CMSManager -> META-INF/services/sun.java2d.cmm.PCMM
+
+# public static sun.java2d.pipe.RenderingEngine getInstance()
+@Provider
+ sun.java2d.pipe.RenderingEngine -> META-INF/services/sun.java2d.pipe.RenderingEngine
+
+# public static sun.java2d.pipe.RenderingEngine getInstance()
+@ClassForName(optional)
+ sun.java2d.pipe.RenderingEngine -> sun.dc.DuctusRenderingEngine
+
+# sun.misc.FloatingDecimal
+@Inline
+ sun.misc.FloatingDecimal -> sun.misc.FloatConsts
+ sun.misc.FloatingDecimal -> sun.misc.DoubleConsts
+
+# sun.misc.FormattedFloatingDecimal
+@Inline
+ sun.misc.FormattedFloatingDecimal -> sun.misc.FloatConsts
+ sun.misc.FormattedFloatingDecimal -> sun.misc.DoubleConsts
+
+# sun.misc.FpUtils
+@Inline
+ sun.misc.FpUtils -> sun.misc.FloatConsts
+ sun.misc.FpUtils -> sun.misc.DoubleConsts
+
+# public java.net.URLStreamHandler createURLStreamHandler(java.lang.String)
+@ClassForName(optional)
+ sun.misc.Launcher$Factory -> sun.net.www.protocol.*.Handler
+
+# private static sun.net.NetHooks$Provider loadProvider(java.lang.String)
+@ClassForName(optional)
+ sun.net.NetHooks -> sun.net.spi.SdpProvider
+
+# sun.net.idn.StringPrep
+@Inline
+ sun.net.idn.StringPrep -> sun.net.idn.UCharacterDirection
+
+# private static boolean init()
+@NativeFindClass
+ sun.net.spi.DefaultProxySelector -> java.net.Proxy
+ sun.net.spi.DefaultProxySelector -> java.net.Proxy$Type
+ sun.net.spi.DefaultProxySelector -> java.net.InetSocketAddress
+
+# private static java.nio.channels.Channel createChannel()
+@ClassForName
+ sun.nio.ch.InheritedChannel -> java.io.FileDescriptor
+
+# private static void initDBBConstructor()
+@ClassForName
+ sun.nio.ch.Util -> java.nio.DirectByteBuffer
+
+# private static void initDBBRConstructor()
+@ClassForName
+ sun.nio.ch.Util -> java.nio.DirectByteBufferR
+
+# private java.nio.charset.Charset lookup(java.lang.String)
+@ClassForName(optional)
+ sun.nio.cs.FastCharsetProvider -> sun.nio.cs.*
+
+# sun.nio.cs.ext.ExtendedCharsets
+@ClassForName(optional)
+ sun.nio.cs.ext.ExtendedCharsets -> sun.nio.cs.ext.*
+
+# sun.nio.cs.ext.ExtendedCharsets
+@ClassForName(optional)
+ sun.nio.cs.ext.ExtendedCharsets -> sun.nio.cs.ext.*
+
+# public static java.nio.file.spi.FileSystemProvider create()
+@ClassForName
+ sun.nio.fs.DefaultFileSystemProvider -> sun.nio.fs.SolarisFileSystemProvider
+ sun.nio.fs.DefaultFileSystemProvider -> sun.nio.fs.LinuxFileSystemProvider
+
+# sun.rmi.server.MarshalInputStream
+@ClassForName
+ sun.rmi.server.MarshalInputStream -> sun.rmi.server.Activation$ActivationSystemImpl_Stub
+ sun.rmi.server.MarshalInputStream -> sun.rmi.registry.RegistryImpl_Stub
+
+# private java.security.Provider doLoadProvider()
+@ClassForName(optional)
+ sun.security.jca.ProviderConfig -> sun.security.pkcs11.SunPKCS11
+ sun.security.jca.ProviderConfig -> sun.security.provider.Sun
+ sun.security.jca.ProviderConfig -> sun.security.rsa.SunRsaSign
+ sun.security.jca.ProviderConfig -> sun.security.ec.SunEC
+ sun.security.jca.ProviderConfig -> com.sun.net.ssl.internal.ssl.Provider
+ sun.security.jca.ProviderConfig -> com.sun.crypto.provider.SunJCE
+ sun.security.jca.ProviderConfig -> sun.security.jgss.SunProvider
+ sun.security.jca.ProviderConfig -> com.sun.security.sasl.Provider
+ sun.security.jca.ProviderConfig -> org.jcp.xml.dsig.internal.dom.XMLDSigRI
+ sun.security.jca.ProviderConfig -> sun.security.smartcardio.SunPCSC
+ sun.security.jca.ProviderConfig -> sun.security.mscapi.SunMSCAPI
+
+# public static java.security.Provider getSunProvider()
+@ClassForName
+ sun.security.jca.Providers -> sun.security.provider.Sun
+ sun.security.jca.Providers -> sun.security.provider.VerificationProvider
+
+# private static sun.security.jgss.spi.MechanismFactory getMechFactoryImpl(java.security.Provider, java.lang.String, org.ietf.jgss.Oid, sun.security.jgss.GSSCaller)
+@ClassForName
+ sun.security.jgss.ProviderList -> sun.security.jgss.spi.MechanismFactory
+
+# sun.security.jgss.wrapper.SunNativeProvider
+@NativeFindClass
+ sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.Oid
+ sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.GSSException
+ sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.GSSNameElement
+ sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.GSSCredElement
+ sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.NativeGSSContext
+ sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.SunNativeProvider
+ sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.MessageProp
+ sun.security.jgss.wrapper.SunNativeProvider -> org.ietf.jgss.ChannelBinding
+ sun.security.jgss.wrapper.SunNativeProvider -> java.net.InetAddress
+ sun.security.jgss.wrapper.SunNativeProvider -> sun.security.jgss.wrapper.GSSLibStub
+
+# static void ensureLoaded()
+@NativeFindClass
+ sun.security.krb5.Credentials -> sun.security.krb5.internal.Krb5
+ sun.security.krb5.Credentials -> sun.security.krb5.internal.Ticket
+ sun.security.krb5.Credentials -> sun.security.krb5.PrincipalName
+ sun.security.krb5.Credentials -> sun.security.util.DerValue
+ sun.security.krb5.Credentials -> sun.security.krb5.EncryptionKey
+ sun.security.krb5.Credentials -> sun.security.krb5.internal.TicketFlags
+ sun.security.krb5.Credentials -> sun.security.krb5.internal.KerberosTime
+
+# public static java.lang.String getDefaultCacheName()
+@ClassForName(optional)
+ sun.security.krb5.internal.ccache.FileCredentialsCache -> com.sun.security.auth.module.UnixSystem
+
+# sun.security.pkcs.PKCS9Attribute
+@ClassForName
+ sun.security.pkcs.PKCS9Attribute -> sun.security.util.ObjectIdentifier
+ sun.security.pkcs.PKCS9Attribute -> java.util.Date
+ sun.security.pkcs.PKCS9Attribute -> sun.security.pkcs.SignerInfo
+ sun.security.pkcs.PKCS9Attribute -> sun.security.x509.CertificateExtensions
+
+# protected T engineGetKeySpec(java.security.Key, java.lang.Class<T>)
+@ClassForName
+ sun.security.provider.DSAKeyFactory -> java.security.spec.DSAPublicKeySpec
+ sun.security.provider.DSAKeyFactory -> java.security.spec.X509EncodedKeySpec
+ sun.security.provider.DSAKeyFactory -> java.security.spec.DSAPrivateKeySpec
+ sun.security.provider.DSAKeyFactory -> java.security.spec.PKCS8EncodedKeySpec
+
+# protected T engineGetParameterSpec(java.lang.Class<T>)
+@ClassForName
+ sun.security.provider.DSAParameters -> java.security.spec.DSAParameterSpec
+
+# sun.security.provider.VerificationProvider
+@ClassForName(optional)
+ sun.security.provider.VerificationProvider -> sun.security.provider.Sun
+ sun.security.provider.VerificationProvider -> sun.security.rsa.SunRsaSign
+
+# sun.security.provider.certpath.URICertStore$LDAP
+@ClassForName(optional)
+ sun.security.provider.certpath.URICertStore$LDAP -> sun.security.provider.certpath.ldap.LDAPCertStoreHelper
+
+# sun.security.smartcardio.PCSC
+@NativeFindClass
+ sun.security.smartcardio.PCSC -> sun.security.smartcardio.PCSCException
+
+# sun.security.ssl.HandshakeMessage
+@ClassForName
+ sun.security.ssl.HandshakeMessage -> java.security.MessageDigest$Delegate
+
+# sun.security.ssl.JsseJce
+@ClassForName(optional)
+ sun.security.ssl.JsseJce -> sun.security.krb5.PrincipalName
+
+# sun.security.x509.OIDMap$OIDInfo
+@ClassForName
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.SubjectKeyIdentifierExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.KeyUsageExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.PrivateKeyUsageExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.SubjectAlternativeNameExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.IssuerAlternativeNameExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.BasicConstraintsExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CRLNumberExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CRLReasonCodeExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.NameConstraintsExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.PolicyMappingsExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.AuthorityKeyIdentifierExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.PolicyConstraintsExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.NetscapeCertTypeExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CertificatePoliciesExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.ExtendedKeyUsageExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.InhibitAnyPolicyExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CRLDistributionPointsExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.CertificateIssuerExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.SubjectInfoAccessExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.AuthorityInfoAccessExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.IssuingDistributionPointExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.DeltaCRLIndicatorExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.FreshestCRLExtension
+ sun.security.x509.OIDMap$OIDInfo -> sun.security.x509.OCSPNoCheckExtension
+
+# sun.util.LocaleServiceProviderPool$AllAvailableLocales
+@Provider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.BreakIteratorProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.CollatorProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.DateFormatProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.DateFormatSymbolsProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.DecimalFormatSymbolsProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.text.spi.NumberFormatProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.util.spi.CurrencyNameProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.util.spi.LocaleNameProvider
+ sun.util.LocaleServiceProviderPool$AllAvailableLocales -> META-INF/services/java.util.spi.TimeZoneNameProvider
+
+# private static final java.lang.String[] retrieveDisplayNames(sun.util.resources.OpenListResourceBundle, java.lang.String, java.util.Locale)
+@Provider
+ sun.util.TimeZoneNameUtility -> META-INF/services/java.util.spi.TimeZoneNamePProvider
+
+# public static sun.util.calendar.CalendarSystem forName(java.lang.String)
+@ClassForName
+ sun.util.calendar.CalendarSystem -> sun.util.calendar.Gregorian
+ sun.util.calendar.CalendarSystem -> sun.util.calendar.LocalGregorianCalendar
+ sun.util.calendar.CalendarSystem -> sun.util.calendar.JulianCalendar
+
+# sun.util.logging.LoggingSupport
+@ClassForName(optional)
+ sun.util.logging.LoggingSupport -> java.util.logging.LoggingProxyImpl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/modules.config Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,858 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+// These classes are not referenced in the JDK but we can't
+// remove them for compatibility reason. Define this module
+// first so that other modules don't need to exclude these clases
+module private-legacy {
+ include sun.misc.Cache*,
+ sun.misc.ClassLoaderUtil,
+ sun.misc.Compare,
+ sun.misc.ConditionLock,
+ sun.misc.CRC16,
+ sun.misc.Lock,
+ sun.misc.Regexp,
+ sun.misc.RequestProcessor,
+ sun.misc.Sort,
+ sun.misc.Request,
+ sun.misc.Timeable,
+ sun.misc.Timer,
+ sun.misc.TimerThread,
+ sun.misc.TimerTickThread,
+ sun.misc.UCDecoder,
+ sun.misc.UCEncoder,
+ sun.misc.UUDecoder,
+ sun.misc.UUEncoder,
+ com.sun.net.ssl.SSLContext,
+ sun.net.NetworkServer,
+ sun.net.URLCanonicalizer,
+ sun.reflect.misc.ConstructorUtil,
+ sun.reflect.FieldInfo,
+ sun.reflect.SignatureIterator,
+ sun.reflect.generics.reflectiveObjects.NotImplementedException,
+ sunw.io.Serializable,
+ sunw.util.EventListener,
+ sunw.util.EventObject;
+}
+
+// Deprecated classes that aren't referenced/used go here.
+module deprecated {
+ // add deprecated security classes once b78 is promoted
+}
+
+/**************************************************************************/
+
+module base {
+ // core classes
+ include java.lang.*,
+ java.lang.annotation.*,
+ java.lang.ref.*,
+ java.lang.reflect.*,
+ java.math.*,
+ java.net.*,
+ java.util.*,
+ java.util.concurrent.**,
+ java.util.jar.*,
+ java.util.regex.*,
+ java.util.spi.*,
+ java.util.zip.*,
+ java.text.**;
+
+ exclude java.util.jar.Pack200*,
+ java.util.XMLUtils,
+ java.text.Bidi;
+
+ include java.io.*, java.nio.*, java.nio.charset.**;
+ exclude java.io.TempFileHelper, java.nio.BufferPoolMXBean;
+
+ // security APIs
+ // javax.crypto and javax.security.auth are included to avoid inconsistent
+ // spliting of JCA and JAAS. This adds about 85k. Also note that some deprecated
+ // classes must be included for now (see 6876158, 6876170)
+ include java.security.*,
+ java.security.cert.*,
+ java.security.interfaces.*,
+ java.security.spec.*,
+ javax.security.auth.**,
+ javax.crypto.**;
+
+ // Sun and RSA security providers (except LDAP CertStore)
+ // roots sun.security.provider.* sun.security.provider.certpath.* sun.security.rsa.*
+ include com.sun.security.auth.PrincipalComparator,
+ com.sun.security.auth.SubjectCodeSource,
+ com.sun.security.auth.login.**,
+ com.sun.security.auth.Policy*,
+ sun.security.action.*,
+ sun.security.ec.*,
+ sun.security.jca.*,
+ sun.security.pkcs.*,
+ sun.security.provider.*,
+ sun.security.provider.certpath.*,
+ sun.security.rsa.*,
+ sun.security.util.*,
+ sun.security.validator.*,
+ sun.security.x509.*,
+ sun.security.timestamp.*;
+
+ // this list is based on the classlist generated from the rootset
+ // need investigation
+ exclude sun.security.ec.ECD*,
+ sun.security.ec.ECKeyPairGenerator,
+ sun.security.ec.SunEC*,
+ sun.security.pkcs.PKCS10*,
+ sun.security.pkcs.EncodingException,
+ sun.security.util.AuthResources_*,
+ sun.security.util.Resources_*,
+ sun.security.util.BigInt,
+ sun.security.util.HostnameChecker,
+ sun.security.x509.CertAndKeyGen,
+ sun.security.util.PathList;
+
+ // Kerberos not needed
+ exclude javax.security.auth.kerberos.**,
+ sun.security.jgss.**,
+ sun.security.krb5.**,
+ sun.security.ssl.Kerberos*,
+ org.ietf.jgss.**;
+
+ // property events and annotations
+ include java.beans.ChangeListenerMap,
+ java.beans.IndexedPropertyChangeEvent,
+ java.beans.PropertyChange*,
+ java.beans.PropertyVetoException,
+ java.beans.VetoableChange*,
+ java.beans.ConstructorProperties;
+
+ // mandatory charsets
+ include sun.nio.cs.*;
+
+ exclude sun.nio.cs.AbstractCharsetProvider,
+ sun.nio.cs.CharsetMapping,
+ sun.nio.cs.IBM*,
+ sun.nio.cs.ISO*,
+ sun.nio.cs.KOI8_*,
+ sun.nio.cs.MS125*,
+ sun.nio.cs.UTF_32*,
+ sun.nio.cs.SingleByteDecoder,
+ sun.nio.cs.SingleByteEncoder;
+
+ allow sun.nio.cs.ISO_8859_1,
+ sun.nio.cs.ISO_8859_15,
+ sun.nio.cs.MS1252;
+
+ include sun.text.*,
+ sun.text.normalizer.*;
+
+ // resource files
+ include sun/text/resources/*.icu;
+
+ exclude sun.text.bidi.*,
+ sun.text.CharArrayCodePointIterator,
+ sun.text.CharSequenceCodePointIterator,
+ sun.text.CharacterIteratorCodePointIterator,
+ sun.text.CodePointIterator;
+
+ include sun.util.*,
+ sun.util.calendar.*,
+ sun.util.logging.*,
+ sun.util.resources.LocaleData,
+ sun.util.resources.LocaleNamesBundle,
+ sun.util.resources.OpenListResourceBundle;
+
+ // US_en locale
+ include sun.text.resources.BreakIteratorInfo,
+ sun.text.resources.FormatData,
+ sun.text.resources.FormatData_en_US,
+ sun.util.resources.CalendarData,
+ sun.util.resources.CalendarData_en,
+ sun.util.resources.TimeZoneNames,
+ sun.util.resources.TimeZoneNames_en,
+ sun.util.resources.TimeZoneNamesBundle,
+ sun.util.resources.LocaleNames,
+ sun.util.resources.LocaleNames_en,
+ sun.util.resources.LocalenamesBundles,
+ sun.util.resources.CurrencyNames,
+ sun.util.resources.CurrencyNames_en_US,
+ sun.util.EmptyListResourceBundle;
+
+ // resources file needed by
+ // - sun.misc.ExtensionInfo
+ // - sun.security.provider.PolicyFile
+ // - com.sun.security.auth.PolicyFile
+ include sun.misc.resources.Messages,
+ sun.security.util.Resources,
+ sun.security.util.AuthResources;
+
+ // java.nio.channels and java.nio.file not in base
+ include sun.nio.ch.Interruptible,
+ sun.nio.ch.DirectBuffer,
+ sun.nio.ByteBuffered;
+
+ include sun.reflect.**;
+
+ // protocol handlers
+ include sun.net.www.protocol.file.*,
+ sun.net.www.protocol.jar.*,
+ sun.net.www.protocol.http.*;
+
+ include sun.net.*,
+ sun.net.spi.*,
+ sun.net.idn.*,
+ sun.net.util.*,
+ sun.net.www.*,
+ sun.net.www.http.*,
+ sun.net.spi.nameservice.*;
+
+ // resource file for sun.net.idn
+ include sun/net/idn/*;
+
+ // classes in net-compat
+ exclude sun.net.Telnet*, sun.net.TransferProtocolClient;
+
+ // classes in deploy
+ exclude sun.net.www.protocol.http.AuthCacheBridge;
+
+ // classes in security-jsse
+ exclude java.net.SecureCacheResponse;
+
+ // launcher
+ include sun.launcher.LauncherHelper, sun.launcher.resources.launcher;
+
+ include sun.misc.*;
+ exclude sun.misc.FIFOQueueEnumerator,
+ sun.misc.LIFOQueueEnumerator,
+ sun.misc.GC,
+ sun.misc.PerformanceLogger,
+ sun.misc.Queue,
+ sun.misc.QueueElement,
+ sun.misc.Ref,
+ sun.misc.VMSupport;
+
+ // On Windows, OSEnvironment dependency
+ include sun.io.Win32ErrorMode;
+}
+
+/**************************************************************************/
+
+module charsets {
+ include sun.nio.cs.ext.**;
+
+ include sun.nio.cs.AbstractCharsetProvider,
+ sun.nio.cs.CharsetMapping,
+ sun.nio.cs.IBM*,
+ sun.nio.cs.ISO*,
+ sun.nio.cs.KOI8_*,
+ sun.nio.cs.MS125*,
+ sun.nio.cs.SingleByte*,
+ sun.nio.cs.UTF_32*;
+
+ exclude sun.nio.cs.ISO_8859_1,
+ sun.nio.cs.MS1252;
+
+ // legacy sun.io converters
+ include sun.io.*;
+}
+
+/**************************************************************************/
+
+// For now, retains the current JRE extensions where localedata.jar in jre/lib/ext
+module localedata {
+ include sun.util.resources.*_ar,
+ sun.util.resources.*_ar_*,
+ sun.util.resources.*_hi,
+ sun.util.resources.*_hi_*,
+ sun.util.resources.*_iw,
+ sun.util.resources.*_iw_*,
+ sun.util.resources.*_ja,
+ sun.util.resources.*_ja_*,
+ sun.util.resources.*_ko,
+ sun.util.resources.*_ko_*,
+ sun.util.resources.*_th,
+ sun.util.resources.*_th_*,
+ sun.util.resources.*_vi,
+ sun.util.resources.*_vi_*,
+ sun.util.resources.*_zh,
+ sun.util.resources.*_zh_*;
+ include sun.text.resources.*_ar,
+ sun.text.resources.*_ar_*,
+ sun.text.resources.*_hi,
+ sun.text.resources.*_hi_*,
+ sun.text.resources.*_iw,
+ sun.text.resources.*_iw_*,
+ sun.text.resources.*_ja,
+ sun.text.resources.*_ja_*,
+ sun.text.resources.*_ko,
+ sun.text.resources.*_ko_*,
+ sun.text.resources.*_th,
+ sun.text.resources.*_th_*,
+ sun.text.resources.*_vi,
+ sun.text.resources.*_vi_*,
+ sun.text.resources.*_zh,
+ sun.text.resources.*_zh_*;
+}
+
+module resources {
+ include sun.text.resources.*, sun.util.resources.*, sun.misc.resources.*;
+}
+
+/**************************************************************************/
+
+module nio {
+ include java.nio.channels.**, java.nio.file.**, com.sun.nio.file.**;
+
+ // this is excluded from base
+ include java.io.TempFileHelper;
+
+ // provider implementations and their dependencies
+ include sun.nio.ch.*, sun.nio.fs.**;
+ exclude sun.nio.ch.Sctp*;
+}
+
+/**************************************************************************/
+
+module pack200 {
+ include java.util.jar.Pack200*, com.sun.java.util.jar.pack.**;
+}
+
+/**************************************************************************/
+
+module logging {
+ include java.util.logging.*, sun.util.logging.**;
+ exclude java.util.logging.PlatformLoggingMXBean;
+
+ // Formatter for HTTP messages
+ include sun.net.www.protocol.http.logging.*;
+}
+
+/**************************************************************************/
+
+module management-snmp {
+ include com.sun.jmx.snmp.**, sun.management.snmp.**;
+}
+
+module management-iiop {
+ include com.sun.jmx.remote.protocol.iiop.*;
+
+ // stubs and ties
+ include javax.management.remote.rmi._*,
+ org.omg.stub.javax.management.remote.rmi.**;
+}
+
+module management {
+ include java.lang.management.*, com.sun.management.**, sun.management.**;
+ include javax.management.**, com.sun.jmx.**;
+
+ // other management interfaces
+ include java.nio.BufferPoolMXBean;
+ include java.util.logging.PlatformLoggingMXBean;
+
+ // supporting classes in sun.misc
+ include sun.misc.VMSupport;
+}
+
+/**************************************************************************/
+
+module instrument {
+ // java.lang.instrument
+ include java.lang.instrument.*, sun.instrument.*;
+
+ // tracing
+ include com.sun.tracing.**, sun.tracing.**;
+
+ // HPROF support
+ include com.sun.demo.jvmti.hprof.*;
+}
+
+/**************************************************************************/
+
+module rmi-activation {
+ include java.rmi.activation.**,
+ sun.rmi.server.Act*,
+ sun.rmi.server.InactiveGroupException;
+}
+
+module rmi {
+ include java.rmi.**, sun.rmi.**, com.sun.rmi.**;
+
+ // SSL factories are in rmi
+ include javax.rmi.ssl.**;
+
+ // rmic is in tools
+ exclude sun.rmi.rmic.**;
+
+ // supporting classes in sun.misc and dependencies
+ include sun.misc.GC;
+}
+
+/**************************************************************************/
+
+module prefs {
+ include java.util.prefs.*;
+}
+
+/**************************************************************************/
+
+module security-jsse {
+ include javax.net.**,
+ javax.security.cert.*,
+ java.net.SecureCacheResponse,
+ com.sun.net.ssl.**,
+ com.sun.security.cert.internal.x509.*,
+ sun.security.ssl.*,
+ sun.net.www.protocol.https.**,
+ sun.security.internal.interfaces.Tls*,
+ sun.security.internal.spec.Tls*,
+ sun.security.util.HostnameChecker;
+}
+
+module security-sunpkcs11 {
+ include sun.security.pkcs11.**;
+}
+
+module security-sunjce {
+ include com.sun.crypto.provider.*;
+}
+
+module security-sunec {
+ include sun.security.ec.*;
+}
+
+module security-sunmscapi {
+ include sun.security.mscapi.*;
+}
+
+module security-kerberos {
+ include javax.security.auth.kerberos.*,
+ com.sun.security.jgss.**,
+ com.sun.security.auth.module.Krb5LoginModule,
+ com.sun.security.sasl.gsskerb.**, // GSSAPI SASL mechanism
+ sun.security.jgss.**,
+ sun.security.ssl.krb5.**,
+ sun.security.krb5.**,
+ org.ietf.jgss.**,
+ sun.net.www.protocol.http.spnego.*;
+}
+
+module security-sasl {
+ include javax.security.sasl.**,
+ com.sun.security.sasl.**;
+}
+
+module security-xmldsig {
+ include javax.xml.crypto.**,
+ org.jcp.xml.dsig.**,
+ com.sun.org.apache.xml.internal.security.**;
+}
+
+module security-smartcardio {
+ include javax.smartcardio.**, sun.security.smartcardio.**;
+}
+
+module security-misc {
+ include com.sun.security.auth.**, sun.security.util.AuthResources_*,
+ sun.security.pkcs.*,
+ sun.security.pkcs12.*;
+
+ // this class is a candidate to be removed.
+ include sun.security.util.BigInt;
+}
+
+module security-resources {
+ include sun.security.util.Resources_*;
+}
+
+module security-compat {
+ include java.security.acl.*, sun.security.acl.*;
+}
+
+/**************************************************************************/
+
+module jndi-ldap {
+ include javax.naming.ldap.**,
+ com.sun.jndi.ldap.**,
+ com.sun.jndi.url.ldap.*,
+ com.sun.jndi.url.ldaps.*,
+ sun.security.provider.certpath.ldap.**;
+}
+
+module jndi-rmiregistry {
+ include com.sun.jndi.rmi.**, com.sun.jndi.url.rmi.**;
+}
+
+module jndi-dns {
+ include com.sun.jndi.dns.**, com.sun.jndi.url.dns.**;
+ include sun.net.dns.**; // to access DNS config.
+ include sun.net.spi.nameservice.dns.**; // for DNS-only name service.
+}
+
+module jndi-cosnaming {
+ include com.sun.jndi.cosnaming.**,
+ com.sun.jndi.toolkit.corba.**,
+ com.sun.jndi.url.corbaname.**,
+ com.sun.jndi.url.iiop.**,
+ com.sun.jndi.url.iiopname.**;
+}
+
+// framework/API and classes used by providers
+module jndi {
+ include javax.naming.**,
+ com.sun.naming.**,
+ com.sun.jndi.toolkit.ctx.**,
+ com.sun.jndi.toolkit.dir.**,
+ com.sun.jndi.toolkit.url.**;
+}
+
+/**************************************************************************/
+
+module jdbc-base {
+ include java.sql.**, javax.sql.*;
+ exclude javax.sql.XA*;
+}
+
+module jdbc-enterprise {
+ include javax.sql.**, com.sun.rowset.**;
+}
+
+module jdbc-odbc {
+ include sun.jdbc.odbc.**;
+}
+
+/**************************************************************************/
+
+module scripting {
+ include javax.script.**;
+
+ // supporting classes for scripting engines
+ include com.sun.script.util.**;
+}
+
+module scripting-rhino {
+ include com.sun.script.javascript.**, sun.org.mozilla.javascript.**;
+}
+
+/**************************************************************************/
+
+module httpserver {
+ include com.sun.net.httpserver.**, sun.net.httpserver.**;
+}
+
+/**************************************************************************/
+
+module sctp {
+ // API and dependencies
+ include com.sun.nio.sctp.**, sun.nio.ch.Sctp*;
+}
+
+/**************************************************************************/
+
+module langtools {
+ include javax.tools.**, javax.lang.model.**, javax.annotation.processing.**;
+
+ // include mirror API for now
+ include com.sun.mirror.**;
+
+ // include the JSR292 APIs for now
+ include java.dyn.**, sun.dyn.**;
+}
+
+/**************************************************************************/
+
+module beans {
+ include java.beans.**, com.sun.beans.**, sun.beans.**;
+}
+
+/**************************************************************************/
+
+module jaxp-parsers-api {
+ include javax.xml.*, javax.xml.parsers.**,
+ org.w3c.dom.**, org.w3c.sax.**, org.xml.sax.**;
+}
+
+module jaxp-api {
+ include javax.xml.**;
+ exclude javax.xml.crypto.**, // XML-DSIG
+ javax.xml.bind.**, // JAX-WS
+ javax.xml.soap.**,
+ javax.xml.ws.**;
+}
+
+module jaxp-xerces-impl {
+ include com.sun.org.apache.xerces.internal.**;
+
+ // include in xerces-impl due to circular dependencies
+ include com.sun.org.apache.xml.internal.serialize.**,
+ com.sun.xml.internal.stream.**;
+ exclude com.sun.xml.internal.stream.buffer.**; // JAX-WS
+}
+
+// required by Xerces and JAX-WS
+module jaxp-xerces-resolver {
+ include com.sun.org.apache.xml.internal.resolver.**;
+}
+
+module jaxp-xalan {
+ include com.sun.org.apache.xalan.internal.**,
+ com.sun.org.apache.xpath.internal.**,
+ com.sun.org.apache.xml.internal.dtm.**,
+ com.sun.org.apache.xml.internal.res.**,
+ com.sun.org.apache.xml.internal.serializer.**,
+ com.sun.org.apache.xml.internal.utils.**,
+ com.sun.org.apache.bcel.internal.**,
+ com.sun.org.apache.regexp.internal.**,
+ com.sun.java_cup.internal.**;
+}
+
+/**************************************************************************/
+
+module jaxws-tools {
+ include com.sun.codemodel.**,
+ com.sun.xml.internal.dtdparser.**,
+ com.sun.xml.internal.rngom.**,
+ com.sun.xml.internal.xsom.**,
+ com.sun.istack.internal.tools.**,
+ com.sun.istack.internal.ws.**,
+ com.sun.tools.internal.xjc.**,
+ com.sun.tools.internal.ws.**,
+ com.sun.tools.internal.jxc.**,
+ org.relaxng.datatype.**;
+}
+
+module jaxws {
+ include javax.jws.**,
+ javax.xml.bind.**,
+ javax.xml.soap.**,
+ javax.xml.ws.**,
+ org.relaxng.**,
+ com.sun.istack.internal.*,
+ com.sun.istack.internal.localization.*,
+ com.sun.xml.internal.**;
+
+ // include JAF in this module
+ include javax.activation.**, com.sun.activation.**;
+
+ include META-INF/mailcap.default,
+ META-INF/mimetypes.default;
+}
+
+/**************************************************************************/
+module enterprise-base {
+ include javax.transaction.**, // JTA
+ javax.annotation.*; // Common annotations (JSR-250)
+}
+
+/**************************************************************************/
+module corba {
+ include javax.activity.**,
+ javax.rmi.*,
+ javax.rmi.CORBA.*,
+ javax.transaction.**,
+ com.sun.corba.**,
+ com.sun.org.omg.**,
+ org.omg.**,
+ sun.corba.**;
+
+ // JMX remote API
+ exclude org.omg.stub.javax.management.**;
+}
+
+/**************************************************************************/
+
+module client {
+ include java.applet.**,
+ java.awt.**,
+ javax.accessibility.*,
+ javax.imageio.**,
+ javax.print.**,
+ javax.sound.**,
+ javax.swing.**,
+ sun.applet.**,
+ sun.audio.**,
+ sun.awt.**,
+ sun.dc.**,
+ sun.font.**,
+ sun.java2d.**,
+ sun.print.**,
+ sun.swing.**,
+ com.sun.accessibility.**,
+ com.sun.awt.**,
+ com.sun.image.**,
+ com.sun.imageio.**,
+ com.sun.java.swing.*, // sajdi also contains classes in a subpackage;
+ // so use '*' instead of '**'
+ com.sun.java.swing.plaf.**,
+ com.sun.media.**,
+ com.sun.swing.**;
+
+ // Bidi class in client module for now
+ include java.text.Bidi, sun.text.bidi.*;
+
+ // PerformanceLogger and dependencies
+ include sun.misc.Ref, sun.misc.PerformanceLogger;
+
+ // misc. dependencies that we need to examine
+ include sun.text.CodePointIterator,
+ sun.text.Char*,
+ sun.misc.Queue*,
+ sun.misc.FIFOQueueEnumerator,
+ sun.misc.LIFOQueueEnumerator;
+
+ // content handlers
+ include sun.net.www.content.audio.**,
+ sun.net.www.content.image.**;
+}
+
+/**************************************************************************/
+
+module deploy {
+ // For now, all plugin and JNLP
+ include com.sun.java.browser.**,
+ netscape.**,
+ sun.plugin.**,
+ sun.plugin2.**,,
+ com.sun.deploy.**,
+ com.sun.javaws.**,
+ javax.jnlp.*,
+ com.sun.jnlp.*,
+ sun.jkernel.*;
+
+ // Hook for http authentication
+ include sun.net.www.protocol.http.AuthCacheBridge;
+}
+
+/**************************************************************************/
+
+module net-compat {
+ // NTLM authentication support
+ include sun.net.www.protocol.http.ntlm.*;
+
+ // ftp and mail clients
+ include sun.net.ftp.**, sun.net.smtp.**;
+
+ // Legacy protocol handlers
+ include sun.net.www.protocol.**;
+
+ // Legacy content handlers
+ include sun.net.www.content.**;
+
+ include sun.net.Telnet*,
+ sun.net.TransferProtocolClient;
+}
+
+/**************************************************************************/
+
+// jar-tool and security-tools are JRE tools
+module jar-tool {
+ include sun.tools.jar.**;
+}
+
+module security-tools {
+ include sun.security.tools.**;
+
+ // Used by security tools
+ include sun.security.util.PathList, sun.security.x509.CertAndKeyGen;
+
+ exclude sun.security.tools.JarBASE64Encoder,
+ sun.security.tools.JarSigner,
+ sun.security.tools.JarSignerParameters,
+ sun.security.tools.JarSignerResources*,
+ sun.security.tools.SignatureFile,
+ sun.security.tools.TimestampedSigner;
+}
+
+module jconsole {
+ include sun.tools.jconsole.**,
+ com.sun.tools.jconsole.*;
+}
+
+module serialver {
+ include sun.tools.serialver.**;
+}
+
+module gui-tools {
+ include jconsole,
+ serialver;
+
+ include com.sun.tools.example.debug.bdi.**,
+ com.sun.tools.example.debug.gui.**,
+ com.sun.tools.internal.xjc.**;
+}
+
+module attach {
+ include com.sun.tools.attach.**,
+ sun.tools.attach.**;
+}
+
+module debugging {
+ include com.sun.jdi.**, com.sun.tools.jdi.**;
+}
+
+module jdb {
+ include com.sun.tools.example.debug.**;
+}
+
+module sajdi {
+ include sun.jvm.hotspot.**,
+ com.sun.java.swing.ui.**,
+ com.sun.java.swing.action.**;
+
+ include toolbarButtonGraphics/**;
+ include sa.properties;
+}
+
+module tools {
+ include attach,
+ debugging,
+ jaxws-tools,
+ jdb,
+ sajdi;
+
+ // include gui-tools in tools module unless the tool binaries
+ // are modified to load the new gui-tools.jar
+ include gui-tools;
+
+ include com.sun.tools.**, sun.tools.**, sun.security.tools.**,
+ com.sun.jarsigner.**,
+ com.sun.javac.**,
+ com.sun.javadoc.**, com.sun.source.**,
+ sun.jvmstat.**,
+ sun.rmi.rmic.**;
+}
+
+/**************************************************************************/
+
+module servicetag {
+ include com.sun.servicetag.**;
+}
+
+/**************************************************************************/
+
+// these classes will be removed from JRE - see 6909002
+module inputmethods-ext {
+ include com.sun.inputmethods.internal.**;
+}
+
+/**************************************************************************/
+
+module other {
+ include **;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/modules.group Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * Example:
+ * module jdbc {
+ * include jdbc-base, jdbc-enterprise, jdbc-odbc;
+ * }
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/optional.depconfig Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,124 @@
+# public final java.nio.channels.SocketChannel getChannel()
+@Optional
+ sun.security.ssl.BaseSSLSocketImpl -> java.nio.channels.SocketChannel
+
+# public XMLDecoder(java.io.InputStream)
+# public XMLDecoder(java.io.InputStream, java.lang.Object)
+# public XMLDecoder(java.io.InputStream, java.lang.Object, java.beans.ExceptionListener)
+# public XMLDecoder(java.io.InputStream, java.lang.Object, java.beans.ExceptionListener, java.lang.ClassLoader)
+# public XMLDecoder(org.xml.sax.InputSource)
+@Optional
+ java.beans.XMLDecoder -> com.sun.beans.decoder.DocumentHandler
+ java.beans.XMLDecoder -> org.xml.sax.InputSource
+
+# public static org.xml.sax.helpers.DefaultHandler createHandler(java.lang.Object, java.beans.ExceptionListener, java.lang.ClassLoader)
+@Optional
+ java.beans.XMLDecoder -> com.sun.beans.decoder.DocumentHandler
+ java.beans.XMLDecoder -> org.xml.sax.helpers.DefaultHandler
+
+# public final java.nio.channels.FileChannel getChannel()
+@Optional
+ java.net.SocketInputStream -> java.nio.channels.FileChannel
+
+# public final java.nio.channels.FileChannel getChannel()
+@Optional
+ java.net.SocketOutputStream -> java.nio.channels.FileChannel
+
+# public Scanner(java.io.File)
+# public Scanner(java.io.File, java.lang.String)
+@Optional
+ java.util.Scanner -> java.nio.channels.ReadableByteChannel
+ java.util.Scanner -> java.nio.channels.Channels
+
+# public Scanner(java.nio.file.FileRef)
+# public Scanner(java.nio.file.FileRef, java.lang.String)
+@Optional
+ java.util.Scanner -> java.nio.file.FileRef
+ java.util.Scanner -> java.nio.file.OpenOption
+
+# public Scanner(java.nio.channels.ReadableByteChannel)
+# public Scanner(java.nio.channels.ReadableByteChannel, java.lang.String)
+@Optional
+ java.util.Scanner -> java.nio.channels.ReadableByteChannel
+ java.util.Scanner -> java.nio.channels.Channels
+
+# private static void loadSnmpAgent(java.lang.String, java.util.Properties)
+@Optional
+ sun.management.Agent -> sun.management.snmp.AdaptorBootstrap
+
+# public void connect()
+@Optional
+ sun.net.www.protocol.http.HttpURLConnection -> java.net.SecureCacheResponse
+
+# private static sun.security.util.PermissionFactory<?> permissionFactory()
+@Optional
+ sun.security.util.SecurityConstants$AWT -> sun.awt.AWTPermissionFactory
+
+# sun.util.logging.LoggingSupport
+@Optional
+ sun.util.logging.LoggingSupport -> java.util.logging.LoggingProxyImpl
+
+# public java.nio.channels.DatagramChannel getChannel()
+@Optional
+ java.net.DatagramSocket -> java.nio.channels.DatagramChannel
+
+# public java.nio.channels.SocketChannel getChannel()
+@Optional
+ java.net.Socket -> java.nio.channels.SocketChannel
+
+# public java.nio.channels.ServerSocketChannel getChannel()
+@Optional
+ java.net.ServerSocket -> java.nio.channels.ServerSocketChannel
+
+# public final java.nio.channels.FileChannel getChannel()
+@Optional
+ java.io.RandomAccessFile -> java.nio.channels.FileChannel
+ java.io.RandomAccessFile -> sun.nio.ch.FileChannelImpl
+
+# public static sun.nio.cs.StreamDecoder forDecoder(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int)
+@Optional
+ sun.nio.cs.StreamDecoder -> java.nio.channels.ReadableByteChannel
+
+# private static java.nio.channels.FileChannel getChannel(java.io.FileInputStream)
+# StreamDecoder(java.io.InputStream, java.lang.Object, java.nio.charset.CharsetDecoder)
+@Optional
+ sun.nio.cs.StreamDecoder -> java.nio.channels.FileChannel
+
+# StreamDecoder(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int)
+@Optional
+ sun.nio.cs.StreamDecoder -> java.nio.channels.ReadableByteChannel
+
+# public static java.io.File createTemporaryFile(java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>[])
+@Optional
+ java.io.File -> java.io.TempFileHelper
+ java.io.File -> java.nio.file.attribute.FileAttribute
+
+# public java.nio.file.Path toPath()
+@Optional
+ java.io.File -> java.nio.file.Paths
+ java.io.File -> java.nio.file.Path
+
+# public static sun.nio.cs.StreamEncoder forEncoder(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int)
+# private StreamEncoder(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int)
+@Optional
+ sun.nio.cs.StreamEncoder -> java.nio.channels.WritableByteChannel
+
+# public java.nio.channels.FileChannel getChannel()
+@Optional
+ java.io.FileOutputStream -> java.nio.channels.FileChannel
+ java.io.FileOutputStream -> sun.nio.ch.FileChannelImpl
+
+# public java.nio.channels.FileChannel getChannel()
+@Optional
+ java.io.FileInputStream -> java.nio.channels.FileChannel
+ java.io.FileInputStream -> sun.nio.ch.FileChannelImpl
+
+# public void loadFromXML(java.io.InputStream)
+# public void storeToXML(java.io.OutputStream, java.lang.String, java.lang.String)
+@Optional
+ java.util.Properties -> java.util.XMLUtils
+
+# public static java.nio.channels.Channel inheritedChannel()
+@Optional
+ java.lang.System -> java.nio.channels.Channel
+ java.lang.System -> java.nio.channels.spi.SelectorProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/Makefile Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,85 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# Makefile for building the classanalyzer tool
+#
+
+BUILDDIR = ../..
+PACKAGE = com.sun.classanalyzer
+PRODUCT = tools
+PROGRAM = classanalyzer
+include $(BUILDDIR)/common/Defs.gmk
+
+BUILDTOOL_SOURCE_ROOT = src
+BUILDTOOL_MAIN = $(PKGDIR)/ClassAnalyzer.java
+BUILTTOOL_MAINCLASS = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
+
+BUILDTOOL_MAIN_SOURCE_FILE = $(BUILDTOOL_SOURCE_ROOT)/$(BUILDTOOL_MAIN)
+BUILDTOOL_MANIFEST_FILE = $(BUILDTOOLCLASSDIR)/$(PROGRAM)_manifest.mf
+BUILDTOOL_JAR_FILE = $(BUILDTOOLJARDIR)/$(PROGRAM).jar
+
+FILES_java := $(shell $(CD) $(BUILDTOOL_SOURCE_ROOT) \
+ && $(FIND) $(PKGDIR) $(SCM_DIRS_prune) -o -type f -print)
+FILES_class = $(FILES_java:%.java=$(BUILDTOOLCLASSDIR)/%.class)
+
+all build: $(BUILDTOOL_JAR_FILE) tool_info
+
+$(BUILDTOOL_MANIFEST_FILE): $(BUILDTOOL_MAIN_SOURCE_FILE)
+ @$(prep-target)
+ $(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@
+
+$(BUILDTOOLCLASSDIR)/%.class : $(BUILDTOOL_SOURCE_ROOT)/%.java
+ @$(prep-target)
+ $(JAVAC_CMD) \
+ -sourcepath $(BUILDTOOL_SOURCE_ROOT) \
+ -d $(BUILDTOOLCLASSDIR) $<
+
+$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) $(FILES_class)
+ @$(prep-target)
+ $(BOOT_JAR_CMD) cfm $@ $(BUILDTOOL_MANIFEST_FILE) \
+ -C $(BUILDTOOLCLASSDIR) $(PKGDIR) \
+ $(BOOT_JAR_JFLAGS) || $(RM) $@
+ $(java-vm-cleanup)
+
+# Printing out a build tool information line
+define printBuildToolSetting
+if [ "$2" != "" ] ; then $(PRINTF) "%-25s %s\n" "$1:" "$2"; fi
+endef
+
+# Print out the build tool information
+tool_info:
+ @$(ECHO) "========================================================="
+ @$(call printBuildToolSetting,BUILDTOOL,$(PROGRAM))
+ @$(call printBuildToolSetting,PACKAGE,$(PACKAGE))
+ @$(call printBuildToolSetting,BUILDTOOL_SOURCE_ROOT,$(BUILDTOOL_SOURCE_ROOT))
+ @$(call printBuildToolSetting,BUILTTOOL_MAINCLASS,$(BUILTTOOL_MAINCLASS))
+ @$(call printBuildToolSetting,BUILDTOOL_JAR_FILE,$(BUILDTOOL_JAR_FILE))
+ @$(ECHO) "========================================================="
+
+clean clobber::
+ @$(RM) -rf $(BUILDTOOLCLASSDIR)/$(PKGDIR)
+ @$(RM) $(BUILDTOOL_MANIFEST_FILE)
+ @$(RM) $(BUILDTOOL_JAR_FILE)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/build.xml Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,33 @@
+<!--
+ Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Sun Microsystems nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<project name="classanalyzer" default="build" basedir=".">
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/nbproject/project.properties Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,92 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# - Neither the name of Sun Microsystems nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+application.title=classanalyzer
+application.vendor=mchung
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+
+cp.extra=${tools.jar}
+
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/classanalyzer.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+
+excludes=
+
+file.reference.tools.jar=${jdk.home}/lib/tools.jar
+file.reference.tools-src=src
+includes=**
+jar.compress=false
+javac.classpath=\
+ ${file.reference.tools.jar}
+javac.deprecation=false
+javac.source=1.5
+javac.target=1.5
+javac.test.classpath=
+javadoc.author=false
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=false
+javadoc.use=false
+javadoc.version=false
+main.class=com.sun.classanalyzer.ClassAnalyzer
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+platform.active=JDK_1.6
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=-Xmx256m
+run.test.classpath=
+source.encoding=UTF-8
+src.dir=${file.reference.tools-src}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/nbproject/project.xml Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,45 @@
+<!--
+ Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Sun Microsystems nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.java.j2seproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+ <name>classanalyzer</name>
+ <explicit-platform explicit-source-supported="true"/>
+ <source-roots>
+ <root id="src.dir"/>
+ </source-roots>
+ <test-roots/>
+ </data>
+ </configuration>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotatedDependency.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,627 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Map;
+
+import com.sun.classanalyzer.Module.Reference;
+import java.util.LinkedList;
+import java.util.TreeMap;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public abstract class AnnotatedDependency implements Comparable<AnnotatedDependency> {
+
+ final Klass from;
+ final List<String> classes;
+ protected boolean optional;
+ String description;
+ Klass.Method method;
+ private List<Filter> filters = null;
+
+ public AnnotatedDependency(Klass klass) {
+ this(klass, false);
+ }
+
+ public AnnotatedDependency(Klass klass, boolean optional) {
+ this.from = klass;
+ this.classes = new ArrayList<String>();
+ this.optional = optional;
+ }
+
+ abstract String getTag();
+
+ abstract boolean isDynamic();
+
+ void setMethod(Klass.Method m) {
+ this.method = m;
+ }
+
+ void addElement(String element, List<String> value) {
+ if (element.equals("value")) {
+ addValue(value);
+ } else if (element.equals("description")) {
+ description = value.get(0);
+ } else if (element.equals("optional")) {
+ optional = value.get(0).equals("1") || Boolean.parseBoolean(value.get(0));
+ }
+ }
+
+ void addValue(List<String> value) {
+ for (String s : value) {
+ if ((s = s.trim()).length() > 0) {
+ classes.add(s);
+ }
+ }
+ }
+
+ List<String> getValue() {
+ return classes;
+ }
+
+ boolean isOptional() {
+ return optional;
+ }
+
+ boolean isEmpty() {
+ return classes.isEmpty();
+ }
+
+ boolean matches(String classname) {
+ synchronized (this) {
+ // initialize filters
+ if (filters == null) {
+ filters = new ArrayList<Filter>();
+ for (String pattern : classes) {
+ filters.add(new Filter(pattern));
+ }
+
+ }
+ }
+
+ for (Filter f : filters) {
+ if (f.matches(classname)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (String v : getValue()) {
+ if (sb.length() == 0) {
+ sb.append(getTag());
+ sb.append("\n");
+ } else {
+ sb.append("\n");
+ }
+ sb.append(" ");
+ sb.append(from.getClassName()).append(" -> ");
+ sb.append(v);
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public int compareTo(AnnotatedDependency o) {
+ if (from == o.from) {
+ if (this.getClass().getName().equals(o.getClass().getName())) {
+ String s1 = classes.isEmpty() ? "" : classes.get(0);
+ String s2 = o.classes.isEmpty() ? "" : o.classes.get(0);
+ return s1.compareTo(s2);
+ } else {
+ return this.getClass().getName().compareTo(o.getClass().getName());
+ }
+
+ } else {
+ return from.compareTo(o.from);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hashcode = 7 + 73 * from.hashCode();
+ for (String s : classes) {
+ hashcode ^= s.hashCode();
+ }
+ return hashcode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof AnnotatedDependency)) {
+ return false;
+ }
+ AnnotatedDependency other = (AnnotatedDependency) obj;
+ boolean ret = this.from.equals(other.from) && this.classes.size() == other.classes.size();
+ if (ret == true) {
+ for (int i = 0; i < this.classes.size(); i++) {
+ ret = ret && this.classes.get(i).equals(other.classes.get(i));
+ }
+ }
+ return ret;
+ }
+
+ static class ClassForName extends AnnotatedDependency {
+
+ public ClassForName(Klass klass, boolean optional) {
+ super(klass, optional);
+ }
+
+ @Override
+ String getTag() {
+ if (this.optional) {
+ return TAG + "(optional)";
+ } else {
+ return TAG;
+ }
+ }
+
+ @Override
+ boolean isDynamic() {
+ return true;
+ }
+ static final String TYPE = "sun.annotation.ClassForName";
+ static final String TAG = "@ClassForName";
+ }
+
+ static class NativeFindClass extends AnnotatedDependency {
+
+ public NativeFindClass(Klass klass, boolean optional) {
+ super(klass, optional);
+ }
+
+ @Override
+ String getTag() {
+ if (this.optional) {
+ return TAG + "(optional)";
+ } else {
+ return TAG;
+ }
+ }
+
+ @Override
+ boolean isDynamic() {
+ return true;
+ }
+ static final String TYPE = "sun.annotation.NativeFindClass";
+ static final String TAG = "@NativeFindClass";
+ }
+
+ static class Provider extends AnnotatedDependency {
+
+ private List<String> services = new ArrayList<String>();
+
+ Provider(Klass klass) {
+ super(klass, true);
+ }
+
+ @Override
+ boolean isDynamic() {
+ return true;
+ }
+
+ public List<String> services() {
+ return services;
+ }
+
+ @Override
+ void addElement(String element, List<String> value) {
+ if (element.equals("service")) {
+ List<String> configFiles = new ArrayList<String>();
+ for (String s : value) {
+ if ((s = s.trim()).length() > 0) {
+ configFiles.add(metaInfPath + s);
+ }
+ }
+ addValue(configFiles);
+ }
+ }
+
+ @Override
+ void addValue(List<String> value) {
+ for (String s : value) {
+ if ((s = s.trim()).length() > 0) {
+ if (s.startsWith("META-INF")) {
+ services.add(s);
+ readServiceConfiguration(s, classes);
+ } else {
+ throw new RuntimeException("invalid value" + s);
+ }
+ }
+ }
+ }
+
+ boolean isEmpty() {
+ return services.isEmpty();
+ }
+ static final String metaInfPath =
+ "META-INF" + File.separator + "services" + File.separator;
+
+ static void readServiceConfiguration(String config, List<String> names) {
+ BufferedReader br = null;
+ try {
+ InputStream is = ClassPath.open(config);
+ if (is != null) {
+ // Properties doesn't perserve the order of the input file
+ br = new BufferedReader(new InputStreamReader(is, "utf-8"));
+ int lc = 1;
+ while ((lc = parseLine(br, lc, names)) >= 0);
+ }
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+ }
+
+ // Parse a single line from the given configuration file, adding the name
+ // on the line to the names list.
+ //
+ private static int parseLine(BufferedReader r, int lc, List<String> names) throws IOException {
+ String ln = r.readLine();
+ if (ln == null) {
+ return -1;
+ }
+ int ci = ln.indexOf('#');
+ if (ci >= 0) {
+ ln = ln.substring(0, ci);
+ }
+ ln = ln.trim();
+ int n = ln.length();
+ if (n != 0) {
+ if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
+ throw new RuntimeException("Illegal configuration-file syntax");
+ }
+ int cp = ln.codePointAt(0);
+ if (!Character.isJavaIdentifierStart(cp)) {
+ throw new RuntimeException("Illegal provider-class name: " + ln);
+ }
+ for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+ cp = ln.codePointAt(i);
+ if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
+ throw new RuntimeException("Illegal provider-class name: " + ln);
+ }
+ }
+ if (!names.contains(ln)) {
+ names.add(ln);
+ }
+ }
+ return lc + 1;
+ }
+
+ @Override
+ String getTag() {
+ return TAG;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof AnnotatedDependency)) {
+ return false;
+ }
+ Provider other = (Provider) obj;
+ boolean ret = this.from.equals(other.from) &&
+ this.services.size() == other.services.size();
+ if (ret == true) {
+ for (int i = 0; i < this.services.size(); i++) {
+ ret = ret && this.services.get(i).equals(other.services.get(i));
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashcode = 7 + 73 * from.hashCode();
+ for (String s : services) {
+ hashcode ^= s.hashCode();
+ }
+ return hashcode;
+ }
+
+ @Override
+ public List<String> getValue() {
+ List<String> result = new ArrayList<String>();
+ result.addAll(services);
+ return result;
+ }
+ static final String TYPE = "sun.annotation.Provider";
+ static final String TAG = "@Provider";
+ }
+
+ static class OptionalDependency extends AnnotatedDependency {
+
+ static boolean isOptional(Klass from, Klass to) {
+ synchronized (OptionalDependency.class) {
+ if (optionalDepsMap == null) {
+ // Build a map of classes to its optional dependencies
+ initDependencies();
+ }
+ }
+ for (Reference ref : optionalDepsMap.keySet()) {
+ if (ref.referrer() == from && ref.referree() == to) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ OptionalDependency(Klass klass) {
+ super(klass, true);
+ }
+
+ @Override
+ boolean isDynamic() {
+ return false;
+ }
+
+ @Override
+ String getTag() {
+ return TAG;
+ }
+ static final String TYPE = "sun.annotation.Optional";
+ static final String TAG = "@Optional";
+ }
+
+ static class CompilerInline extends AnnotatedDependency {
+
+ public CompilerInline(Klass klass) {
+ super(klass);
+ }
+
+ @Override
+ String getTag() {
+ return TAG;
+ }
+
+ @Override
+ boolean isDynamic() {
+ return false;
+ }
+ static final String TYPE = "sun.annotation.Inline";
+ static final String TAG = "@Inline";
+ }
+
+ static class Filter {
+
+ final String pattern;
+ final String regex;
+
+ Filter(String pattern) {
+ this.pattern = pattern;
+
+ boolean isRegex = false;
+ for (int i = 0; i < pattern.length(); i++) {
+ char p = pattern.charAt(i);
+ if (p == '*' || p == '[' || p == ']') {
+ isRegex = true;
+ break;
+ }
+ }
+
+ if (isRegex) {
+ this.regex = convertToRegex(pattern);
+ } else {
+ this.regex = null;
+ }
+ }
+
+ private String convertToRegex(String pattern) {
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
+ int index = 0;
+ int plen = pattern.length();
+ while (i < plen) {
+ char p = pattern.charAt(i);
+ if (p == '*') {
+ sb.append("(").append(pattern.substring(index, i)).append(")");
+ if (i + 1 < plen && pattern.charAt(i + 1) == '*') {
+ sb.append(".*");
+ index = i + 2;
+ } else {
+ sb.append("[^\\.]*");
+ index = i + 1;
+ }
+ } else if (p == '[') {
+ int j = i + 1;
+ while (j < plen) {
+ if (pattern.charAt(j) == ']') {
+ break;
+ }
+ j++;
+ }
+ if (j >= plen || pattern.charAt(j) != ']') {
+ throw new RuntimeException("Malformed pattern " + pattern);
+ }
+ sb.append("(").append(pattern.substring(index, i)).append(")");
+ sb.append(pattern.substring(i, j + 1));
+ index = j + 1;
+ i = j;
+ }
+ i++;
+ }
+ if (index < plen) {
+ sb.append("(").append(pattern.substring(index, plen)).append(")");
+ }
+ return sb.toString();
+ }
+
+ boolean matches(String name) {
+ if (regex == null) {
+ // the pattern is not a regex
+ return name.equals(pattern);
+ } else {
+ return name.matches(regex);
+ }
+ }
+ }
+
+ static boolean isValidType(String type) {
+ if (type.endsWith("(optional)")) {
+ int len = type.length() - "(optional)".length();
+ type = type.substring(0, len);
+ }
+ return type.equals(ClassForName.TYPE) || type.equals(ClassForName.TAG) ||
+ type.equals(NativeFindClass.TYPE) || type.equals(NativeFindClass.TAG) ||
+ type.equals(Provider.TYPE) || type.equals(Provider.TAG) ||
+ type.equals(CompilerInline.TYPE) || type.equals(CompilerInline.TAG) ||
+ type.equals(OptionalDependency.TYPE) || type.equals(OptionalDependency.TAG);
+ }
+
+ static AnnotatedDependency newAnnotatedDependency(String tag, String value, Klass klass) {
+ AnnotatedDependency dep = newAnnotatedDependency(tag, klass);
+ if (dep != null) {
+ dep.addValue(Collections.singletonList(value));
+ }
+ return dep;
+ }
+ static List<AnnotatedDependency> annotatedDependencies = new LinkedList<AnnotatedDependency>();
+ static List<AnnotatedDependency> optionalDependencies = new LinkedList<AnnotatedDependency>();
+
+ static AnnotatedDependency newAnnotatedDependency(String type, Klass klass) {
+ boolean optional = false;
+ if (type.endsWith("(optional)")) {
+ optional = true;
+ int len = type.length() - "(optional)".length();
+ type = type.substring(0, len);
+ }
+
+ if (type.equals(OptionalDependency.TYPE) || type.equals(OptionalDependency.TAG)) {
+ return newOptionalDependency(klass);
+ }
+
+ AnnotatedDependency dep;
+ if (type.equals(ClassForName.TYPE) || type.equals(ClassForName.TAG)) {
+ dep = new ClassForName(klass, optional);
+ } else if (type.equals(NativeFindClass.TYPE) || type.equals(NativeFindClass.TAG)) {
+ dep = new NativeFindClass(klass, optional);
+ } else if (type.equals(Provider.TYPE) || type.equals(Provider.TAG)) {
+ dep = new Provider(klass);
+ } else if (type.equals(CompilerInline.TYPE) || type.equals(CompilerInline.TAG)) {
+ dep = new CompilerInline(klass);
+ } else {
+ return null;
+ }
+ klass.addAnnotatedDep(dep);
+ annotatedDependencies.add(dep);
+ return dep;
+ }
+
+ static OptionalDependency newOptionalDependency(Klass klass) {
+ OptionalDependency dep = new OptionalDependency(klass);
+ optionalDependencies.add(dep);
+ return dep;
+ }
+ static Map<Reference, Set<AnnotatedDependency>> annotatedDepsMap = null;
+ static Map<Reference, Set<AnnotatedDependency>> optionalDepsMap = null;
+
+ static Map<Reference, Set<AnnotatedDependency>> getReferences(Module m) {
+ // ensure it's initialized
+ initDependencies();
+
+ Map<Reference, Set<AnnotatedDependency>> result = new TreeMap<Reference, Set<AnnotatedDependency>>();
+ for (Reference ref : annotatedDepsMap.keySet()) {
+ if (m.contains(ref.referrer()) && m.isModuleDependence(ref.referree())) {
+ result.put(ref, annotatedDepsMap.get(ref));
+ }
+ }
+ return result;
+ }
+
+ static Set<Module.Dependency> getDependencies(Module m) {
+ // ensure it's initialized
+ initDependencies();
+
+ Set<Module.Dependency> deps = new TreeSet<Module.Dependency>();
+ for (Reference ref : annotatedDepsMap.keySet()) {
+ if (m.contains(ref.referrer())) {
+ Module other = m.getModuleDependence(ref.referree());
+ if (other != null) {
+ for (AnnotatedDependency ad : annotatedDepsMap.get(ref)) {
+ Module.Dependency d = new Module.Dependency(other, ad.isOptional(), ad.isDynamic());
+ deps.add(d);
+ }
+ }
+ }
+ }
+ return deps;
+ }
+
+ synchronized static void initDependencies() {
+ if (annotatedDepsMap != null) {
+ return;
+ }
+
+ // Build a map of references to its dependencies
+ annotatedDepsMap = new TreeMap<Reference, Set<AnnotatedDependency>>();
+ optionalDepsMap = new TreeMap<Reference, Set<AnnotatedDependency>>();
+
+ for (Klass k : Klass.getAllClasses()) {
+ for (AnnotatedDependency ad : annotatedDependencies) {
+ if (ad.matches(k.getClassName())) {
+ Reference ref = new Reference(ad.from, k);
+ Set<AnnotatedDependency> set = annotatedDepsMap.get(ref);
+ if (set == null) {
+ set = new TreeSet<AnnotatedDependency>();
+ annotatedDepsMap.put(ref, set);
+ }
+ set.add(ad);
+ }
+ }
+
+ for (AnnotatedDependency ad : optionalDependencies) {
+ if (ad.matches(k.getClassName())) {
+ Reference ref = new Reference(ad.from, k);
+ Set<AnnotatedDependency> set = optionalDepsMap.get(ref);
+ if (set == null) {
+ set = new TreeSet<AnnotatedDependency>();
+ optionalDepsMap.put(ref, set);
+ }
+ set.add(ad);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/AnnotationParser.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.Annotation;
+import com.sun.tools.classfile.ExtendedAnnotation;
+import com.sun.tools.classfile.Annotation.Annotation_element_value;
+import com.sun.tools.classfile.Annotation.Array_element_value;
+import com.sun.tools.classfile.Annotation.Class_element_value;
+import com.sun.tools.classfile.Annotation.Enum_element_value;
+import com.sun.tools.classfile.Annotation.Primitive_element_value;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.classanalyzer.AnnotatedDependency.*;
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class AnnotationParser {
+
+ static boolean parseAnnotation = false;
+ static void setParseAnnotation(boolean newValue) {
+ parseAnnotation = newValue;
+ }
+
+ private final ClassFileParser cfparser;
+ public AnnotationParser(ClassFileParser cfparser) {
+ this.cfparser = cfparser;
+ }
+
+ private AnnotatedDependency addAnnotation(Annotation annot, Klass.Method method) {
+ String type = getType(annot.type_index);
+ AnnotatedDependency dep = AnnotatedDependency.newAnnotatedDependency(type, cfparser.this_klass);
+ if (dep != null) {
+ for (int i = 0; i < annot.num_element_value_pairs; i++) {
+ Element element = getElement(annot.element_value_pairs[i]);
+ dep.addElement(element.name, element.value);
+ }
+ dep.setMethod(method);
+ }
+ return dep;
+ }
+
+ private AnnotatedDependency addAnnotation(ExtendedAnnotation annot, Klass.Method method) {
+ return addAnnotation(annot.annotation, method);
+ }
+
+ class Element {
+
+ String name;
+ List<String> value;
+
+ Element(String name) {
+ this.name = name;
+ this.value = new ArrayList<String>();
+ }
+
+ void add(String v) {
+ value.add(v);
+ }
+ }
+
+ Element getElement(Annotation.element_value_pair pair) {
+ Element element = new Element(getName(pair.element_name_index));
+ evp.parse(pair.value, element);
+ return element;
+ }
+
+ private String getType(int index) {
+ try {
+ Descriptor d = new Descriptor(index);
+ return d.getFieldType(cfparser.classfile.constant_pool);
+ } catch (ConstantPoolException ignore) {
+ } catch (InvalidDescriptor ignore) {
+ }
+ return "Unknown";
+ }
+
+ private String getName(int index) {
+ return cfparser.constantPoolParser.stringValue(index);
+ }
+ element_value_Parser evp = new element_value_Parser();
+
+ class element_value_Parser implements Annotation.element_value.Visitor<Void, Element> {
+
+ public Void parse(Annotation.element_value value, Element element) {
+ value.accept(this, element);
+ return null;
+ }
+
+ public Void visitPrimitive(Primitive_element_value ev, Element element) {
+ String value = getName(ev.const_value_index);
+ element.add(value);
+ return null;
+ }
+
+ public Void visitEnum(Enum_element_value ev, Element element) {
+ String value = getName(ev.type_name_index) + "." + getName(ev.const_name_index);
+ element.add(value);
+ return null;
+ }
+
+ public Void visitClass(Class_element_value ev, Element element) {
+ String value = getName(ev.class_info_index) + ".class";
+ element.add(value);
+ return null;
+ }
+
+ public Void visitAnnotation(Annotation_element_value ev, Element element) {
+ // AnnotationParser.this.addAnnotation(ev.annotation_value);
+ throw new UnsupportedOperationException("Not supported: " + ev);
+ }
+
+ public Void visitArray(Array_element_value ev, Element element) {
+ for (int i = 0; i < ev.num_values; i++) {
+ parse(ev.values[i], element);
+ }
+ return null;
+ }
+ }
+
+ void parseAttributes(Attributes attributes, Klass.Method method) {
+ if (!parseAnnotation) {
+ return;
+ }
+
+ visitRuntimeAnnotations((RuntimeVisibleAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleAnnotations), method);
+ visitRuntimeAnnotations((RuntimeInvisibleAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleAnnotations), method);
+ visitRuntimeTypeAnnotations((RuntimeVisibleTypeAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleTypeAnnotations), method);
+ visitRuntimeTypeAnnotations((RuntimeInvisibleTypeAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleTypeAnnotations), method);
+ visitRuntimeParameterAnnotations((RuntimeVisibleParameterAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleParameterAnnotations), method);
+ visitRuntimeParameterAnnotations((RuntimeInvisibleParameterAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleParameterAnnotations), method);
+ }
+
+ public void visitRuntimeAnnotations(RuntimeAnnotations_attribute attr, Klass.Method method) {
+ if (attr == null) {
+ return;
+ }
+
+ for (int i = 0; i < attr.annotations.length; i++) {
+ addAnnotation(attr.annotations[i], method);
+ }
+ }
+
+ public void visitRuntimeTypeAnnotations(RuntimeTypeAnnotations_attribute attr, Klass.Method method) {
+ if (attr == null) {
+ return;
+ }
+
+ for (int i = 0; i < attr.annotations.length; i++) {
+ addAnnotation(attr.annotations[i], method);
+ }
+ }
+
+ public void visitRuntimeParameterAnnotations(RuntimeParameterAnnotations_attribute attr, Klass.Method method) {
+ if (attr == null) {
+ return;
+ }
+
+ for (int param = 0; param < attr.parameter_annotations.length; param++) {
+ for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
+ addAnnotation(attr.parameter_annotations[param][i], method);
+ }
+ }
+ }
+
+ void parseAttributes(Attributes attributes) {
+ parseAttributes(attributes, null);
+ }
+
+ public static void main(String[] args) throws Exception {
+ String jdkhome = null;
+ String output = ".";
+
+ // process arguments
+ int i = 0;
+ while (i < args.length) {
+ String arg = args[i++];
+ if (arg.equals("-jdkhome")) {
+ if (i < args.length) {
+ jdkhome = args[i++];
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-output")) {
+ output = args[i++];
+ } else {
+ usage();
+ }
+ }
+ if (jdkhome == null) {
+ usage();
+ }
+
+ // parse annotation and code attribute to find all references
+ // to Class.forName etc
+ CodeAttributeParser.setParseCodeAttribute(true);
+ AnnotationParser.setParseAnnotation(true);
+
+ ClassPath.setJDKHome(jdkhome);
+ ClassPath.parseAllClassFiles();
+
+ PrintWriter writer = new PrintWriter(new File(output, "jdk7.depconfig"));
+
+ try {
+ for (Klass k : Klass.getAllClasses()) {
+ for (AnnotatedDependency dep : k.getAnnotatedDeps()) {
+ if (dep.isEmpty()) {
+ continue;
+ }
+ writer.format("# %s \n", dep.method == null ? dep.from : dep.method);
+ writer.format("%s\n\n", dep);
+ }
+ }
+ } finally {
+ writer.close();
+ }
+
+ writer = new PrintWriter(new File(output, "optional.depconfig"));
+ try {
+ AnnotatedDependency prev = null;
+ for (AnnotatedDependency dep : AnnotatedDependency.optionalDependencies) {
+ if (prev != null && !dep.equals(prev)) {
+ writer.format("%s\n\n", prev);
+ }
+ writer.format("# %s \n", dep.method == null ? dep.from : dep.method);
+ prev = dep;
+ }
+ if (prev != null) {
+ writer.format("%s\n\n", prev);
+ }
+ } finally {
+ writer.close();
+ }
+
+ writer = new PrintWriter(new File(output, "runtime.references"));
+ try {
+ for (Map.Entry<String, Set<Klass.Method>> entry : CodeAttributeParser.runtimeReferences.entrySet()) {
+ writer.format("References to %s\n", entry.getKey());
+ Klass prev = null;
+ for (Klass.Method m : entry.getValue()) {
+ if (prev == null || prev != m.getKlass()) {
+ writer.format(" %-50s # %s\n", m.getKlass(), m);
+ } else if (prev == m.getKlass()) {
+ writer.format(" %-50s # %s\n", "", m);
+ }
+ prev = m.getKlass();
+ }
+ }
+ } finally {
+ writer.close();
+ }
+ }
+
+ private static void usage() {
+ System.out.println("Usage: AnnotationParser <options>");
+ System.out.println("Options: ");
+ System.out.println("\t-jdkhome <JDK home> where all jars will be parsed");
+ System.out.println("\t-depconfig <output file for annotated dependencies>");
+ System.out.println("\t-optional <output file for optional dependencies>");
+ System.exit(-1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/BootAnalyzer.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,819 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.File;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.ConstantPool.*;
+import static com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Instruction.TypeKind;
+import com.sun.tools.classfile.Type.*;
+
+/**
+ * Generate the module config for the boot module with
+ * a given set of roots (classes or methods) and exclude list.
+ *
+ * This tool does method-level dependency analysis starting
+ * from the root set and follows references transitively as follows:
+ * <ul>
+ * <li>For a given class, it will parse the ClassFile to
+ * find its superclass and superinterfaces and also
+ * its static initializer <clinit>.</li>
+ * <li>For each method, it will parse its Code attribute
+ * to look for a Methodref, Fieldref, and InterfaceMethodref.
+ * </li>
+ * <li>For each Fieldref, it will include the type of
+ * the field in the dependency.</li>
+ * <li>For each MethodRef, it will follow all references in
+ * that method.</li>
+ * <li>For each InterfaceMethodref, it will follow all references in
+ * that method defined its implementation classes in
+ * the resulting dependency list.</li>
+ * </ul>
+ *
+ * Limitation:
+ * <ul>
+ * <li>For each Methodref, it only parses the method of
+ * the specified type. It doesn't analyze the class hierarchy
+ * and follow references of its subclasses since it ends up
+ * pulls in many unnecessary dependencies. For now,
+ * the list of subclasses and methods need to be listed in
+ * the root set.</li>
+ * </ul>
+ *
+ * @author Mandy Chung
+ */
+public class BootAnalyzer {
+
+ public static void main(String[] args) throws Exception {
+ String jdkhome = null;
+ String config = null;
+ String output = ".";
+ boolean printClassList = false;
+
+ // process arguments
+ int i = 0;
+ while (i < args.length) {
+ String arg = args[i++];
+ if (arg.equals("-jdkhome")) {
+ if (i < args.length) {
+ jdkhome = args[i++];
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-config")) {
+ config = args[i++];
+ } else if (arg.equals("-output")) {
+ output = args[i++];
+ } else if (arg.equals("-classlist")) {
+ printClassList = true;
+ } else {
+ usage();
+ }
+ }
+
+
+
+ if (jdkhome == null || config == null) {
+ usage();
+ }
+
+ File jre = new File(jdkhome, "jre");
+ if (jre.exists()) {
+ ClassPath.setJDKHome(jdkhome);
+ } else {
+ File classes = new File(jdkhome, "classes");
+ if (classes.exists()) {
+ ClassPath.setClassPath(classes.getCanonicalPath());
+ } else {
+ throw new RuntimeException("Invalid jdkhome: " + jdkhome);
+ }
+ }
+
+ parseConfigFile(config);
+ followRoots();
+
+ // create output directory if it doesn't exist
+ File dir = new File(output);
+ if (!dir.isDirectory()) {
+ if (!dir.exists()) {
+ boolean created = dir.mkdir();
+ if (!created) {
+ throw new RuntimeException("Unable to create `" + dir + "'");
+ }
+ }
+ }
+
+ String bootmodule = "boot";
+ String bootconfig = resolve(dir, bootmodule, "config");
+ printBootConfig(bootconfig, bootmodule);
+
+ List<ModuleConfig> list = ModuleConfig.readConfigurationFile(bootconfig);
+ Module module = Module.addModule(list.get(0));
+ for (Klass k : Klass.getAllClasses()) {
+ module.addKlass(k);
+ }
+ module.fixupDependencies();
+
+ if (printClassList) {
+ module.printClassListTo(resolve(dir, bootmodule, "classlist"));
+ module.printSummaryTo(resolve(dir, bootmodule, "summary"));
+ }
+ }
+
+ // print boot.config file as an input to the ClassAnalyzer
+ private static void printBootConfig(String output, String bootmodule) throws IOException {
+
+ File f = new File(output);
+ PrintWriter writer = new PrintWriter(f);
+ try {
+ int count = 0;
+ writer.format("module %s {%n", bootmodule);
+ for (Klass k : Klass.getAllClasses()) {
+ if (count++ == 0) {
+ writer.format("%4s%7s %s", "", "include", k);
+ } else {
+ writer.format(",%n");
+ writer.format("%4s%7s %s", "", "", k);
+ }
+ }
+ writer.format(";%n}%n");
+ } finally {
+ writer.close();
+ }
+ }
+
+ private static String resolve(File dir, String mname, String suffix) {
+ File f = new File(dir, mname + "." + suffix);
+ return f.toString();
+
+ }
+ static List<MethodDescriptor> methods = new LinkedList<MethodDescriptor>();
+ static Deque<MethodDescriptor> pending = new ArrayDeque<MethodDescriptor>();
+ static Deque<MethodDescriptor> interfaceMethodRefs = new ArrayDeque<MethodDescriptor>();
+ static Filter filter = new Filter();
+
+ private static void followRoots() throws IOException {
+ MethodDescriptor md = null;
+
+ while ((md = pending.poll()) != null) {
+ if (!methods.contains(md)) {
+ methods.add(md);
+ if (md.classname.isEmpty()) {
+ trace("Warning: class missing %s%n", md);
+ continue;
+ }
+
+ if (filter.isExcluded(md.classname)) {
+ trace("excluded %s%n", md);
+ } else {
+ KlassInfo kinfo = getKlassInfo(md.classname);
+ if (kinfo.classname.contains("$")) {
+ int pos = kinfo.classname.lastIndexOf('$');
+ String outer = kinfo.classname.substring(0, pos);
+ if (!cache.containsKey(outer)) {
+ trace(" include outer class %s%n", outer);
+ getKlassInfo(outer).ensureParse();
+ }
+ }
+
+ kinfo.ensureParse();
+ if (md.methodname.length() > 0) {
+ if (filter.isExcluded(md.name)) {
+ trace("excluded %s%n", md);
+ } else {
+ if (md.interfaceMethodRef) {
+ trace("interface methodref %s%n", md);
+ interfaceMethodRefs.add(md);
+ } else {
+ List<String> descriptors = kinfo.parse(md);
+ if (descriptors.isEmpty()) {
+ if (kinfo.getSuperclass() != null) {
+ String sn = kinfo.getSuperclass().classname;
+ MethodDescriptor superMD = new MethodDescriptor(sn + "." + md.methodname, md.descriptor, false);
+ if (!methods.contains(superMD) && !pending.contains(superMD)) {
+ trace(" delegated %s to %s%n", md, superMD);
+ pending.add(superMD);
+ }
+ } else if (kinfo.isClass()) {
+ trace(" %s (not found)%n", md);
+ } else {
+ trace(" %s (interface)%n", md);
+ }
+ } else {
+ if (md.descriptor.equals("*")) {
+ trace(" parsed %s : ", md.name);
+ for (String s : descriptors) {
+ trace(" %s", s);
+ }
+ trace("%n");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (pending.isEmpty()) {
+ for (Klass k : Klass.getAllClasses()) {
+ if (k.getFileSize() == 0) {
+ getKlassInfo(k.getClassName()).ensureParse();
+ }
+ }
+ while ((md = interfaceMethodRefs.poll()) != null) {
+ addSubClassMethods(md);
+ }
+ }
+ }
+ }
+
+ static void addSubClassMethods(MethodDescriptor md) throws IOException {
+ for (KlassInfo kinfo : getSubClasses(md.classname)) {
+ String methodname = kinfo.classname + "." + md.methodname;
+ MethodDescriptor other = new MethodDescriptor(methodname, md.descriptor, false);
+ if (!methods.contains(other) && !pending.contains(other)) {
+ trace("Warning: subclass from %s to %s%n", md.classname, other);
+ pending.add(other);
+ }
+ }
+ }
+ private final static String privilegedActionInterf = "java.security.PrivilegedAction";
+ private final static String privilegedExceptionActionInterf = "java.security.PrivilegedExceptionAction";
+
+ static boolean isPrivilegedAction(String classname) {
+ if (classname.isEmpty()) {
+ return false;
+ }
+ KlassInfo kinfo = getKlassInfo(classname);
+ for (KlassInfo ki : kinfo.getInterfaces()) {
+ String interf = ki.classname;
+ if (interf.equals(privilegedActionInterf) ||
+ interf.equals(privilegedExceptionActionInterf)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ static Map<String, KlassInfo> cache = new HashMap<String, KlassInfo>();
+
+ static KlassInfo getKlassInfo(String classname) {
+ classname = classname.replace('/', '.');
+
+ KlassInfo kinfo = cache.get(classname);
+ if (kinfo == null) {
+ kinfo = new KlassInfo(classname);
+ cache.put(classname, kinfo);
+ }
+ return kinfo;
+ }
+
+ static class KlassInfo {
+
+ final String classname;
+ private ClassFileParser parser;
+ private KlassInfo superclass;
+ private List<KlassInfo> interfaces = new LinkedList<KlassInfo>();
+
+ KlassInfo(String classname) {
+ this.classname = classname;
+ }
+
+ boolean isClass() {
+ ensureParse();
+ return parser.classfile.isClass();
+ }
+
+ KlassInfo getSuperclass() {
+ ensureParse();
+ return superclass;
+ }
+
+ List<KlassInfo> getInterfaces() {
+ ensureParse();
+ return java.util.Collections.unmodifiableList(interfaces);
+ }
+
+ void ensureParse() {
+ try {
+ getClassFileParser();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ synchronized ClassFileParser getClassFileParser() throws IOException {
+ if (parser == null) {
+ parser = ClassPath.parserForClass(classname);
+ if (parser != null) {
+ parseClassFile();
+ List<String> descriptors = parse(new MethodDescriptor(classname + ".<clinit>", "()V", false));
+ }
+ }
+ return parser;
+ }
+
+ List<String> parse(MethodDescriptor md) {
+ ensureParse();
+ try {
+ List<String> descriptors = new LinkedList<String>();
+ for (Method m : parser.classfile.methods) {
+ String name = m.getName(parser.classfile.constant_pool);
+ String desc = parser.constantPoolParser.getDescriptor(m.descriptor.index);
+ if (name.equals(md.methodname)) {
+ if (md.descriptor.equals("*") || md.descriptor.equals(desc)) {
+ parseMethod(parser, m);
+ descriptors.add(desc);
+ }
+ }
+ }
+ return descriptors;
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private void parseClassFile() throws IOException {
+ parser.parseClassInfo();
+
+ ClassFile classfile = parser.classfile;
+ try {
+ if (classfile.super_class > 0) {
+ superclass = getKlassInfo(classfile.getSuperclassName());
+ }
+ if (classfile.interfaces != null) {
+ for (int i = 0; i < classfile.interfaces.length; i++) {
+ interfaces.add(getKlassInfo(classfile.getInterfaceName(i)));
+ }
+ }
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ static List<KlassInfo> getSubClasses(String classname) throws IOException {
+ List<KlassInfo> result = new LinkedList<KlassInfo>();
+ List<KlassInfo> list = new LinkedList<KlassInfo>();
+ list.addAll(cache.values());
+ for (KlassInfo kinfo : list) {
+ if (kinfo.getSuperclass() != null && classname.equals(kinfo.getSuperclass().classname)) {
+ result.add(kinfo);
+ }
+ for (KlassInfo interf : kinfo.getInterfaces()) {
+ if (classname.equals(interf.classname)) {
+ result.add(kinfo);
+ }
+ }
+ }
+ return result;
+ }
+
+ private static void parseConfigFile(String config) throws IOException {
+ FileInputStream in = new FileInputStream(config);
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ int lineNumber = 0;
+ while ((line = reader.readLine()) != null) {
+ lineNumber++;
+ if ((line = line.trim()).length() > 0) {
+ if (line.startsWith("#")) {
+ continue;
+ }
+
+ String[] s = line.split("\\s+");
+ if ("exclude".equals(s[0])) {
+ filter.exclude(s[1]);
+ } else {
+ String name = s[0].replace('/', '.');
+ if (name.length() > 0) {
+ String classname = name.replace('/', '.');
+ if (s.length == 2) {
+ // method name
+ int pos = classname.lastIndexOf('.');
+ classname = classname.substring(0, pos);
+ }
+
+ KlassInfo kinfo = getKlassInfo(classname);
+ if (kinfo.getClassFileParser() != null) {
+ // class exists
+ MethodDescriptor md = (s.length == 1) ? new MethodDescriptor(name) : new MethodDescriptor(name, s[1], false);
+ if (!pending.contains(md)) {
+ pending.add(md);
+ }
+ } else {
+ // class not found
+ trace("Class %s not found%n", classname);
+ }
+ }
+ }
+ }
+ }
+
+ } finally {
+ in.close();
+ }
+ }
+
+ private static void parseMethod(ClassFileParser cfparser, Method m) {
+ Klass.Method kmethod = cfparser.parseMethod(m);
+ Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);
+ if (c_attr != null) {
+ LineNumberTable_attribute lineNumTable =
+ (LineNumberTable_attribute) c_attr.attributes.get(Attribute.LineNumberTable);
+ InstructorVisitor visitor = new InstructorVisitor(cfparser, lineNumTable);
+ trace("parseMethod %s %s %n", cfparser.this_klass, kmethod);
+ for (Instruction instr : c_attr.getInstructions()) {
+ try {
+ instr.accept(visitor, kmethod);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new RuntimeException("error at or after byte " + instr.getPC());
+ }
+
+ }
+
+ if (c_attr.exception_table_langth > 0) {
+ for (int i = 0; i <
+ c_attr.exception_table.length; i++) {
+ Code_attribute.Exception_data handler = c_attr.exception_table[i];
+ int catch_type = handler.catch_type;
+ if (catch_type > 0) {
+ visitor.addConstantPoolRef(catch_type, kmethod, handler.start_pc);
+ }
+
+ }
+ }
+ }
+ }
+
+ static class MethodDescriptor {
+
+ final String name;
+ final String classname;
+ final String methodname;
+ final String descriptor;
+ final boolean interfaceMethodRef;
+
+ MethodDescriptor(String classname) {
+ this.classname = classname.replace('/', '.');
+ this.name = this.classname;
+ this.methodname = "";
+ this.descriptor = "";
+ this.interfaceMethodRef = false;
+ if (this.classname.length() == 1) {
+ throw new RuntimeException("invalid " + this);
+ }
+ }
+
+ MethodDescriptor(String name, String descriptor, boolean interfaceMethodRef) {
+ name = name.replace('/', '.');
+ this.name = name;
+ int pos = name.lastIndexOf('.');
+ this.classname = name.substring(0, pos);
+ this.methodname = name.substring(pos + 1, name.length());
+ this.descriptor = descriptor;
+ this.interfaceMethodRef = interfaceMethodRef;
+ if (this.classname.length() == 1) {
+ throw new RuntimeException("invalid " + this);
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ MethodDescriptor m = (MethodDescriptor) obj;
+
+ return this.name.equals(m.name) &&
+ this.descriptor.equals(m.descriptor);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0);
+ hash = 97 * hash + (this.descriptor != null ? this.descriptor.hashCode() : 0);
+ return hash;
+ }
+
+ public String toString() {
+ if (descriptor.isEmpty()) {
+ return name;
+ } else {
+ return name + " : " + descriptor;
+ }
+ }
+ }
+
+ static class Filter {
+
+ private Set<String> excludes = new TreeSet<String>();
+
+ Filter exclude(String pattern) {
+ excludes.add(pattern);
+ return this;
+ }
+
+ boolean isExcluded(String klass) {
+ for (String pattern : excludes) {
+ if (matches(klass, pattern)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean matches(String klass, String pattern) {
+ int pos = klass.lastIndexOf('.');
+ String packageName = pos > 0 ? klass.substring(0, pos) : "<unnamed>";
+ if (pattern.endsWith("**")) {
+ String p = pattern.substring(0, pattern.length() - 2);
+ return klass.startsWith(p);
+ } else if (pattern.endsWith("*")) {
+ pos = pattern.lastIndexOf('.');
+ String pkg = pos > 0 ? pattern.substring(0, pos) : "<unnamed>";
+ if (packageName.equals(pkg)) {
+ // package name has to be exact match
+ String p = pattern.substring(0, pattern.length() - 1);
+ return klass.startsWith(p);
+ } else {
+ return false;
+ }
+ } else {
+ // exact match or inner class
+ return klass.equals(pattern) || klass.startsWith(pattern + "$");
+ }
+ }
+ }
+
+ static class InstructorVisitor implements Instruction.KindVisitor<Void, Klass.Method> {
+
+ private final ClassFileParser parser;
+ private final LineNumberTable_attribute lineNumTable;
+
+ InstructorVisitor(ClassFileParser parser, LineNumberTable_attribute lineNumTable) {
+ this.parser = parser;
+ this.lineNumTable = lineNumTable;
+ }
+
+ int getLineNumber(int pc) {
+ if (lineNumTable != null) {
+ int start_pc = 0;
+ int lineno = 0;
+ for (int i = 0; i < lineNumTable.line_number_table_length; i++) {
+ int cur_start_pc = lineNumTable.line_number_table[i].start_pc;
+ if (pc == 0 && cur_start_pc == 0) {
+ return lineNumTable.line_number_table[i].line_number;
+ } else if (pc >= start_pc && pc < cur_start_pc) {
+ return lineno;
+ }
+ start_pc = cur_start_pc;
+ lineno = lineNumTable.line_number_table[i].line_number;
+ }
+ }
+ return 0;
+ }
+
+ void addConstantPoolRef(int index, Klass.Method m, int pc) {
+ try {
+ CPInfo cpInfo = parser.classfile.constant_pool.get(index);
+ String name = cpInfo.accept(typeFinder, null);
+ if (name != null) {
+ trace(" %s %s at line %d%n", parser.constantPoolParser.tagName(index), name, getLineNumber(pc));
+ }
+ } catch (InvalidIndex ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public Void visitNoOperands(Instruction instr, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitArrayType(Instruction instr, TypeKind kind, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitBranch(Instruction instr, int offset, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitConstantPoolRef(Instruction instr, int index, Klass.Method m) {
+ addConstantPoolRef(index, m, instr.getPC());
+ return null;
+ }
+
+ public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Klass.Method m) {
+ addConstantPoolRef(index, m, instr.getPC());
+ return null;
+ }
+
+ public Void visitLocal(Instruction instr, int index, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitLocalAndValue(Instruction instr, int index, int value, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitValue(Instruction instr, int value, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitUnknown(Instruction instr, Klass.Method m) {
+ return null;
+ }
+ private ConstantPool.Visitor<String, Void> typeFinder = new ConstantPool.Visitor<String, Void>() {
+
+ String getClassName(CPRefInfo info, Void p) {
+ try {
+ return parser.checkClassName(info.getClassName()).replace('/', '.');
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ boolean addReferencedClass(String name) {
+ if (Klass.findKlass(name) == null) {
+ MethodDescriptor md = new MethodDescriptor(name);
+ if (!methods.contains(md) && !pending.contains(md)) {
+ pending.add(md);
+ }
+ return true;
+ }
+ return false;
+ }
+ private String privilegedActionClass = "";
+
+ void cachePrivilegedAction(String classname) {
+ trace(" found PrivilegedAction %s%n", classname);
+ privilegedActionClass = classname;
+ }
+
+ void doPrivilegedCall(String method) {
+ if (privilegedActionClass.length() > 0) {
+ MethodDescriptor md = new MethodDescriptor(privilegedActionClass + ".run", "*", false);
+ if (!methods.contains(md) && !pending.contains(md)) {
+ trace(" doPrivileged %s%n", md);
+ pending.add(md);
+ }
+ }
+ }
+
+ private String addMethodDescriptor(CPRefInfo info, Void p) {
+ try {
+ String classname = getClassName(info, null);
+ String method = classname + "." + info.getNameAndTypeInfo().getName();
+ String descriptor = info.getNameAndTypeInfo().getType();
+
+ if (method.endsWith(".<init>") && isPrivilegedAction(classname)) {
+ cachePrivilegedAction(classname);
+ }
+ if (method.equals("java.security.AccessController.doPrivileged")) {
+ doPrivilegedCall(method);
+ return method;
+ }
+
+ boolean interfaceMethodRef = info instanceof CONSTANT_InterfaceMethodref_info;
+ MethodDescriptor md = new MethodDescriptor(method, descriptor, interfaceMethodRef);
+ if (!methods.contains(md) && !pending.contains(md)) {
+ pending.add(md);
+ }
+ return method;
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String visitClass(CONSTANT_Class_info info, Void p) {
+ try {
+ String classname = parser.checkClassName(info.getName()).replace('/', '.');
+ if (classname.length() > 0) {
+ addReferencedClass(classname);
+ }
+ return classname;
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public String visitDouble(CONSTANT_Double_info info, Void p) {
+ // skip
+ return null;
+ }
+
+ public String visitFieldref(CONSTANT_Fieldref_info info, Void p) {
+ try {
+ String classname = getClassName(info, p);
+ if (classname.length() > 0) {
+ addReferencedClass(classname);
+ }
+
+ String type = info.getNameAndTypeInfo().getType();
+ String fieldType = parser.checkClassName(type).replace('/', '.');
+ if (fieldType.length() > 0) {
+ addReferencedClass(classname);
+ }
+ return parser.constantPoolParser.stringValue(info);
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String visitFloat(CONSTANT_Float_info info, Void p) {
+ // skip
+ return null;
+ }
+
+ public String visitInteger(CONSTANT_Integer_info info, Void p) {
+ // skip
+ return null;
+ }
+
+ public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
+ return addMethodDescriptor(info, p);
+ }
+
+ public String visitLong(CONSTANT_Long_info info, Void p) {
+ // skip
+ return null;
+ }
+
+ public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
+ // skip
+ return null;
+ }
+
+ public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
+ return addMethodDescriptor(info, p);
+ }
+
+ public String visitString(CONSTANT_String_info info, Void p) {
+ // skip
+ return null;
+ }
+
+ public String visitUtf8(CONSTANT_Utf8_info info, Void p) {
+ return null;
+ }
+ };
+ }
+ static boolean traceOn = System.getProperty("classanalyzer.debug") != null;
+
+ private static void trace(String format, Object... args) {
+ if (traceOn) {
+ System.out.format(format, args);
+ }
+ }
+
+ private static void usage() {
+ System.out.println("Usage: BootAnalyzer <options>");
+ System.out.println("Options: ");
+ System.out.println("\t-jdkhome <JDK home> where all jars will be parsed");
+ System.out.println("\t-config <roots for the boot module>");
+ System.out.println("\t-output <output dir>");
+ System.out.println("\t-classlist print class list and summary");
+ System.exit(-1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/CheckDeps.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A simple tool to check module dependencies against a known list of
+ * dependencies. The tool fails (by throwing a RuntimeException) is an
+ * unexpected dependency is detected.
+ */
+
+public class CheckDeps {
+
+ /**
+ * Represents a dependency from one module to another module. The dependency
+ * may be optional.
+ */
+ static class Dependency {
+ private final String module;
+ private final String other;
+ private final boolean optional;
+
+ private Dependency(String module, String other, boolean optional) {
+ this.module = module;
+ this.other = other;
+ this.optional = optional;
+ }
+
+ String module() { return module; }
+ String other() { return other; }
+ boolean isOptional() { return optional; }
+
+ /**
+ * Parses a dependency in one of the following forms:
+ * a -> b
+ * [optional] a -> b
+ */
+ static Dependency fromString(String s) {
+ String[] components = s.split(" ");
+ int count = components.length;
+ if (count != 3 && count != 4)
+ throw new IllegalArgumentException(s);
+ boolean optional = (count == 4);
+ if (optional && !components[0].equals("[optional]"))
+ throw new IllegalArgumentException(s);
+ String arrow = optional ? components[2] : components[1];
+ if (!arrow.equals("->"))
+ throw new IllegalArgumentException(s);
+ String module = optional ? components[1] : components[0];
+ String other = optional ? components[3] : components[2];
+ return new Dependency(module, other, optional);
+ }
+
+ @Override public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (optional)
+ sb.append("[optional] ");
+ sb.append(module);
+ sb.append(" -> ");
+ sb.append(other);
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Represents the "tail"
+ */
+ static class DependencyTail {
+ private final String module;
+ private final boolean optional;
+
+ DependencyTail(String module, boolean optional) {
+ this.module = module;
+ this.optional = optional;
+ }
+ String module() { return module; }
+ boolean isOptional() { return optional; }
+ }
+
+ static void usage() {
+ System.out.println("java CheckDeps file1 file2");
+ System.out.println(" where file1 is the expected dependencies and file2 is");
+ System.out.println(" the actual dependencies. Both files are assumed to be");
+ System.out.println(" in modules.summary format (see ClassAnalyzer tool).");
+ System.out.println();
+ System.out.println("Example usages:");
+ System.out.println(" java CheckDeps make/modules/modules.summary " +
+ "$(OUTPUTDIR)/modules.summary");
+ System.exit(-1);
+ }
+
+ public static void main(String[] args) throws IOException {
+ if (args.length != 2)
+ usage();
+
+ // maps a module to the list of modules that it depends on
+ Map<String,List<DependencyTail>> expected =
+ new HashMap<String,List<DependencyTail>>();
+
+ // parse the expected dependencies file
+ Scanner s;
+ s = new Scanner(new FileInputStream(args[0]));
+ try {
+ while (s.hasNextLine()) {
+ Dependency ref = Dependency.fromString(s.nextLine());
+ if (ref != null) {
+ String module = ref.module();
+ List<DependencyTail> list = expected.get(module);
+ if (list == null) {
+ list = new ArrayList<DependencyTail>();
+ expected.put(module, list);
+ }
+ list.add(new DependencyTail(ref.other(), ref.isOptional()));
+ }
+ }
+ } finally {
+ s.close();
+ }
+
+ // parse the actual dependencies file, checking each dependency
+ // against the expected list.
+ boolean fail = false;
+ s = new Scanner(new FileInputStream(args[1]));
+ try {
+ while (s.hasNextLine()) {
+ Dependency dep = Dependency.fromString(s.nextLine());
+
+ // check if this dependency is expected
+ List<DependencyTail> list = expected.get(dep.module());
+ DependencyTail tail = null;
+ if (list != null) {
+ for (DependencyTail t: list) {
+ if (t.module().equals(dep.other())) {
+ tail = t;
+ break;
+ }
+ }
+ }
+ if (tail == null) {
+ System.err.println("Unexpected dependency: " + dep);
+ fail = true;
+ } else {
+ // hard dependency when optional dependency is expected
+ if (tail.isOptional() != dep.isOptional()) {
+ if (tail.isOptional()) {
+ System.err.println("Unexpected dependency: " + dep);
+ fail = true;
+ }
+ }
+ }
+ }
+ } finally {
+ s.close();
+ }
+
+ if (fail)
+ throw new RuntimeException("Unexpected dependencies found");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassAnalyzer.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import com.sun.classanalyzer.AnnotatedDependency.*;
+import com.sun.classanalyzer.Module.Dependency;
+import com.sun.classanalyzer.Module.PackageInfo;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class ClassAnalyzer {
+
+ public static void main(String[] args) throws Exception {
+ String jdkhome = null;
+ String cpath = null;
+ List<String> configs = new ArrayList<String>();
+ List<String> depconfigs = new ArrayList<String>();
+ String output = ".";
+ boolean mergeModules = true;
+ boolean showDynamic = false;
+
+ // process arguments
+ int i = 0;
+ while (i < args.length) {
+ String arg = args[i++];
+ if (arg.equals("-jdkhome")) {
+ if (i < args.length) {
+ jdkhome = args[i++];
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-cpath")) {
+ if (i < args.length) {
+ cpath = args[i++];
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-config")) {
+ if (i < args.length) {
+ configs.add(args[i++]);
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-depconfig")) {
+ if (i < args.length) {
+ depconfigs.add(args[i++]);
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-output")) {
+ if (i < args.length) {
+ output = args[i++];
+ } else {
+ usage();
+ }
+ } else if (arg.equals("-base")) {
+ ModuleConfig.setBaseModule(args[i++]);
+ } else if (arg.equals("-nomerge")) {
+ // analyze the fine-grained module dependencies
+ mergeModules = false;
+ } else if (arg.equals("-showdynamic")) {
+ showDynamic = true;
+ } else {
+ System.err.println("Invalid option: " + arg);
+ usage();
+ }
+ }
+
+ if ((jdkhome == null && cpath == null) || (jdkhome != null && cpath != null)) {
+ usage();
+ }
+ if (configs.isEmpty()) {
+ usage();
+ }
+
+ if (jdkhome != null) {
+ ClassPath.setJDKHome(jdkhome);
+ } else if (cpath != null) {
+ ClassPath.setClassPath(cpath);
+ }
+
+ // create output directory if it doesn't exist
+ File dir = new File(output);
+ if (!dir.isDirectory()) {
+ if (!dir.exists()) {
+ boolean created = dir.mkdir();
+ if (!created) {
+ throw new RuntimeException("Unable to create `" + dir + "'");
+ }
+ }
+ }
+
+ buildModules(configs, depconfigs, mergeModules);
+
+ // generate output files
+ for (Module m : modules) {
+ // only generate reports for top-level modules
+ if (m.group() == m) {
+ m.printClassListTo(resolve(dir, m.name(), "classlist"));
+ m.printResourceListTo(resolve(dir, m.name(), "resources"));
+ m.printSummaryTo(resolve(dir, m.name(), "summary"));
+ m.printDependenciesTo(resolve(dir, m.name(), "dependencies"), showDynamic);
+ }
+ }
+
+ // Generate other summary reports
+ printModulesSummary(dir, showDynamic);
+ printModulesDot(dir, showDynamic);
+ printModulesList(dir);
+ printPackagesSummary(dir);
+ }
+ private static List<Module> modules = new ArrayList<Module>();
+
+ static void buildModules(List<String> configs,
+ List<String> depconfigs,
+ boolean mergeModules) throws IOException {
+ // create modules based on the input config files
+ for (String file : configs) {
+ for (ModuleConfig mconfig : ModuleConfig.readConfigurationFile(file)) {
+ modules.add(Module.addModule(mconfig));
+ }
+ }
+
+ // parse class files
+ ClassPath.parseAllClassFiles();
+
+ // Add additional dependencies if specified
+ if (depconfigs != null && depconfigs.size() > 0) {
+ DependencyConfig.parse(depconfigs);
+ }
+
+ // process the roots and dependencies to get the classes for each module
+ for (Module m : modules) {
+ m.processRootsAndReferences();
+ }
+
+ // update the dependencies for classes that were subsequently allocated
+ // to modules
+ for (Module m : modules) {
+ m.fixupDependencies();
+ }
+
+ if (mergeModules) {
+ Module.buildModuleMembers();
+ }
+ }
+
+ private static void printModulesSummary(File dir, boolean showDynamic) throws IOException {
+ // print summary of dependencies
+ PrintWriter writer = new PrintWriter(new File(dir, "modules.summary"));
+ try {
+ for (Module m : modules) {
+ // only show top-level module dependencies
+ if (m.group() == m) {
+ for (Dependency dep : m.dependents()) {
+ if (!showDynamic && dep.dynamic && dep.optional) {
+ continue;
+ }
+ if (dep.module == null || !dep.module.isBase()) {
+
+ String prefix = "";
+ if (dep.optional) {
+ if (dep.dynamic) {
+ prefix = "[dynamic] ";
+ } else {
+ prefix = "[optional] ";
+ }
+ }
+
+ Module other = dep != null ? dep.module : null;
+ writer.format("%s%s -> %s%n", prefix, m, other);
+ }
+ }
+ }
+ }
+ } finally {
+ writer.close();
+ }
+ }
+
+ private static void printModulesDot(File dir, boolean showDynamic) throws IOException {
+ PrintWriter writer = new PrintWriter(new File(dir, "modules.dot"));
+ try {
+ writer.println("digraph jdk {");
+ for (Module m : modules) {
+ if (m.group() == m) {
+ for (Dependency dep : m.dependents()) {
+ if (!showDynamic && dep.dynamic && dep.optional) {
+ continue;
+ }
+ if (dep.module == null || !dep.module.isBase()) {
+ String style = "";
+ String color = "";
+ String property = "";
+ if (dep.optional) {
+ style = "style=dotted";
+ }
+ if (dep.dynamic) {
+ color = "color=red";
+ }
+ if (style.length() > 0 || color.length() > 0) {
+ String comma = "";
+ if (style.length() > 0 && color.length() > 0) {
+ comma = ", ";
+ }
+ property = String.format(" [%s%s%s]", style, comma, color);
+ }
+ Module other = dep != null ? dep.module : null;
+ writer.format(" \"%s\" -> \"%s\"%s;%n", m, other, property);
+ }
+ }
+ }
+ }
+ writer.println("}");
+ } finally {
+ writer.close();
+ }
+ }
+
+ private static void printMembers(Module m, PrintWriter writer) {
+ for (Module member : m.members()) {
+ if (!member.isEmpty()) {
+ writer.format("%s ", member);
+ printMembers(member, writer);
+ }
+ }
+ }
+
+ private static void printModulesList(File dir) throws IOException {
+ // print module group / members relationship
+ PrintWriter writer = new PrintWriter(new File(dir, "modules.list"));
+ try {
+ for (Module m : modules) {
+ if (m.group() == m && !m.isEmpty()) {
+ writer.format("%s ", m);
+ printMembers(m, writer);
+ writer.println();
+ }
+ }
+ } finally {
+ writer.close();
+ }
+ }
+
+ private static void printPackagesSummary(File dir) throws IOException {
+ // print package / module relationship
+ PrintWriter writer = new PrintWriter(new File(dir, "modules.pkginfo"));
+ try {
+ Map<String, Set<Module>> packages = new TreeMap<String, Set<Module>>();
+ Set<String> splitPackages = new TreeSet<String>();
+
+ for (Module m : modules) {
+ if (m.group() == m) {
+ for (PackageInfo info : m.getPackageInfos()) {
+ Set<Module> value = packages.get(info.pkgName);
+ if (value == null) {
+ value = new TreeSet<Module>();
+ packages.put(info.pkgName, value);
+ } else {
+ // package in more than one module
+ splitPackages.add(info.pkgName);
+ }
+ value.add(m);
+ }
+ }
+ }
+
+ // packages that are splitted among multiple modules
+ writer.println("Packages splitted across modules:-\n");
+ writer.format("%-60s %s\n", "Package", "Module");
+
+ for (String pkgname : splitPackages) {
+ writer.format("%-60s", pkgname);
+ for (Module m : packages.get(pkgname)) {
+ writer.format(" %s", m);
+ }
+ writer.println();
+ }
+
+ writer.println("\nPackage-private dependencies:-");
+ for (String pkgname : splitPackages) {
+ for (Klass k : Klass.getAllClasses()) {
+ if (k.getPackageName().equals(pkgname)) {
+ Module m = k.getModule();
+ // check if this klass references a package-private
+ // class that is in a different module
+ for (Klass other : k.getReferencedClasses()) {
+ if (other.getModule() != m &&
+ !other.isPublic() &&
+ other.getPackageName().equals(pkgname)) {
+ String from = k.getClassName() + " (" + m + ")";
+ writer.format("%-60s -> %s (%s)\n", from, other, other.getModule());
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ writer.close();
+ }
+
+ }
+
+ private static String resolve(File dir, String mname, String suffix) {
+ File f = new File(dir, mname + "." + suffix);
+ return f.toString();
+
+ }
+
+ private static void usage() {
+ System.out.println("Usage: ClassAnalyzer <options>");
+ System.out.println("Options: ");
+ System.out.println("\t-jdkhome <JDK home> where all jars will be parsed");
+ System.out.println("\t-cpath <classpath> where classes and jars will be parsed");
+ System.out.println("\t Either -jdkhome or -cpath option can be used.");
+ System.out.println("\t-config <module config file>");
+ System.out.println("\t This option can be repeated for multiple module config files");
+ System.out.println("\t-output <output dir>");
+ System.out.println("\t-nomerge specify not to merge modules");
+ System.out.println("\t-showdynamic show dynamic dependencies in the reports");
+ System.exit(-1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassFileParser.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,629 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.classanalyzer;
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.Type.*;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import static com.sun.tools.classfile.AccessFlags.*;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class ClassFileParser {
+
+ final Klass this_klass;
+ final ClassFile classfile;
+ final ConstantPoolParser constantPoolParser;
+ final AnnotationParser annotationParser;
+ final CodeAttributeParser codeAttributeParser;
+ private final boolean buildDeps;
+
+ protected ClassFileParser(InputStream in, long size, boolean buildDeps) throws IOException {
+ try {
+ this.classfile = ClassFile.read(in);
+ this.this_klass = getKlass(this.classfile);
+ this.buildDeps = buildDeps;
+ this.constantPoolParser = new ConstantPoolParser(this);
+ this.annotationParser = new AnnotationParser(this);
+ this.codeAttributeParser = new CodeAttributeParser(this);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private Klass getKlass(ClassFile cf) throws ConstantPoolException {
+ Klass k = Klass.getKlass(cf.getName());
+ k.setAccessFlags(cf.access_flags.flags);
+ k.setFileSize(cf.byteLength());
+ return k;
+ }
+
+ public static ClassFileParser newParser(InputStream in, long size, boolean buildDeps) throws IOException {
+ return new ClassFileParser(in, size, buildDeps);
+ }
+
+ public static ClassFileParser newParser(String classPathname, boolean buildDeps) throws IOException {
+ return newParser(new File(classPathname), buildDeps);
+ }
+
+ public static ClassFileParser newParser(File f, boolean buildDeps) throws IOException {
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
+ try {
+ return newParser(in, f.length(), buildDeps);
+ } finally {
+ in.close();
+ }
+ }
+
+ public void parseDependency(boolean publicAPIs) throws IOException {
+ if (publicAPIs && !classfile.access_flags.is(ACC_PUBLIC)) {
+ // process public APIs only
+ return;
+ }
+
+ parseClassInfo();
+ if (!publicAPIs) {
+ // parse all references in the classfile
+ constantPoolParser.parseDependency();
+ }
+ parseMethods(publicAPIs);
+ parseFields(publicAPIs);
+ }
+
+ void parseClassInfo() throws IOException {
+ ConstantPool cpool = classfile.constant_pool;
+ try {
+ Signature_attribute sigAttr = (Signature_attribute) classfile.attributes.get(Attribute.Signature);
+ if (sigAttr == null) {
+ // use info from class file header
+ if (classfile.isClass() && classfile.super_class != 0) {
+ String sn = classfile.getSuperclassName();
+ addExtends(sn);
+ }
+ for (int i = 0; i < classfile.interfaces.length; i++) {
+ String interf = classfile.getInterfaceName(i);
+ if (classfile.isClass()) {
+ addImplements(interf);
+ } else {
+ addExtends(interf);
+ }
+ }
+ } else {
+ Type t = sigAttr.getParsedSignature().getType(cpool);
+ // The signature parser cannot disambiguate between a
+ // FieldType and a ClassSignatureType that only contains a superclass type.
+ if (t instanceof Type.ClassSigType) {
+ Type.ClassSigType cst = Type.ClassSigType.class.cast(t);
+ if (cst.superclassType != null) {
+ for (Klass k : getKlass(cst.superclassType)) {
+ addExtends(k);
+ }
+ }
+ if (cst.superinterfaceTypes != null) {
+ for (Type t1 : cst.superinterfaceTypes) {
+ for (Klass k : getKlass(t1)) {
+ addImplements(k);
+ }
+ }
+ }
+ } else {
+ for (Klass k : getKlass(t)) {
+ addExtends(k);
+ }
+ }
+ }
+ // parse attributes
+ annotationParser.parseAttributes(classfile.attributes);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private void parseFields(boolean publicAPIs) throws IOException {
+ ConstantPool cpool = classfile.constant_pool;
+ for (Field f : classfile.fields) {
+ try {
+ AccessFlags flags = f.access_flags;
+ if (publicAPIs && !flags.is(ACC_PUBLIC) && !flags.is(ACC_PROTECTED)) {
+ continue;
+ }
+ String fieldname = f.getName(cpool);
+ Signature_attribute sigAttr = (Signature_attribute) f.attributes.get(Attribute.Signature);
+
+ if (sigAttr == null) {
+ Set<Klass> types = parseDescriptor(f.descriptor);
+ String info = getFlag(flags) + " " + f.descriptor.getFieldType(cpool) + " " + fieldname;
+ addFieldTypes(types, info, flags);
+ } else {
+ Type t = sigAttr.getParsedSignature().getType(cpool);
+ String info = getFlag(flags) + " " + t + " " + fieldname;
+ addFieldTypes(getKlass(t), info, flags);
+ }
+ // parse attributes
+ annotationParser.parseAttributes(f.attributes);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ } catch (InvalidDescriptor ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ private void parseMethods(boolean publicAPIs) {
+ for (Method m : classfile.methods) {
+ if (publicAPIs && !m.access_flags.is(ACC_PUBLIC) && !m.access_flags.is(ACC_PROTECTED)) {
+ // only interest in the API level
+ return;
+ }
+
+ parseMethod(m);
+ }
+ }
+
+ String checkClassName(String classname) {
+ int i = 0;
+ while (i < classname.length()) {
+ switch (classname.charAt(i)) {
+ case 'Z':
+ case 'B':
+ case 'C':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'F':
+ case 'D':
+ return "";
+ case 'L':
+ if (!classname.endsWith(";")) {
+ throw new RuntimeException("Invalid classname " + classname);
+ }
+ return classname.substring(i + 1, classname.length() - 1);
+ case '[':
+ i++;
+ break;
+ default:
+ if (classname.endsWith(";")) {
+ throw new RuntimeException("Invalid classname " + classname);
+ }
+ return classname;
+
+ }
+ }
+ throw new RuntimeException("Invalid classname " + classname);
+ }
+
+ private void addExtends(String classname) throws IOException {
+ if (!buildDeps) {
+ return;
+ }
+
+ addExtends(Klass.getKlass(classname));
+ }
+
+ private void addExtends(Klass k) {
+ if (!buildDeps) {
+ return;
+ }
+
+ ResolutionInfo resInfo = ResolutionInfo.resolvedExtends(this_klass, k);
+ resInfo.setPublicAccess(classfile.access_flags.is(ACC_PUBLIC));
+ this_klass.addDep(k, resInfo);
+ k.addReferrer(this_klass, resInfo);
+ }
+
+ private void addImplements(String classname) throws IOException {
+ if (!buildDeps) {
+ return;
+ }
+
+ addImplements(Klass.getKlass(classname));
+ }
+
+ private void addImplements(Klass k) {
+ if (!buildDeps) {
+ return;
+ }
+
+ ResolutionInfo resInfo = ResolutionInfo.resolvedImplements(this_klass, k);
+ resInfo.setPublicAccess(classfile.access_flags.is(ACC_PUBLIC));
+
+ this_klass.addDep(k, resInfo);
+
+ k.addReferrer(this_klass, resInfo);
+ }
+
+ private Set<Klass> getKlass(Type type) throws IOException {
+ Set<Klass> refTypes = new TreeSet<Klass>();
+ if (!buildDeps) {
+ return refTypes;
+ }
+
+ type.accept(typevisitor, refTypes);
+ return refTypes;
+ }
+ private Type.Visitor<Void, Set<Klass>> typevisitor = new Type.Visitor<Void, Set<Klass>>() {
+
+ public Void visitSimpleType(SimpleType type, Set<Klass> klasses) {
+ // nop
+ return null;
+ }
+
+ public Void visitArrayType(ArrayType type, Set<Klass> klasses) {
+ try {
+ klasses.addAll(getKlass(type.elemType));
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ return null;
+
+ }
+
+ public Void visitMethodType(MethodType type, Set<Klass> klasses) {
+ throw new InternalError("Unexpected type " + type);
+ }
+
+ public Void visitClassSigType(ClassSigType type, Set<Klass> klasses) {
+ try {
+ if (type.superclassType != null) {
+ klasses.addAll(getKlass(type.superclassType));
+ }
+ if (type.superinterfaceTypes != null) {
+ for (Type t : type.superinterfaceTypes) {
+ klasses.addAll(getKlass(t));
+ }
+ }
+ if (type.typeParamTypes != null) {
+ for (Type t : type.typeParamTypes) {
+ klasses.addAll(getKlass(t));
+ }
+ }
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ return null;
+ }
+
+ public Void visitClassType(ClassType type, Set<Klass> klasses) {
+ klasses.add(Klass.getKlass(type.getBinaryName()));
+ if (type.typeArgs != null) {
+ for (Type t : type.typeArgs) {
+ try {
+ klasses.addAll(getKlass(t));
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+ return null;
+
+ }
+
+ public Void visitTypeParamType(TypeParamType type, Set<Klass> klasses) {
+ try {
+ if (type.classBound != null) {
+ klasses.addAll(getKlass(type.classBound));
+ }
+ if (type.interfaceBounds != null) {
+ for (Type t : type.interfaceBounds) {
+ klasses.addAll(getKlass(t));
+ }
+ }
+
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ return null;
+
+ }
+
+ public Void visitWildcardType(WildcardType type, Set<Klass> klasses) {
+ if (type.boundType != null) {
+ try {
+ klasses.addAll(getKlass(type.boundType));
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ return null;
+
+ }
+ };
+
+ private void printMethod(Method m) {
+ try {
+ System.out.println("parsing " + m.getName(classfile.constant_pool) + "(" +
+ m.descriptor.getParameterTypes(classfile.constant_pool) + ") return type " +
+ m.descriptor.getReturnType(classfile.constant_pool));
+
+ } catch (ConstantPoolException ex) {
+ } catch (InvalidDescriptor ex) {
+ }
+ }
+
+ private static StringBuilder appendWord(StringBuilder sb, String word) {
+ if (sb.length() > 0) {
+ sb.append(" ");
+ }
+ sb.append(word);
+ return sb;
+ }
+
+ private static String getFlag(AccessFlags flags) {
+ StringBuilder modifier = new StringBuilder();
+ if (flags.is(ACC_PUBLIC)) {
+ modifier.append("public");
+ }
+ if (flags.is(ACC_PRIVATE)) {
+ modifier.append("private");
+ }
+ if (flags.is(ACC_PROTECTED)) {
+ modifier.append("protected");
+ }
+ if (flags.is(ACC_STATIC)) {
+ appendWord(modifier, "static");
+ }
+ if (flags.is(ACC_FINAL)) {
+ appendWord(modifier, "final");
+ }
+ if (flags.is(ACC_SYNCHRONIZED)) {
+ // return "synchronized";
+ }
+ if (flags.is(0x80)) {
+ // return (t == Type.Field ? "transient" : null);
+ // return "transient";
+ }
+ if (flags.is(ACC_VOLATILE)) {
+ // return "volatile";
+ }
+ if (flags.is(ACC_NATIVE)) {
+ // return "native";
+ }
+ if (flags.is(ACC_ABSTRACT)) {
+ appendWord(modifier, "abstract");
+ }
+ if (flags.is(ACC_STRICT)) {
+ // return "strictfp";
+ }
+ if (flags.is(ACC_MODULE)) {
+ appendWord(modifier, "module");
+ }
+ return modifier.toString();
+ }
+
+ private Klass.Method toKlassMethod(Method m, Descriptor d) {
+ try {
+ ConstantPool cpool = classfile.constant_pool;
+ String methodname = m.getName(cpool);
+ StringBuilder sb = new StringBuilder();
+ sb.append(getFlag(m.access_flags));
+ if (methodname.equals("<init>")) {
+ String s = this_klass.getBasename() + d.getParameterTypes(cpool);
+ appendWord(sb, s);
+ } else if (methodname.equals("<clinit>")) {
+ // <clinit>
+ appendWord(sb, methodname);
+ } else {
+ String s = d.getReturnType(cpool) + " " + methodname + d.getParameterTypes(cpool);
+ appendWord(sb, s);
+ }
+ String signature = sb.toString().replace('/', '.');
+ return this_klass.getMethod(methodname, signature);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ } catch (InvalidDescriptor ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ Klass.Method parseMethod(Method m) {
+ AccessFlags flags = m.access_flags;
+ Descriptor d;
+ List<? extends Type> methodExceptions = null;
+ try {
+ ConstantPool cpool = classfile.constant_pool;
+ Klass.Method kmethod;
+ Signature_attribute sigAttr = (Signature_attribute) m.attributes.get(Attribute.Signature);
+ if (sigAttr == null) {
+ d = m.descriptor;
+ Set<Klass> types = parseDescriptor(d);
+
+ kmethod = toKlassMethod(m, d);
+ addMethodTypes(types, kmethod, flags);
+ } else {
+ Type.MethodType methodType;
+ Signature methodSig = sigAttr.getParsedSignature();
+ d = methodSig;
+ try {
+ kmethod = toKlassMethod(m, d);
+ methodType = (Type.MethodType) methodSig.getType(cpool);
+ addMethodTypes(getKlass(methodType.returnType), kmethod, flags);
+ if (methodType.paramTypes != null) {
+ for (Type t : methodType.paramTypes) {
+ addMethodTypes(getKlass(t), kmethod, flags);
+ }
+ }
+ if (methodType.typeParamTypes != null) {
+ for (Type t : methodType.typeParamTypes) {
+ addMethodTypes(getKlass(t), kmethod, flags);
+ }
+ }
+
+ methodExceptions = methodType.throwsTypes;
+ if (methodExceptions != null) {
+ if (methodExceptions.size() == 0) {
+ methodExceptions = null;
+ } else {
+ for (Type t : methodExceptions) {
+ addCheckedExceptionTypes(getKlass(t), kmethod, flags);
+ }
+ }
+ }
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ Attribute e_attr = m.attributes.get(Attribute.Exceptions);
+ if (e_attr != null && methodExceptions == null) {
+ // if there are generic exceptions, there must be erased exceptions
+ if (e_attr instanceof Exceptions_attribute) {
+ Exceptions_attribute exceptions = (Exceptions_attribute) e_attr;
+ for (int i = 0; i < exceptions.number_of_exceptions; i++) {
+ String classname = checkClassName(exceptions.getException(i, classfile.constant_pool));
+ if (classname.length() > 0 && buildDeps) {
+ Klass to = Klass.getKlass(classname);
+ ResolutionInfo resInfo = ResolutionInfo.resolvedCheckedException(this_klass, to, kmethod);
+ resInfo.setPublicAccess(flags.is(ACC_PUBLIC));
+
+ this_klass.addDep(to, resInfo);
+ to.addReferrer(this_klass, resInfo);
+ }
+ }
+ } else {
+ throw new RuntimeException("Invalid attribute: " + e_attr);
+ }
+ }
+
+ Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);
+ if (c_attr != null) {
+ codeAttributeParser.parse(c_attr, kmethod);
+ }
+ kmethod.isAbstract = classfile.access_flags.is(ACC_ABSTRACT);
+ kmethod.setCodeLength(m.byteLength());
+
+ // parse annotation attributes
+ annotationParser.parseAttributes(m.attributes, kmethod);
+ return kmethod;
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private void addFieldTypes(Set<Klass> types, String info, AccessFlags flags) {
+ if (types.isEmpty() || !buildDeps) {
+ return;
+ }
+
+ for (Klass to : types) {
+ ResolutionInfo resInfo = ResolutionInfo.resolvedField(this_klass, to, info);
+ resInfo.setPublicAccess(flags.is(ACC_PUBLIC));
+
+ this_klass.addDep(to, resInfo);
+ to.addReferrer(this_klass, resInfo);
+ }
+ }
+
+ private void addReferencedTypes(Method m, Descriptor d, AccessFlags flags) {
+ Set<Klass> types = parseDescriptor(d);
+
+ Klass.Method method = toKlassMethod(m, d);
+ addMethodTypes(types, method, flags);
+ }
+
+ private void addMethodTypes(Set<Klass> types, Klass.Method method, AccessFlags flags) {
+ if (types.isEmpty() || !buildDeps) {
+ return;
+ }
+ for (Klass to : types) {
+ ResolutionInfo resInfo = ResolutionInfo.resolvedMethodSignature(this_klass, to, method);
+ resInfo.setPublicAccess(flags.is(ACC_PUBLIC));
+
+ this_klass.addDep(to, resInfo);
+ to.addReferrer(this_klass, resInfo);
+ }
+ }
+
+ private void addCheckedExceptionTypes(Set<Klass> types, Klass.Method method, AccessFlags flags) {
+ if (types.isEmpty() || !buildDeps) {
+ return;
+ }
+ for (Klass to : types) {
+ ResolutionInfo resInfo = ResolutionInfo.resolvedCheckedException(this_klass, to, method);
+ resInfo.setPublicAccess(flags.is(ACC_PUBLIC));
+
+ this_klass.addDep(to, resInfo);
+ to.addReferrer(this_klass, resInfo);
+ }
+ }
+
+ private Set<Klass> parseDescriptor(Descriptor d) {
+ Set<Klass> types = new TreeSet<Klass>();
+ try {
+ String desc = d.getValue(classfile.constant_pool);
+ int p = 0;
+ while (p < desc.length()) {
+ String type;
+ char ch;
+ switch (ch = desc.charAt(p++)) {
+ case '(':
+ case ')':
+ case '[':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ case 'V':
+ continue;
+ case 'L':
+ int sep = desc.indexOf(';', p);
+ if (sep == -1) {
+ throw new RuntimeException("Invalid descriptor: " + (p - 1) + " " + desc);
+ }
+ type = checkClassName(desc.substring(p, sep));
+ p = sep + 1;
+ break;
+ default:
+ throw new RuntimeException("Invalid descriptor: " + (p - 1) + " " + desc);
+ }
+
+ if (!type.isEmpty() && buildDeps) {
+ Klass to = Klass.getKlass(type);
+ types.add(to);
+
+ }
+ }
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ return types;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ClassPath.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.classanalyzer;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ *
+ * @author mchung
+ */
+public class ClassPath {
+
+ public class FileInfo {
+
+ File file;
+ JarFile jarfile;
+ int classCount;
+ long filesize;
+
+ FileInfo(File f) throws IOException {
+ this.file = f;
+ this.classCount = 0;
+ if (file.getName().endsWith(".jar")) {
+ this.filesize = file.length();
+ jarfile = new JarFile(f);
+ }
+ }
+
+ File getFile() {
+ return file;
+ }
+
+ JarFile getJarFile() {
+ return jarfile;
+ }
+
+ String getName() throws IOException {
+ return file.getCanonicalPath();
+ }
+ }
+ private List<FileInfo> fileList = new ArrayList<FileInfo>();
+ private static ClassPath instance = new ClassPath();
+
+ static List<FileInfo> getFileInfos() {
+ return instance.fileList;
+ }
+
+ static ClassPath setJDKHome(String jdkhome) throws IOException {
+ List<File> files = new ArrayList<File>();
+ File jre = new File(jdkhome, "jre");
+ File lib = new File(jdkhome, "lib");
+ if (jre.exists() && jre.isDirectory()) {
+ listFiles(new File(jre, "lib"), ".jar", files);
+ } else if (lib.exists() && lib.isDirectory()) {
+ // either a JRE or a jdk build image
+ listFiles(lib, ".jar", files);
+
+ File classes = new File(jdkhome, "classes");
+ if (classes.exists() && classes.isDirectory()) {
+ // jdk build outputdir
+ instance.add(classes);
+ }
+ } else {
+ throw new RuntimeException("\"" + jdkhome + "\" not a JDK home");
+ }
+
+ for (File f : files) {
+ instance.add(f);
+ }
+ return instance;
+ }
+
+ static ClassPath setClassPath(String path) throws IOException {
+ if (path.endsWith(".class")) {
+ // one class file
+ File f = new File(path);
+ if (!f.exists()) {
+ throw new RuntimeException("Classfile \"" + f + "\" doesn't exist");
+ }
+
+ instance.add(f);
+ } else {
+ List<File> jarFiles = new ArrayList<File>();
+ String[] locs = path.split(File.pathSeparator);
+ for (String p : locs) {
+ File f = new File(p);
+ if (!f.exists()) {
+ throw new RuntimeException("\"" + f + "\" doesn't exist");
+ }
+
+ if (f.isDirectory()) {
+ instance.add(f); // add the directory to look up .class files
+ listFiles(f, ".jar", jarFiles);
+ } else if (p.endsWith(".jar")) {
+ // jar files
+ jarFiles.add(f);
+ } else {
+ throw new RuntimeException("Invalid file \"" + f);
+ }
+ }
+ // add jarFiles if any
+ for (File f : jarFiles) {
+ instance.add(f);
+ }
+ }
+
+ return instance;
+ }
+
+ private void add(File f) throws IOException {
+ fileList.add(new FileInfo(f));
+ }
+
+ public static InputStream open(String pathname) throws IOException {
+ for (FileInfo fi : instance.fileList) {
+ if (fi.getName().endsWith(".jar")) {
+ String path = pathname.replace(File.separatorChar, '/');
+ JarEntry e = fi.jarfile.getJarEntry(path);
+ if (e != null) {
+ return fi.jarfile.getInputStream(e);
+ }
+ } else if (fi.getFile().isDirectory()) {
+ File f = new File(fi.getFile(), pathname);
+ if (f.exists()) {
+ return new FileInputStream(f);
+ }
+ } else if (fi.file.isFile()) {
+ if (fi.getName().endsWith(File.separator + pathname)) {
+ return new FileInputStream(fi.file);
+ }
+ }
+ }
+ return null;
+ }
+
+ static ClassFileParser parserForClass(String classname) throws IOException {
+ String pathname = classname.replace('.', File.separatorChar) + ".class";
+
+ ClassFileParser cfparser = null;
+ for (FileInfo fi : instance.fileList) {
+ if (fi.getName().endsWith(".class")) {
+ if (fi.getName().endsWith(File.separator + pathname)) {
+ cfparser = ClassFileParser.newParser(fi.getFile(), true);
+ break;
+ }
+ } else if (fi.getName().endsWith(".jar")) {
+ JarEntry e = fi.jarfile.getJarEntry(classname.replace('.', '/') + ".class");
+ if (e != null) {
+ cfparser = ClassFileParser.newParser(fi.jarfile.getInputStream(e), e.getSize(), true);
+ break;
+ }
+ } else if (fi.getFile().isDirectory()) {
+ File f = new File(fi.getFile(), pathname);
+ if (f.exists()) {
+ cfparser = ClassFileParser.newParser(f, true);
+ break;
+ }
+ }
+ }
+ return cfparser;
+ }
+
+ public static void parseAllClassFiles() throws IOException {
+ instance.parseFiles();
+ }
+
+ private void parseFiles() throws IOException {
+ Set<Klass> classes = new HashSet<Klass>();
+
+ int count = 0;
+ for (FileInfo fi : fileList) {
+ // filter out public generated classes (i.e. not public API)
+ // javax.management.remote.rmi._RMIConnectionImpl_Tie
+ // javax.management.remote.rmi._RMIServerImpl_Tie
+ if (fi.getName().endsWith(".class")) {
+ parseClass(fi);
+ } else if (fi.getName().endsWith(".jar")) {
+ Enumeration<JarEntry> entries = fi.jarfile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry e = entries.nextElement();
+ if (e.getName().endsWith(".class")) {
+ ClassFileParser cfparser = ClassFileParser.newParser(fi.jarfile.getInputStream(e), e.getSize(), true);
+ cfparser.parseDependency(false);
+ fi.classCount++;
+ } else if (!e.isDirectory() && ResourceFile.isResource(e.getName())) {
+ ResourceFile.addResource(e.getName(), fi.jarfile.getInputStream(e));
+ }
+ }
+ } else if (fi.getFile().isDirectory()) {
+ List<File> files = new ArrayList<File>();
+ listFiles(fi.getFile(), "", files);
+ for (File f : files) {
+ if (f.getName().endsWith(".class")) {
+ parseClass(fi, f);
+ } else if (!f.isDirectory() && ResourceFile.isResource(f.getCanonicalPath())) {
+ String pathname = f.getCanonicalPath();
+ String dir = fi.getName();
+ if (!pathname.startsWith(dir)) {
+ throw new RuntimeException("Incorrect pathname " + pathname);
+ }
+ String name = pathname.substring(dir.length() + 1, pathname.length());
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
+ try {
+ ResourceFile.addResource(name, in);
+ } finally {
+ in.close();
+ }
+ }
+ }
+ } else {
+ // should not reach here
+ throw new RuntimeException("Unexpected class path: " + fi.getFile());
+ }
+ }
+ }
+
+ private void parseClass(FileInfo fi) throws IOException {
+ parseClass(fi, fi.getFile());
+ }
+
+ private void parseClass(FileInfo fi, File f) throws IOException {
+ ClassFileParser cfparser = ClassFileParser.newParser(f, true);
+ cfparser.parseDependency(false);
+ fi.classCount++;
+ // need to update the filesize for this directory
+ fi.filesize += fi.getFile().length();
+
+ }
+
+ public static void listFiles(File path, String suffix, List<File> result) {
+ if (path.isDirectory()) {
+ File[] children = path.listFiles();
+ for (File c : children) {
+ listFiles(c, suffix, result);
+ }
+
+ } else {
+ if (suffix.isEmpty() || path.getName().endsWith(suffix)) {
+ result.add(path);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/CodeAttributeParser.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package com.sun.classanalyzer;
+
+import com.sun.classanalyzer.Klass.Method;
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.Instruction.*;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class CodeAttributeParser {
+ private final ClassFileParser cfparser;
+ private final ConstantPool cpool;
+ private final ConstantPoolParser constantPoolParser;
+
+
+ static final Map<String, Set<Method>> runtimeReferences =
+ new HashMap<String, Set<Method>>();
+
+
+ CodeAttributeParser(ClassFileParser parser) {
+ this.cfparser = parser;
+ this.cpool = cfparser.classfile.constant_pool;
+ this.constantPoolParser = cfparser.constantPoolParser;
+ }
+
+ static boolean parseCodeAttribute = false; // by default don't parse code attribute
+ static void setParseCodeAttribute(boolean newValue) {
+ parseCodeAttribute = newValue;
+ }
+
+ void parse(Code_attribute attr, Klass.Method method) {
+ if (!parseCodeAttribute) {
+ return;
+ }
+
+ for (Instruction instr : attr.getInstructions()) {
+ try {
+ instr.accept(instructionVisitor, method);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new RuntimeException("error at or after byte " + instr.getPC());
+ }
+
+ }
+
+ if (attr.exception_table_langth > 0) {
+ for (int i = 0; i <
+ attr.exception_table.length; i++) {
+ Code_attribute.Exception_data handler = attr.exception_table[i];
+ int catch_type = handler.catch_type;
+ if (catch_type > 0) {
+ addMethodReference(catch_type, method);
+ }
+
+ }
+ }
+
+ }
+
+
+ private void addMethodReference(int index, Klass.Method m) {
+ String method = constantPoolParser.getMethodName(index);
+
+ if (method != null &&
+ (method.equals("java.lang.Class.forName") ||
+ method.equals("java.lang.Class.loadClass") ||
+ method.startsWith("java.util.ServiceLoader.load") ||
+ method.equals("sun.misc.Service.providers"))) {
+ Set<Method> refs = runtimeReferences.get(method);
+ if (refs == null) {
+ refs = new TreeSet<Method>();
+ runtimeReferences.put(method, refs);
+ }
+ refs.add(m);
+ }
+ }
+
+ Instruction.KindVisitor<Void, Klass.Method> instructionVisitor =
+ new Instruction.KindVisitor<Void, Klass.Method>() {
+
+ public Void visitNoOperands(Instruction instr, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitArrayType(Instruction instr, TypeKind kind, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitBranch(Instruction instr, int offset, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitConstantPoolRef(Instruction instr, int index, Klass.Method m) {
+ addMethodReference(index, m);
+ return null;
+ }
+
+ public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Klass.Method m) {
+ addMethodReference(index, m);
+ return null;
+ }
+
+ public Void visitLocal(Instruction instr, int index, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitLocalAndValue(Instruction instr, int index, int value, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitValue(Instruction instr, int value, Klass.Method m) {
+ return null;
+ }
+
+ public Void visitUnknown(Instruction instr, Klass.Method m) {
+ return null;
+ }
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolAnalyzer.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.classanalyzer;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class ConstantPoolAnalyzer {
+ public static void main(String[] args) throws Exception {
+ String jdkhome = null;
+
+ // process arguments
+ int i = 0;
+ while (i < args.length) {
+ String arg = args[i++];
+ if (arg.equals("-jdkhome")) {
+ if (i < args.length) {
+ jdkhome = args[i++];
+ } else {
+ usage();
+ }
+ }
+ }
+ if (jdkhome == null) {
+ usage();
+ }
+ ClassPath.setJDKHome(jdkhome);
+ ClassPath.parseAllClassFiles();
+ }
+
+ private static void usage() {
+ System.out.println("Usage: ConstantPoolAnalyzer <options>");
+ System.out.println("Options: ");
+ System.out.println("\t-jdkhome <JDK home> where all jars will be parsed");
+ System.out.println("\t-cpath <classpath> where classes and jars will be parsed");
+ System.exit(-1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ConstantPoolParser.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.ConstantPool.*;
+import static com.sun.tools.classfile.ConstantPool.*;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class ConstantPoolParser {
+
+ private final ClassFileParser cfparser;
+ private final StringValueVisitor visitor;
+ private final ConstantPool cpool;
+
+ ConstantPoolParser(ClassFileParser parser) {
+ this.cfparser = parser;
+ this.cpool = cfparser.classfile.constant_pool;
+ this.visitor = new StringValueVisitor();
+ }
+
+ public String stringValue(CPInfo cpInfo) {
+ return visitor.visit(cpInfo);
+ }
+
+ public String stringValue(int constant_pool_index) {
+ try {
+ return stringValue(cpool.get(constant_pool_index));
+ } catch (ConstantPool.InvalidIndex e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void parseDependency() {
+ ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer, Void>() {
+
+ public Integer visitClass(CONSTANT_Class_info info, Void p) {
+ try {
+ String classname = cfparser.checkClassName(info.getName());
+ if (classname.isEmpty()) {
+ return 1;
+ }
+
+ Klass from = cfparser.this_klass;
+ Klass to = Klass.getKlass(classname);
+ ResolutionInfo resInfo = ResolutionInfo.resolvedConstantPool(from, to, info.name_index);
+
+ from.addDep(to, resInfo);
+ to.addReferrer(from, resInfo);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ return 1;
+ }
+
+ public Integer visitDouble(CONSTANT_Double_info info, Void p) {
+ // skip
+ return 2;
+ }
+
+ public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitFloat(CONSTANT_Float_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitInteger(CONSTANT_Integer_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitLong(CONSTANT_Long_info info, Void p) {
+ // skip
+ return 2;
+ }
+
+ public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitString(CONSTANT_String_info info, Void p) {
+ // skip
+ return 1;
+ }
+
+ public Integer visitUtf8(CONSTANT_Utf8_info info, Void p) {
+ // skip
+ return 1;
+ }
+ };
+ int cpx = 1;
+ while (cpx < cpool.size()) {
+ try {
+ CPInfo cpInfo = cpool.get(cpx);
+ cpx += cpInfo.accept(v, null);
+ } catch (ConstantPool.InvalidIndex ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ int getTag(int index) {
+ try {
+ return cpool.get(index).getTag();
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ String getDescriptor(int index) {
+ CPInfo cpInfo;
+ try {
+ cpInfo = cpool.get(index);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ int tag = cpInfo.getTag();
+ switch (tag) {
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ case CONSTANT_Fieldref:
+ // simplify references within this class
+ CPRefInfo ref = (CPRefInfo) cpInfo;
+ try {
+ return ref.getNameAndTypeInfo().getType();
+ } catch (ConstantPoolException ex) {
+ }
+ }
+ return stringValue(cpInfo);
+ }
+
+ String getMethodName(int index) {
+ try {
+ CPInfo cpInfo = cpool.get(index);
+ if (cpInfo.getTag() == CONSTANT_Methodref ||
+ cpInfo.getTag() == CONSTANT_InterfaceMethodref) {
+
+ // simplify references within this class
+ CPRefInfo ref = (CPRefInfo) cpInfo;
+ String classname;
+ if (ref.class_index == cfparser.classfile.this_class) {
+ classname = cfparser.this_klass.getClassName();
+ } else {
+ classname = cfparser.checkClassName(ref.getClassName()).replace('/', '.');
+ }
+ String methodname = ref.getNameAndTypeInfo().getName();
+ return classname + "." + methodname;
+ } else {
+ return null;
+ }
+ } catch (InvalidIndex ex) {
+ throw new RuntimeException(ex);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ }
+
+ class StringValueVisitor implements ConstantPool.Visitor<String, Void> {
+
+ public StringValueVisitor() {
+ }
+
+ public String visit(CPInfo info) {
+ return info.accept(this, null);
+ }
+
+ public String visitClass(CONSTANT_Class_info info, Void p) {
+ return getCheckedName(info);
+ }
+
+ String getCheckedName(CONSTANT_Class_info info) {
+ try {
+ return checkName(info.getName());
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String visitDouble(CONSTANT_Double_info info, Void p) {
+ return info.value + "d";
+ }
+
+ public String visitFieldref(CONSTANT_Fieldref_info info, Void p) {
+ return visitRef(info, p);
+ }
+
+ public String visitFloat(CONSTANT_Float_info info, Void p) {
+ return info.value + "f";
+ }
+
+ public String visitInteger(CONSTANT_Integer_info info, Void p) {
+ return String.valueOf(info.value);
+ }
+
+ public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
+ return visitRef(info, p);
+ }
+
+ public String visitLong(CONSTANT_Long_info info, Void p) {
+ return info.value + "l";
+ }
+
+ public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
+ return getCheckedName(info) + ":" + getType(info);
+ }
+
+ String getCheckedName(CONSTANT_NameAndType_info info) {
+ try {
+ return checkName(info.getName());
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ String getType(CONSTANT_NameAndType_info info) {
+ try {
+ return info.getType();
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
+ return visitRef(info, p);
+ }
+
+ public String visitString(CONSTANT_String_info info, Void p) {
+ try {
+ int string_index = info.string_index;
+ return cpool.getUTF8Info(string_index).accept(this, p);
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String visitUtf8(CONSTANT_Utf8_info info, Void p) {
+ String s = info.value;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\t':
+ sb.append('\\').append('t');
+ break;
+ case '\n':
+ sb.append('\\').append('n');
+ break;
+ case '\r':
+ sb.append('\\').append('r');
+ break;
+ case '\"':
+ sb.append('\\').append('\"');
+ break;
+ default:
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ String visitRef(CPRefInfo info, Void p) {
+ String cn = getCheckedClassName(info);
+ String nat;
+ try {
+ nat = info.getNameAndTypeInfo().accept(this, p);
+ } catch (ConstantPoolException e) {
+ nat = e.getMessage();
+ }
+ return cn + "." + nat;
+ }
+
+ String getCheckedClassName(CPRefInfo info) {
+ try {
+ return checkName(info.getClassName());
+ } catch (ConstantPoolException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ /* If name is a valid binary name, return it; otherwise quote it. */
+
+ private static String checkName(String name) {
+ if (name == null) {
+ return "null";
+ }
+
+ int len = name.length();
+ if (len == 0) {
+ return "\"\"";
+ }
+
+ int cc = '/';
+ int cp;
+ for (int k = 0; k < len; k += Character.charCount(cp)) {
+ cp = name.codePointAt(k);
+ if ((cc == '/' && !Character.isJavaIdentifierStart(cp)) || (cp != '/' && !Character.isJavaIdentifierPart(cp))) {
+ return "\"" + name + "\"";
+ }
+ cc = cp;
+ }
+ return name;
+ }
+
+ String tagName(int index) {
+ try {
+ int tag = cpool.get(index).getTag();
+ switch (tag) {
+ case CONSTANT_Utf8:
+ return "Utf8";
+ case CONSTANT_Integer:
+ return "int";
+ case CONSTANT_Float:
+ return "float";
+ case CONSTANT_Long:
+ return "long";
+ case CONSTANT_Double:
+ return "double";
+ case CONSTANT_Class:
+ return "class";
+ case CONSTANT_String:
+ return "String";
+ case CONSTANT_Fieldref:
+ return "Field";
+ case CONSTANT_Methodref:
+ return "Method";
+ case CONSTANT_InterfaceMethodref:
+ return "InterfaceMethod";
+ case CONSTANT_NameAndType:
+ return "NameAndType";
+ default:
+ return "(unknown tag)";
+ }
+ } catch (InvalidIndex e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/DependencyConfig.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+
+/**
+ * Config file specifying additional dependency
+ * Each line consists of:
+ * <tag> <classname> -> <value>
+ * where <tag> can be:
+ * @ClassForName and <value> is its dependency
+ * @Provider and <value> is the service name
+ * @Providers and <value> is the list of the service names
+ *
+ * @author Mandy Chung
+ */
+public class DependencyConfig {
+ private DependencyConfig() {
+ }
+
+ static void parse(List<String> configs) throws IOException {
+ for (String s : configs) {
+ parse(s);
+ }
+ }
+
+ private static void parse(String config) throws IOException {
+ // parse configuration file
+ FileInputStream in = new FileInputStream(config);
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ int lineNumber = 0;
+ String type = null;
+ while ((line = reader.readLine()) != null) {
+ lineNumber++;
+ line = line.trim();
+ if (line.length() == 0 || line.charAt(0) == '#') {
+ continue;
+ }
+ if (line.charAt(0) == '@') {
+ if (AnnotatedDependency.isValidType(line)) {
+ type = line;
+ continue;
+ } else {
+ throw new RuntimeException(config + ", line " +
+ lineNumber + ", invalid annotation type.");
+ }
+ }
+ String[] s = line.split("\\s+");
+ if (s.length < 3 || !s[1].equals("->")) {
+ throw new RuntimeException(config + ", line " +
+ lineNumber + ", is malformed");
+ }
+ String classname = s[0].trim();
+ String value = s[2].trim();
+
+ Klass k = Klass.findKlass(classname);
+ if (k == null) {
+ // System.out.println("Warning: " + classname + " cannot be found");
+ continue;
+ }
+ AnnotatedDependency dep = AnnotatedDependency.newAnnotatedDependency(type, value, k);
+ if (dep == null) {
+ throw new RuntimeException(config + ", line " +
+ lineNumber + ", is malformed. Fail to construct the dependency.");
+ }
+ }
+
+ } finally {
+ in.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/Klass.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package com.sun.classanalyzer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import com.sun.tools.classfile.AccessFlags;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class Klass implements Comparable<Klass> {
+ private final String classname;
+ private final String packagename;
+ private Module module;
+ private boolean isJavaLangObject;
+ private String[] paths;
+ private Map<String, Set<Method>> methods;
+ private AccessFlags accessFlags;
+ private long filesize;
+
+ private SortedMap<Klass, Set<ResolutionInfo>> deps;
+ private SortedMap<Klass, Set<ResolutionInfo>> referrers;
+ private List<AnnotatedDependency> annotatedDeps;
+ private Set<String> classForNameRefs;
+
+ private Klass(String classname) {
+ this.classname = classname;
+ this.paths = classname.replace('.', '/').split("/");
+ this.isJavaLangObject = classname.equals("java.lang.Object");
+ this.deps = new TreeMap<Klass, Set<ResolutionInfo>>();
+ this.referrers = new TreeMap<Klass, Set<ResolutionInfo>>();
+ this.methods = new HashMap<String, Set<Method>>();
+ this.annotatedDeps = new ArrayList<AnnotatedDependency>();
+ this.classForNameRefs = new TreeSet<String>();
+
+ int pos = classname.lastIndexOf('.');
+ this.packagename = (pos > 0) ? classname.substring(0, pos) : "<unnamed>";
+ }
+
+ String getBasename() {
+ return paths[paths.length - 1];
+ }
+
+ String getClassName() {
+ return classname;
+ }
+
+ String getPackageName() {
+ return packagename;
+ }
+
+ String getClassFilePathname() {
+ StringBuilder sb = new StringBuilder(paths[0]);
+ for (int i = 1; i < paths.length; i++) {
+ String p = paths[i];
+ sb.append(File.separator).append(p);
+ }
+ return sb.append(".class").toString();
+ }
+
+ boolean isPublic() {
+ return accessFlags == null || accessFlags.is(AccessFlags.ACC_PUBLIC);
+ }
+
+ Module getModule() {
+ return module;
+ }
+
+ void setModule(Module m) {
+ if (module != null) {
+ throw new RuntimeException("Module for " + this + " already set");
+ }
+ this.module = m;
+ }
+
+ Set<Klass> getReferencedClasses() {
+ return deps.keySet();
+ }
+
+ Set<Klass> getReferencingClasses() {
+ return referrers.keySet();
+ }
+
+ void setAccessFlags(int flags) {
+ this.accessFlags = new AccessFlags(flags);
+ }
+
+ void setFileSize(long size) {
+ this.filesize = size;
+ }
+
+ long getFileSize() {
+ return this.filesize;
+ }
+
+ boolean exists() {
+ return filesize > 0;
+ }
+
+ boolean skip(Klass k) {
+ // skip if either class is a root or same class
+ return k.isJavaLangObject || this == k || k.classname.equals(classname);
+ }
+
+ void addDep(Method callee, ResolutionInfo resInfo) {
+ addDep(callee.getKlass(), resInfo);
+ }
+
+ void addDep(Klass ref, ResolutionInfo ri) {
+ if (skip(ref)) {
+ return;
+ }
+ Set<ResolutionInfo> resInfos;
+ if (!deps.containsKey(ref)) {
+ resInfos = new TreeSet<ResolutionInfo>();
+ deps.put(ref, resInfos);
+ } else {
+ resInfos = deps.get(ref);
+ }
+ resInfos.add(ri);
+ }
+
+ void addReferrer(Method caller, ResolutionInfo resInfo) {
+ addReferrer(caller.getKlass(), resInfo);
+ }
+
+ void addReferrer(Klass k, ResolutionInfo ri) {
+ if (skip(k)) {
+ return;
+ }
+ Set<ResolutionInfo> resInfos;
+ if (!referrers.containsKey(k)) {
+ resInfos = new TreeSet<ResolutionInfo>();
+ referrers.put(k, resInfos);
+ } else {
+ resInfos = referrers.get(k);
+ }
+ resInfos.add(ri);
+ }
+
+ Method getMethod(String name) {
+ return getMethod(name, "");
+ }
+
+ Method getMethod(String name, String signature) {
+ Set<Method> set;
+ if (methods.containsKey(name)) {
+ set = methods.get(name);
+ } else {
+ set = new TreeSet<Method>();
+ methods.put(name, set);
+ }
+
+ for (Method m : set) {
+ if (m.getName().equals(name) && m.getSignature().equals(signature)) {
+ return m;
+ }
+ }
+ Method m = new Method(this, name, signature);
+ set.add(m);
+ return m;
+ }
+
+ @Override
+ public String toString() {
+ return classname;
+ }
+
+ @Override
+ public int compareTo(Klass o) {
+ return classname.compareTo(o.classname);
+ }
+
+ void addAnnotatedDep(AnnotatedDependency dep) {
+ annotatedDeps.add(dep);
+ }
+
+ void addClassForNameReference(String method) {
+ classForNameRefs.add(method);
+ }
+
+ List<AnnotatedDependency> getAnnotatedDeps() {
+ return annotatedDeps;
+ }
+
+ private static Map<String, Klass> classes = new TreeMap<String, Klass>();
+ static Set<Klass> getAllClasses() {
+ return new TreeSet<Klass>(classes.values());
+ }
+
+ static Klass findKlassFromPathname(String filename) {
+ String name = filename;
+ if (filename.endsWith(".class")) {
+ name = filename.substring(0, filename.length() - 6);
+ }
+
+ // trim ".class"
+ name = name.replace('/', '.');
+ for (Klass k : classes.values()) {
+ if (name.endsWith(k.getClassName())) {
+ return k;
+ }
+ }
+ return null;
+ }
+
+ static Klass findKlass(String classname) {
+ return classes.get(classname);
+ }
+
+ static Klass getKlass(String name) {
+ Klass k;
+ String classname = name.replace('/', '.');
+ if (classname.charAt(classname.length() - 1) == ';') {
+ classname = classname.substring(0, classname.length() - 1);
+ }
+ if (classes.containsKey(classname)) {
+ k = classes.get(classname);
+ } else {
+ k = new Klass(classname);
+ classes.put(classname, k);
+ }
+ return k;
+ }
+
+ public class Method implements Comparable<Method> {
+
+ private final Klass k;
+ private final String method;
+ private final String signature;
+ private long codeLength;
+ // non-primitive types only
+ private final List<Klass> argTypes;
+ private final Klass returnType;
+ boolean isAbstract = false;
+ boolean marked = false;
+
+ public Method(Klass k, String method, String signature) {
+ this(k, method, signature, null, null);
+ }
+
+ public Method(Klass k, String method, String signature, Klass returnType, List<Klass> argTypes) {
+ this.k = k;
+ this.method = method;
+ this.signature = signature;
+ this.argTypes = argTypes;
+ this.returnType = returnType;
+ this.codeLength = 0;
+ }
+
+ public Klass getKlass() {
+ return k;
+ }
+
+ public String getName() {
+ return method;
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ public Klass getReturnType() {
+ return returnType;
+ }
+
+ public List<Klass> argTypes() {
+ return argTypes;
+ }
+
+ public void setCodeLength(long len) {
+ this.codeLength = len;
+ }
+
+ public long getCodeLength() {
+ return codeLength;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Method) {
+ return compareTo((Method) o) == 0;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 71 * hash + (this.k != null ? this.k.hashCode() : 0);
+ hash = 71 * hash + (this.method != null ? this.method.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ if (signature.isEmpty()) {
+ return k.classname + "." + method;
+ } else {
+ return signature;
+ }
+ }
+
+ public String toHtmlString() {
+ return toString().replace("<", "<").replace(">", ">");
+ }
+
+ boolean isClinit() {
+ return method.equals("<clinit>");
+ }
+
+ public int compareTo(Method m) {
+ if (k == m.getKlass()) {
+ if (method.equals(m.method)) {
+ return signature.compareTo(m.signature);
+ } else {
+ return method.compareTo(m.method);
+ }
+ } else {
+ return k.compareTo(m.getKlass());
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/Module.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,693 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.classanalyzer;
+
+import com.sun.classanalyzer.AnnotatedDependency.OptionalDependency;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class Module implements Comparable<Module> {
+
+ private static Map<String, Module> modules = new LinkedHashMap<String, Module>();
+
+ public static Module addModule(ModuleConfig config) {
+ String name = config.module;
+ if (modules.containsKey(name)) {
+ throw new RuntimeException("module \"" + name + "\" already exists");
+ }
+
+ Module m = new Module(config);
+ modules.put(name, m);
+ return m;
+ }
+
+ public static Module findModule(String name) {
+ return modules.get(name);
+ }
+
+ static Collection<Module> getAllModules() {
+ return Collections.unmodifiableCollection(modules.values());
+ }
+ private final String name;
+ private final ModuleConfig config;
+ private final Set<Klass> classes;
+ private final Set<ResourceFile> resources;
+ private final Set<Reference> unresolved;
+ private final Set<Dependency> dependents;
+ private final Map<String, PackageInfo> packages;
+ private final Set<Module> members;
+ private Module group;
+ private boolean isBaseModule;
+
+ private Module(ModuleConfig config) {
+ this.name = config.module;
+ this.isBaseModule = config.isBase;
+ this.classes = new TreeSet<Klass>();
+ this.resources = new TreeSet<ResourceFile>();
+ this.config = config;
+ this.unresolved = new HashSet<Reference>();
+ this.dependents = new TreeSet<Dependency>();
+ this.packages = new TreeMap<String, PackageInfo>();
+ this.members = new TreeSet<Module>();
+ this.group = this; // initialize to itself
+ }
+
+ String name() {
+ return name;
+ }
+
+ Module group() {
+ return group;
+ }
+
+ boolean isBase() {
+ return isBaseModule;
+ }
+
+ Set<Module> members() {
+ return members;
+ }
+
+ boolean contains(Klass k) {
+ return k != null && classes.contains(k);
+ }
+
+ boolean isEmpty() {
+ return classes.isEmpty() && resources.isEmpty();
+ }
+
+ /**
+ * Returns an Iterable of Dependency, only one for each dependent
+ * module of the strongest dependency (i.e.
+ * hard static > hard dynamic > optional static > optional dynamic
+ */
+ Iterable<Dependency> dependents() {
+ Map<Module, Dependency> deps = new LinkedHashMap<Module, Dependency>();
+ for (Dependency dep : dependents) {
+ Dependency d = deps.get(dep.module);
+ if (d == null || dep.compareTo(d) > 0) {
+ deps.put(dep.module, dep);
+ }
+ }
+ return deps.values();
+ }
+
+ @Override
+ public int compareTo(Module o) {
+ if (o == null) {
+ return -1;
+ }
+ return name.compareTo(o.name);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ void addKlass(Klass k) {
+ classes.add(k);
+ k.setModule(this);
+
+ // update package statistics
+ String pkg = k.getPackageName();
+ PackageInfo pkginfo = packages.get(pkg);
+ if (pkginfo == null) {
+ pkginfo = new PackageInfo(pkg);
+ packages.put(pkg, pkginfo);
+ }
+ if (k.exists()) {
+ // only count the class that is parsed
+ pkginfo.add(k.getFileSize());
+ }
+ }
+
+ void addResource(ResourceFile res) {
+ resources.add(res);
+ res.setModule(this);
+ }
+
+ void processRootsAndReferences() {
+ // start with the root set
+ Deque<Klass> pending = new ArrayDeque<Klass>();
+ for (Klass k : Klass.getAllClasses()) {
+ if (k.getModule() != null) {
+ continue;
+ }
+ String classname = k.getClassName();
+ if (config.matchesRoot(classname) && !config.isExcluded(classname)) {
+ addKlass(k);
+ pending.add(k);
+ }
+ }
+
+ // follow all references
+ Klass k;
+ while ((k = pending.poll()) != null) {
+ if (!classes.contains(k)) {
+ addKlass(k);
+ }
+ for (Klass other : k.getReferencedClasses()) {
+ Module otherModule = other.getModule();
+ if (otherModule != null && otherModule != this) {
+ // this module is dependent on otherModule
+ addDependency(k, other);
+ continue;
+ }
+
+ if (!classes.contains(other)) {
+ if (config.isExcluded(other.getClassName())) {
+ // reference to an excluded class
+ unresolved.add(new Reference(k, other));
+ } else {
+ pending.add(other);
+ }
+ }
+ }
+ }
+
+ // add other matching classes that don't require dependency analysis
+ for (Klass c : Klass.getAllClasses()) {
+ if (c.getModule() == null) {
+ String classname = c.getClassName();
+ if (config.matchesIncludes(classname) && !config.isExcluded(classname)) {
+ addKlass(c);
+ // dependencies
+ for (Klass other : c.getReferencedClasses()) {
+ Module otherModule = other.getModule();
+ if (otherModule == null) {
+ unresolved.add(new Reference(c, other));
+ } else {
+ if (otherModule != this) {
+ // this module is dependent on otherModule
+ addDependency(c, other);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ // add other matching classes that don't require dependency analysis
+ for (ResourceFile res : ResourceFile.getAllResources()) {
+ if (res.getModule() == null) {
+ String name = res.getName();
+ if (config.matchesIncludes(name) && !config.isExcluded(name)) {
+ addResource(res);
+ }
+ }
+ }
+ }
+
+ void addDependency(Klass from, Klass to) {
+ Dependency dep = new Dependency(from, to);
+ dependents.add(dep);
+ }
+
+ void fixupDependencies() {
+ // update dependencies for classes that were allocated to modules after
+ // this module was processed.
+ for (Reference ref : unresolved) {
+ Module m = ref.referree().getModule();
+ if (m == null || m != this) {
+ addDependency(ref.referrer, ref.referree);
+ }
+ }
+
+ fixupAnnotatedDependencies();
+ }
+
+ private void fixupAnnotatedDependencies() {
+ // add dependencies that this klass may depend on due to the AnnotatedDependency
+ dependents.addAll(AnnotatedDependency.getDependencies(this));
+ }
+
+ boolean isModuleDependence(Klass k) {
+ Module m = k.getModule();
+ return m == null || (!classes.contains(k) && !m.isBase());
+ }
+
+ Module getModuleDependence(Klass k) {
+ if (isModuleDependence(k)) {
+ Module m = k.getModule();
+ if (group == this && m != null) {
+ // top-level module
+ return m.group;
+ } else {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ <P> void visit(Set<Module> visited, Visitor<P> visitor, P p) {
+ if (!visited.contains(this)) {
+ visited.add(this);
+ visitor.preVisit(this, p);
+ for (Module m : members) {
+ m.visit(visited, visitor, p);
+ visitor.postVisit(this, m, p);
+ }
+ } else {
+ throw new RuntimeException("Cycle detected: module " + this.name);
+ }
+ }
+
+ void addMember(Module m) {
+ // merge class list
+ for (Klass k : m.classes) {
+ classes.add(k);
+ }
+
+ // merge resource list
+ for (ResourceFile res : m.resources) {
+ resources.add(res);
+ }
+
+ // merge the package statistics
+ for (PackageInfo pinfo : m.getPackageInfos()) {
+ String packageName = pinfo.pkgName;
+ PackageInfo pkginfo = packages.get(packageName);
+ if (pkginfo == null) {
+ pkginfo = new PackageInfo(packageName);
+ packages.put(packageName, pkginfo);
+ }
+ pkginfo.add(pinfo);
+ }
+ }
+
+ static void buildModuleMembers() {
+ // set up module member relationship
+ for (Module m : modules.values()) {
+ m.group = m; // initialize to itself
+ for (String name : m.config.members()) {
+ Module member = modules.get(name);
+ if (member == null) {
+ throw new RuntimeException("module \"" + name + "\" doesn't exist");
+ }
+ m.members.add(member);
+ }
+ }
+
+ // set up the top-level module
+ Visitor<Module> groupSetter = new Visitor<Module>() {
+
+ public void preVisit(Module m, Module p) {
+ m.group = p;
+ if (p.isBaseModule) {
+ // all members are also base
+ m.isBaseModule = true;
+ }
+ }
+
+ public void postVisit(Module m, Module child, Module p) {
+ // nop - breadth-first search
+ }
+ };
+
+ // propagate the top-level module to all its members
+ for (Module p : modules.values()) {
+ for (Module m : p.members) {
+ if (m.group == m) {
+ m.visit(new TreeSet<Module>(), groupSetter, p);
+ }
+ }
+ }
+
+ Visitor<Module> mergeClassList = new Visitor<Module>() {
+
+ public void preVisit(Module m, Module p) {
+ // nop - depth-first search
+ }
+
+ public void postVisit(Module m, Module child, Module p) {
+ m.addMember(child);
+ }
+ };
+
+ Set<Module> visited = new TreeSet<Module>();
+ for (Module m : modules.values()) {
+ if (m.group() == m) {
+ if (m.members().size() > 0) {
+ // merge class list from all its members
+ m.visit(visited, mergeClassList, m);
+ }
+
+ // clear the dependencies before fixup
+ m.dependents.clear();
+
+ // fixup dependencies
+ for (Klass k : m.classes) {
+ for (Klass other : k.getReferencedClasses()) {
+ if (m.isModuleDependence(other)) {
+ // this module is dependent on otherModule
+ m.addDependency(k, other);
+ }
+ }
+ }
+
+ // add dependencies that this klass may depend on due to the AnnotatedDependency
+ m.fixupAnnotatedDependencies();
+ }
+ }
+ }
+
+ class PackageInfo implements Comparable {
+
+ final String pkgName;
+ int count;
+ long filesize;
+
+ PackageInfo(String name) {
+ this.pkgName = name;
+ this.count = 0;
+ this.filesize = 0;
+ }
+
+ void add(PackageInfo pkg) {
+ this.count += pkg.count;
+ this.filesize += pkg.filesize;
+ }
+
+ void add(long size) {
+ count++;
+ filesize += size;
+
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return pkgName.compareTo(((PackageInfo) o).pkgName);
+ }
+ }
+
+ Set<PackageInfo> getPackageInfos() {
+ return new TreeSet<PackageInfo>(packages.values());
+ }
+
+ void printSummaryTo(String output) throws IOException {
+ PrintWriter writer = new PrintWriter(output);
+ try {
+ long total = 0L;
+ int count = 0;
+ writer.format("%10s\t%10s\t%s\n", "Bytes", "Classes", "Package name");
+ for (String pkg : packages.keySet()) {
+ PackageInfo info = packages.get(pkg);
+ if (info.count > 0) {
+ writer.format("%10d\t%10d\t%s\n", info.filesize, info.count, pkg);
+ total += info.filesize;
+ count += info.count;
+ }
+ }
+
+ writer.format("\nTotal: %d bytes (uncompressed) %d classes\n", total, count);
+ } finally {
+ writer.close();
+ }
+
+ }
+
+ void printClassListTo(String output) throws IOException {
+ // no file created if the module doesn't have any class
+ if (classes.isEmpty()) {
+ return;
+ }
+
+ PrintWriter writer = new PrintWriter(output);
+ try {
+ for (Klass c : classes) {
+ if (c.exists()) {
+ writer.format("%s\n", c.getClassFilePathname());
+ } else {
+ trace("%s in module %s missing\n", c, this);
+ }
+ }
+
+ } finally {
+ writer.close();
+ }
+ }
+
+ void printResourceListTo(String output) throws IOException {
+ // no file created if the module doesn't have any resource file
+ if (resources.isEmpty()) {
+ return;
+ }
+
+ PrintWriter writer = new PrintWriter(output);
+ try {
+ for (ResourceFile res : resources) {
+ writer.format("%s\n", res.getPathname());
+ }
+ } finally {
+ writer.close();
+ }
+ }
+
+ void printDependenciesTo(String output, boolean showDynamic) throws IOException {
+ // no file created if the module doesn't have any class
+ if (classes.isEmpty()) {
+ return;
+ }
+
+ PrintWriter writer = new PrintWriter(output);
+ try {
+ // classes that this klass may depend on due to the AnnotatedDependency
+ Map<Reference, Set<AnnotatedDependency>> annotatedDeps = AnnotatedDependency.getReferences(this);
+
+ for (Klass klass : classes) {
+ Set<Klass> references = klass.getReferencedClasses();
+ for (Klass other : references) {
+ String classname = klass.getClassName();
+ boolean optional = OptionalDependency.isOptional(klass, other);
+ if (optional) {
+ classname = "[optional] " + classname;
+ }
+
+ Module m = getModuleDependence(other);
+ if (m != null || other.getModule() == null) {
+ writer.format("%-40s -> %s (%s)", classname, other, m);
+ Reference ref = new Reference(klass, other);
+ if (annotatedDeps.containsKey(ref)) {
+ for (AnnotatedDependency ad : annotatedDeps.get(ref)) {
+ writer.format(" %s", ad.getTag());
+ }
+ // printed; so remove the dependency from the annotated deps list
+ annotatedDeps.remove(ref);
+ }
+ writer.format("\n");
+ }
+ }
+ }
+
+
+ // print remaining dependencies specified in AnnotatedDependency list
+ if (annotatedDeps.size() > 0) {
+ for (Map.Entry<Reference, Set<AnnotatedDependency>> entry : annotatedDeps.entrySet()) {
+ Reference ref = entry.getKey();
+ Module m = getModuleDependence(ref.referree);
+ if (m != null || ref.referree.getModule() == null) {
+ String classname = ref.referrer.getClassName();
+ boolean optional = true;
+ boolean dynamic = true;
+ String tag = "";
+ for (AnnotatedDependency ad : entry.getValue()) {
+ if (optional && !ad.isOptional()) {
+ optional = false;
+ tag = ad.getTag();
+ }
+ if (!ad.isDynamic()) {
+ dynamic = false;
+ }
+ }
+ if (!showDynamic && optional && dynamic) {
+ continue;
+ }
+ if (optional) {
+ if (dynamic) {
+ classname = "[dynamic] " + classname;
+ } else {
+ classname = "[optional] " + classname;
+ }
+ }
+ writer.format("%-40s -> %s (%s) %s%n", classname, ref.referree, m, tag);
+ }
+ }
+ }
+
+ } finally {
+ writer.close();
+ }
+ }
+
+ static class Dependency implements Comparable<Dependency> {
+
+ final Module module;
+ final boolean optional;
+ final boolean dynamic;
+
+ Dependency(Klass from, Klass to) {
+ // static dependency
+ this.module = to.getModule() != null ? to.getModule().group() : null;
+ this.optional = OptionalDependency.isOptional(from, to);
+ this.dynamic = false;
+ }
+
+ Dependency(Module m, boolean optional, boolean dynamic) {
+ this.module = m != null ? m.group() : null;
+ this.optional = optional;
+ this.dynamic = dynamic;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Dependency)) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ Dependency d = (Dependency) obj;
+ if (this.module != d.module) {
+ return false;
+ } else {
+ return this.optional == d.optional && this.dynamic == d.dynamic;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 19 * hash + (this.module != null ? this.module.hashCode() : 0);
+ hash = 19 * hash + (this.optional ? 1 : 0);
+ hash = 19 * hash + (this.dynamic ? 1 : 0);
+ return hash;
+ }
+
+ @Override
+ public int compareTo(Dependency d) {
+ if (this.equals(d)) {
+ return 0;
+ }
+
+ // Hard static > hard dynamic > optional static > optional dynamic
+ if (this.module == d.module) {
+ if (this.optional == d.optional) {
+ return this.dynamic ? -1 : 1;
+ } else {
+ return this.optional ? -1 : 1;
+ }
+ } else if (this.module != null && d.module != null) {
+ return (this.module.compareTo(d.module));
+ } else {
+ return (this.module == null) ? -1 : 1;
+ }
+ }
+
+ @Override
+ public String toString() {
+ String s = module.name();
+ if (dynamic && optional) {
+ s += " (dynamic)";
+ } else if (optional) {
+ s += " (optional)";
+ }
+ return s;
+ }
+ }
+
+ static class Reference implements Comparable<Reference> {
+
+ private final Klass referrer, referree;
+
+ Reference(Klass referrer, Klass referree) {
+ this.referrer = referrer;
+ this.referree = referree;
+ }
+
+ Klass referrer() {
+ return referrer;
+ }
+
+ Klass referree() {
+ return referree;
+ }
+
+ @Override
+ public int hashCode() {
+ return referrer.hashCode() ^ referree.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Reference)) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ Reference r = (Reference) obj;
+ return (this.referrer.equals(r.referrer) &&
+ this.referree.equals(r.referree));
+ }
+
+ @Override
+ public int compareTo(Reference r) {
+ int ret = referrer.compareTo(r.referrer);
+ if (ret == 0) {
+ ret = referree.compareTo(r.referree);
+ }
+ return ret;
+ }
+ }
+
+ interface Visitor<P> {
+
+ public void preVisit(Module m, P param);
+
+ public void postVisit(Module m, Module child, P param);
+ }
+ private static boolean traceOn = System.getProperty("classanalyzer.debug") != null;
+
+ private static void trace(String format, Object... params) {
+ System.err.format(format, params);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ModuleConfig.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,562 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class ModuleConfig {
+
+ private static String baseModuleName = "base";
+ private final Set<String> roots;
+ private final Set<String> includes;
+ private final Filter filter;
+ private List<String> members;
+ final String module;
+ final boolean isBase;
+
+ private ModuleConfig(String name) throws IOException {
+ this.roots = new TreeSet<String>();
+ this.includes = new TreeSet<String>();
+ this.module = name;
+ this.isBase = name.equals(baseModuleName);
+ this.filter = new Filter(this);
+ }
+
+ List<String> members() {
+ if (members == null) {
+ members = new LinkedList<String>();
+
+ for (String s : includes) {
+ if (!s.contains("*") && Module.findModule(s) != null) {
+ // module member
+ members.add(s);
+ }
+ }
+ }
+ return members;
+ }
+
+ boolean matchesRoot(String name) {
+ for (String pattern : roots) {
+ if (matches(name, pattern)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean matchesIncludes(String name) {
+ for (String pattern : includes) {
+ if (matches(name, pattern)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isExcluded(String name) {
+ return filter.isExcluded(name);
+ }
+
+ boolean matchesPackage(String packageName, String pattern) {
+ int pos = pattern.lastIndexOf('.');
+ String pkg = pos > 0 ? pattern.substring(0, pos) : "<unnamed>";
+ return packageName.equals(pkg);
+ }
+
+
+ boolean matches(String name, String pattern) {
+ if (pattern.contains("**") && !pattern.endsWith("**")) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ String javaName = name;
+
+ boolean isResourceFile = name.indexOf('/') >= 0;
+ if (isResourceFile) {
+ // it's a resource file; convert the name as a java
+ javaName = name.replace('/', '.');
+ }
+ if (pattern.indexOf('/') < 0) {
+ // if the pattern doesn't contain '/
+ return matchesJavaName(javaName, pattern);
+ } else {
+ if (isResourceFile) {
+ // the pattern is for matching resource file
+ return matchesNameWithSlash(name, pattern);
+ } else {
+ return false;
+ }
+ }
+ }
+
+ boolean matchesJavaName(String name, String pattern) {
+ int pos = name.lastIndexOf('.');
+ String packageName = pos > 0 ? name.substring(0, pos) : "<unnamed>";
+ if (pattern.endsWith("**")) {
+ String p = pattern.substring(0, pattern.length() - 2);
+ return name.startsWith(p);
+ } else if (pattern.endsWith("*") && pattern.indexOf('*') == pattern.lastIndexOf('*')) {
+ if (matchesPackage(packageName, pattern)) {
+ // package name has to be exact match
+ String p = pattern.substring(0, pattern.length() - 1);
+ return name.startsWith(p);
+ } else {
+ return false;
+ }
+ } else if (pattern.contains("*")) {
+ String basename = pos > 0 ? name.substring(pos + 1, name.length()) : name;
+ pos = pattern.indexOf('*');
+ String prefix = pattern.substring(0, pos);
+ String suffix = pattern.substring(pos + 1, pattern.length());
+ if (name.startsWith(prefix) && matchesPackage(packageName, prefix)) {
+ // package name has to be exact match
+ if (suffix.contains("*")) {
+ return name.matches(convertToRegex(pattern));
+ } else {
+ return basename.endsWith(suffix);
+ }
+ } else {
+ // we don't support wildcard be used in the package name
+ return false;
+ }
+ } else {
+ // exact match or inner class
+ return name.equals(pattern) || name.startsWith(pattern + "$");
+ }
+ }
+
+ boolean matchesNameWithSlash(String name, String pattern) {
+ if (pattern.endsWith("**")) {
+ String p = pattern.substring(0, pattern.length() - 2);
+ return name.startsWith(p);
+ } else if (pattern.contains("*")) {
+ int pos = pattern.indexOf('*');
+ String prefix = pattern.substring(0, pos);
+ String suffix = pattern.substring(pos + 1, pattern.length());
+ String tail = name.substring(pos, name.length());
+
+ if (!name.startsWith(prefix)) {
+ // prefix has to exact match
+ return false;
+ }
+
+ if (pattern.indexOf('*') == pattern.lastIndexOf('*')) {
+ // exact match prefix with no '/' in the tail string
+ String wildcard = tail.substring(0, tail.length() - suffix.length());
+ return tail.indexOf('/') < 0 && tail.endsWith(suffix);
+ }
+
+ if (suffix.contains("*")) {
+ return matchesNameWithSlash(tail, suffix);
+ } else {
+ // tail ends with the suffix while no '/' in the wildcard matched string
+ String any = tail.substring(0, tail.length() - suffix.length());
+ return tail.endsWith(suffix) && any.indexOf('/') < 0;
+ }
+ } else {
+ // exact match
+ return name.equals(pattern);
+ }
+ }
+
+ private String convertToRegex(String pattern) {
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
+ int index = 0;
+ int plen = pattern.length();
+ while (i < plen) {
+ char p = pattern.charAt(i);
+ if (p == '*') {
+ sb.append("(").append(pattern.substring(index, i)).append(")");
+ if (i + 1 < plen && pattern.charAt(i + 1) == '*') {
+ sb.append(".*");
+ index = i + 2;
+ } else {
+ sb.append("[^\\.]*");
+ index = i + 1;
+ }
+ }
+ i++;
+ }
+ if (index < plen) {
+ sb.append("(").append(pattern.substring(index, plen)).append(")");
+ }
+ return sb.toString();
+ }
+
+ static class Filter {
+
+ final ModuleConfig config;
+ final Set<String> exclude = new TreeSet<String>();
+ final Set<String> allow = new TreeSet<String>();
+
+ Filter(ModuleConfig config) {
+ this.config = config;
+ }
+
+ Filter exclude(String pattern) {
+ exclude.add(pattern);
+ return this;
+ }
+
+ Filter allow(String pattern) {
+ allow.add(pattern);
+ return this;
+ }
+
+ String allowedBy(String name) {
+ String allowedBy = null;
+ for (String pattern : allow) {
+ if (config.matches(name, pattern)) {
+ if (name.equals(pattern)) {
+ return pattern; // exact match
+ }
+ if (allowedBy == null) {
+ allowedBy = pattern;
+ } else {
+ if (pattern.length() > allowedBy.length()) {
+ allowedBy = pattern;
+ }
+ }
+ }
+ }
+ return allowedBy;
+ }
+
+ String excludedBy(String name) {
+ String allowedBy = allowedBy(name);
+ String excludedBy = null;
+
+ if (allowedBy != null && name.equals(allowedBy)) {
+ return null; // exact match
+ }
+ for (String pattern : exclude) {
+ if (config.matches(name, pattern)) {
+ // not matched by allowed rule or exact match
+ if (allowedBy == null || name.equals(pattern)) {
+ return pattern;
+ }
+ if (excludedBy == null) {
+ excludedBy = pattern;
+ } else {
+ if (pattern.length() > excludedBy.length()) {
+ excludedBy = pattern;
+ }
+ }
+ }
+ }
+ return excludedBy;
+ }
+
+ boolean isExcluded(String name) {
+ String allowedBy = allowedBy(name);
+ String excludedBy = excludedBy(name);
+
+ if (excludedBy == null) {
+ return false;
+ }
+ // not matched by allowed rule or exact match
+ if (allowedBy == null || name.equals(excludedBy)) {
+ return true;
+ }
+
+ if (allowedBy == null) {
+ return true;
+ }
+ if (allowedBy != null &&
+ excludedBy.length() > allowedBy.length()) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private static String trimComment(String line) {
+ StringBuilder sb = new StringBuilder();
+
+ int pos = 0;
+ while (pos >= 0 && pos < line.length()) {
+ int c1 = line.indexOf("//", pos);
+ if (c1 > 0 && !Character.isWhitespace(line.charAt(c1-1))) {
+ // not a comment
+ c1 = -1;
+ }
+
+ int c2 = line.indexOf("/*", pos);
+ if (c2 > 0 && !Character.isWhitespace(line.charAt(c2-1))) {
+ // not a comment
+ c2 = -1;
+ }
+
+ int c = line.length();
+ int n = line.length();
+ if (c1 >= 0 || c2 >= 0) {
+ if (c1 >= 0) {
+ c = c1;
+ }
+ if (c2 >= 0 && c2 < c) {
+ c = c2;
+ }
+ int c3 = line.indexOf("*/", c2 + 2);
+ if (c == c2 && c3 > c2) {
+ n = c3 + 2;
+ }
+ }
+ if (c > 0) {
+ if (sb.length() > 0) {
+ // add a whitespace if multiple comments on one line
+ sb.append(" ");
+ }
+ sb.append(line.substring(pos, c));
+ }
+ pos = n;
+ }
+ return sb.toString();
+ }
+
+ private static boolean beginBlockComment(String line) {
+ int pos = 0;
+ while (pos >= 0 && pos < line.length()) {
+ int c = line.indexOf("/*", pos);
+ if (c < 0) {
+ return false;
+ }
+
+ if (c > 0 && !Character.isWhitespace(line.charAt(c-1))) {
+ return false;
+ }
+
+ int c1 = line.indexOf("//", pos);
+ if (c1 >= 0 && c1 < c) {
+ return false;
+ }
+
+ int c2 = line.indexOf("*/", c + 2);
+ if (c2 < 0) {
+ return true;
+ }
+ pos = c + 2;
+ }
+ return false;
+ }
+
+ static void setBaseModule(String name) {
+ baseModuleName = name;
+ }
+ // TODO: we shall remove "-" from the regex once we define
+ // the naming convention for the module names without dashes
+ static final Pattern classNamePattern = Pattern.compile("[\\w\\.\\*_$-/]+");
+
+ static List<ModuleConfig> readConfigurationFile(String file) throws IOException {
+ List<ModuleConfig> result = new ArrayList<ModuleConfig>();
+ // parse configuration file
+ FileInputStream in = new FileInputStream(file);
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+
+ int lineNumber = 0;
+ boolean inRoots = false;
+ boolean inIncludes = false;
+ boolean inAllows = false;
+ boolean inExcludes = false;
+ boolean inBlockComment = false;
+ ModuleConfig config = null;
+
+ while ((line = reader.readLine()) != null) {
+ lineNumber++;
+
+ if (inBlockComment) {
+ int c = line.indexOf("*/");
+ if (c >= 0) {
+ line = line.substring(c + 2, line.length());
+ inBlockComment = false;
+ } else {
+ // skip lines until end of comment block
+ continue;
+ }
+ }
+
+ inBlockComment = beginBlockComment(line);
+
+ line = trimComment(line).trim();
+ // ignore empty lines
+ if (line.length() == 0) {
+ continue;
+ }
+
+ String values;
+ if (inRoots || inIncludes || inExcludes || inAllows) {
+ values = line;
+ } else {
+ String[] s = line.split("\\s+");
+ String keyword = s[0].trim();
+ if (keyword.equals("module")) {
+ if (s.length != 3 || !s[2].trim().equals("{")) {
+ throw new RuntimeException(file + ", line " +
+ lineNumber + ", is malformed");
+ }
+ config = new ModuleConfig(s[1].trim());
+ result.add(config);
+ // switch to a new module; so reset the flags
+ inRoots = false;
+ inIncludes = false;
+ inExcludes = false;
+ inAllows = false;
+ continue;
+ } else if (keyword.equals("roots")) {
+ inRoots = true;
+ } else if (keyword.equals("include")) {
+ inIncludes = true;
+ } else if (keyword.equals("exclude")) {
+ inExcludes = true;
+ } else if (keyword.equals("allow")) {
+ inAllows = true;
+ } else if (keyword.equals("}")) {
+ if (config == null || s.length != 1) {
+ throw new RuntimeException(file + ", line " +
+ lineNumber + ", is malformed");
+ } else {
+ // end of a module
+ config = null;
+ continue;
+ }
+ } else {
+ throw new RuntimeException(file + ", \"" + keyword + "\" on line " +
+ lineNumber + ", is not recognized");
+ }
+ values = line.substring(keyword.length(), line.length()).trim();
+ }
+
+ if (config == null) {
+ throw new RuntimeException(file + ", module not specified");
+ }
+
+ int len = values.length();
+ if (len == 0) {
+ continue;
+ }
+ char lastchar = values.charAt(len - 1);
+ if (lastchar != ',' && lastchar != ';') {
+ throw new RuntimeException(file + ", line " +
+ lineNumber + ", is malformed:" +
+ " ',' or ';' is missing.");
+ }
+
+ values = values.substring(0, len - 1);
+ // parse the values specified for a keyword specified
+ for (String s : values.split(",")) {
+ s = s.trim();
+ if (s.length() > 0) {
+ if (!classNamePattern.matcher(s).matches()) {
+ throw new RuntimeException(file + ", line " +
+ lineNumber + ", is malformed: \"" + s + "\"");
+ }
+ if (inRoots) {
+ config.roots.add(s);
+ } else if (inIncludes) {
+ config.includes.add(s);
+ } else if (inExcludes) {
+ config.filter.exclude(s);
+ } else if (inAllows) {
+ config.filter.allow(s);
+ }
+
+ }
+ }
+ if (lastchar == ';') {
+ inRoots = false;
+ inIncludes = false;
+ inExcludes = false;
+ inAllows = false;
+ }
+ }
+
+ if (inBlockComment) {
+ throw new RuntimeException(file + ", line " +
+ lineNumber + ", missing \"*/\" to end a block comment");
+ }
+ if (config != null) {
+ throw new RuntimeException(file + ", line " +
+ lineNumber + ", missing \"}\" to end module definition" +
+ " for \"" + config.module + "\"");
+ }
+
+ } finally {
+ in.close();
+ }
+
+ return result;
+ }
+
+ private String format(String keyword, Collection<String> values) {
+ if (values.size() == 0) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ String format = "%4s%-9s";
+ String spaces = String.format(format, "", "");
+ sb.append(String.format(format, "", keyword));
+ int count = 0;
+ for (String s : values) {
+ if (count > 0) {
+ sb.append(",\n").append(spaces);
+ } else if (count++ > 0) {
+ sb.append(", ");
+ }
+ sb.append(s);
+ }
+ if (count > 0) {
+ sb.append(";\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("module " + module).append(" {\n");
+ sb.append(format("include", includes));
+ sb.append(format("root", roots));
+ sb.append(format("allow", filter.allow));
+ sb.append(format("exclude", filter.exclude));
+ sb.append("}\n");
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ResolutionInfo.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package com.sun.classanalyzer;
+
+import com.sun.classanalyzer.Klass.Method;
+
+/**
+ *
+ * @author mchung
+ */
+public class ResolutionInfo implements Comparable<ResolutionInfo> {
+
+ enum Type {
+
+ REFLECTION("reflection", true),
+ NATIVE("native", true),
+ INTERFACE("interface", false),
+ SUPER("super", false),
+ EXPLICIT("explicit", false),
+ VERIFICATION("verification", false),
+ METHODTRACE("method trace", true),
+ CONSTANT_POOL("constant pool", true),
+ CHECKED_EXCEPTION("throws", true),
+ METHOD("method", true),
+ FIELD("field", true),
+ EXTENDS("extends", true),
+ IMPLEMENTS("implements", true),
+ NOINFO("No info", false);
+
+ private final String name;
+ private final boolean hasInfo;
+
+ private Type(String name, boolean hasInfo) {
+ this.name = name;
+ this.hasInfo = hasInfo;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean hasInfo() {
+ return hasInfo;
+ }
+
+ public static Type getType(String s) {
+ if (s.isEmpty()) {
+ return NOINFO;
+ }
+ for (Type t : values()) {
+ if (s.equals(t.name)) {
+ return t;
+ }
+ }
+ // Need to fix the VM output to add "native"
+ // throw new IllegalArgumentException("Invalid ResolutionInfo.type \"" + s + "\"");
+ System.out.println("WARNING: Invalid ResolutionInfo.type \"" + s + "\"");
+ return null;
+ }
+ }
+ final Klass fromClass;
+ final Method method;
+ final Klass toClass;
+ final int linenumber;
+ final Type type;
+ final String info;
+ private boolean isPublic = false;
+
+ private ResolutionInfo(Klass from, Klass to, int linenumber, Type type, String info) {
+ this.fromClass = from;
+ this.method = null;
+ this.toClass = to;
+ this.linenumber = linenumber;
+ this.type = type;
+ this.info = info;
+ }
+
+ private ResolutionInfo(Klass from, Method m, Klass to, int linenumber, Type type) {
+ this.fromClass = from;
+ this.method = m;
+ this.toClass = to;
+ this.linenumber = linenumber;
+ this.type = type;
+ this.info = m.toString();
+ }
+
+ public boolean isPublic() {
+ return isPublic;
+ }
+
+ public void setPublicAccess(boolean value) {
+ isPublic = value;
+ }
+ static ResolutionInfo resolved(Klass from, Klass to) {
+ return new ResolutionInfo(from, to, 0, Type.NOINFO, "");
+ }
+
+ static ResolutionInfo resolved(Klass from, Klass to, int linenumber) {
+ return new ResolutionInfo(from, to, linenumber, Type.NOINFO, "");
+ }
+
+ static ResolutionInfo resolved(Klass from, Klass to, int linenumber, String reason) {
+ String[] ss = reason.split("\\s+");
+ Type type;
+ String info;
+ if (linenumber == -1) {
+ type = Type.NATIVE;
+ info = ss[0]; // native method name
+ } else {
+ info = ss.length == 2 ? ss[1] : "";
+ type = Type.getType(ss[0]);
+ if (type == null) {
+ if (reason.isEmpty()) {
+ throw new IllegalArgumentException("Invalid type: " + reason + " (" + ss[0] + ")" + ss.length);
+ }
+ // assume it's native
+ type = Type.NATIVE;
+ info = reason.isEmpty() ? ss[0] : reason;
+ }
+ }
+
+ return new ResolutionInfo(from, to, linenumber, type, info);
+ }
+
+ static ResolutionInfo resolved(Klass from, Klass to, Method callee) {
+ return new ResolutionInfo(from, callee, to, 0, Type.METHODTRACE);
+ }
+
+ static ResolutionInfo resolvedConstantPool(Klass from, Klass to, int index) {
+ return new ResolutionInfo(from, to, 0, Type.CONSTANT_POOL, "#" + index);
+ }
+
+ static ResolutionInfo resolvedField(Klass from, Klass to, String fieldname) {
+ return new ResolutionInfo(from, to, 0, Type.FIELD, fieldname);
+ }
+
+ static ResolutionInfo resolvedMethodSignature(Klass from, Klass to, Method m) {
+ return new ResolutionInfo(from, m, to, 0, Type.METHOD);
+ }
+
+ static ResolutionInfo resolvedCheckedException(Klass from, Klass to, Method m) {
+ return new ResolutionInfo(from, m, to, 0, Type.CHECKED_EXCEPTION);
+ }
+
+ static ResolutionInfo resolvedExtends(Klass from, Klass to) {
+ String info = from.getClassName() + " implements " + to.getClassName();
+ return new ResolutionInfo(from, to, 0, Type.EXTENDS, info);
+ }
+
+ static ResolutionInfo resolvedImplements(Klass from, Klass to) {
+ String info = from.getClassName() + " implements " + to.getClassName();
+ return new ResolutionInfo(from, to, 0, Type.IMPLEMENTS, info);
+ }
+
+ @Override
+ public int compareTo(ResolutionInfo ri) {
+ if (this.fromClass == ri.fromClass &&
+ this.toClass == ri.toClass &&
+ this.linenumber == ri.linenumber &&
+ this.type == ri.type &&
+ this.info.equals(ri.info)) {
+ return 0;
+ } else if (this.fromClass == ri.fromClass) {
+ if (this.linenumber > ri.linenumber) {
+ return 1;
+ } else if (this.linenumber < ri.linenumber) {
+ return -1;
+ } else if (this.type != ri.type) {
+ return this.type.getName().compareTo(ri.type.getName());
+ } else if (this.toClass != ri.toClass) {
+ return this.toClass.compareTo(ri.toClass);
+ } else {
+ return this.info.compareTo(ri.info);
+ }
+ } else {
+ return this.fromClass.compareTo(ri.fromClass);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ResourceFile.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ *
+ * @author Mandy Chung
+ */
+public class ResourceFile implements Comparable<ResourceFile> {
+
+ private final String pathname;
+ private Module module;
+
+ ResourceFile(String pathname) {
+ this.pathname = pathname.replace(File.separatorChar, '/');
+ }
+
+ Module getModule() {
+ return module;
+ }
+
+ void setModule(Module m) {
+ if (module != null) {
+ throw new RuntimeException("Module for " + this + " already set");
+ }
+ this.module = m;
+ }
+
+ String getName() {
+ return pathname;
+ }
+
+ String getPathname() {
+ return pathname;
+ }
+
+ @Override
+ public String toString() {
+ return pathname;
+ }
+
+ @Override
+ public int compareTo(ResourceFile o) {
+ return pathname.compareTo(o.pathname);
+ }
+ static Set<ResourceFile> resources = new TreeSet<ResourceFile>();
+
+ static boolean isResource(String pathname) {
+ String name = pathname.replace(File.separatorChar, '/');
+
+ if (name.endsWith("META-INF/MANIFEST.MF")) {
+ return false;
+ }
+ if (name.contains("META-INF/JCE_RSA.")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static void addResource(String name, InputStream in) {
+ ResourceFile res;
+ name = name.replace(File.separatorChar, '/');
+ if (name.startsWith("META-INF/services")) {
+ res = new ServiceProviderConfigFile(name, in);
+ } else {
+ res = new ResourceFile(name);
+ }
+ resources.add(res);
+ }
+
+ static Set<ResourceFile> getAllResources() {
+ return Collections.unmodifiableSet(resources);
+ }
+
+ static class ServiceProviderConfigFile extends ResourceFile {
+
+ private final List<String> providers = new ArrayList<String>();
+ private final String service;
+ ServiceProviderConfigFile(String pathname, InputStream in) {
+ super(pathname);
+ readServiceConfiguration(in, providers);
+ this.service = pathname.substring("META-INF/services".length() + 1, pathname.length());
+ }
+
+ @Override
+ String getName() {
+ if (providers.isEmpty()) {
+ return service;
+ } else {
+ // just use the first one for matching
+ return providers.get(0);
+ }
+ }
+
+ @SuppressWarnings("empty-statement")
+ void readServiceConfiguration(InputStream in, List<String> names) {
+ BufferedReader br = null;
+ try {
+ if (in != null) {
+ // Properties doesn't perserve the order of the input file
+ br = new BufferedReader(new InputStreamReader(in, "utf-8"));
+ int lc = 1;
+ while ((lc = parseLine(br, lc, names)) >= 0);
+ }
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+ }
+
+ // Parse a single line from the given configuration file, adding the name
+ // on the line to the names list.
+ //
+ private int parseLine(BufferedReader r, int lc, List<String> names) throws IOException {
+ String ln = r.readLine();
+ if (ln == null) {
+ return -1;
+ }
+ int ci = ln.indexOf('#');
+ if (ci >= 0) {
+ ln = ln.substring(0, ci);
+ }
+ ln = ln.trim();
+ int n = ln.length();
+ if (n != 0) {
+ if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
+ throw new RuntimeException("Illegal configuration-file syntax");
+ }
+ int cp = ln.codePointAt(0);
+ if (!Character.isJavaIdentifierStart(cp)) {
+ throw new RuntimeException("Illegal provider-class name: " + ln);
+ }
+ for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+ cp = ln.codePointAt(i);
+ if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
+ throw new RuntimeException("Illegal provider-class name: " + ln);
+ }
+ }
+ if (!names.contains(ln)) {
+ names.add(ln);
+ }
+ }
+ return lc + 1;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/modules/tools/src/com/sun/classanalyzer/ShowDeps.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.classanalyzer;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * A simple tool to print out the static dependencies for a given set of JAR,
+ * class files, or combinations of. The tools supports an -ignore option to
+ * ignore references to classes listed in the file (including .classlists
+ * created by the ClassAnalyzer tool).
+ */
+
+public class ShowDeps {
+
+ static void usage() {
+ System.out.println("java ShowDeps [-ignore <classlist>] file...");
+ System.out.println(" where <file> is a class or JAR file, or a directory");
+ System.out.println();
+ System.out.println("Example usages:");
+ System.out.println(" java ShowDeps Foo.jar");
+ System.out.println(" java ShowDeps -ignore base.classlist Foo.jar");
+ System.out.println(" java ShowDeps -ignore base.classlist -ignore " +
+ "jaxp-parsers.classlist <dir>");
+ System.exit(-1);
+ }
+
+ public static void main(String[] args) throws IOException {
+ // process -ignore options
+ int argi = 0;
+ Set<String> ignore = new HashSet<String>();
+ while (argi < args.length && args[argi].equals("-ignore")) {
+ argi++;
+ Scanner s = new Scanner(new File(args[argi++]));
+ try {
+ while (s.hasNextLine()) {
+ String line = s.nextLine();
+ if (!line.endsWith(".class"))
+ continue;
+ int len = line.length();
+ // convert to class names
+ String clazz = line.replace('\\', '.').replace('/', '.')
+ .substring(0, len-6);
+ ignore.add(clazz);
+ }
+ } finally {
+ s.close();
+ }
+ }
+
+ if (argi >= args.length)
+ usage();
+
+ // parse all classes
+ while (argi < args.length)
+ ClassPath.setClassPath(args[argi++]);
+ ClassPath.parseAllClassFiles();
+
+ // find the classes that don't exist
+ Set<Klass> unresolved = new TreeSet<Klass>();
+ for (Klass k : Klass.getAllClasses()) {
+ if (k.getFileSize() == 0)
+ unresolved.add(k);
+ }
+
+ // print references to classes that don't exist
+ for (Klass k: Klass.getAllClasses()) {
+ for (Klass other : k.getReferencedClasses()) {
+ if (unresolved.contains(other)) {
+ String name = other.toString();
+ if (!ignore.contains(name)) {
+ System.out.format("%s -> %s\n", k, other);
+ }
+ }
+ }
+ }
+ }
+}
--- a/jdk/src/share/bin/java.c Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/bin/java.c Wed Jul 05 17:04:56 2017 +0200
@@ -93,6 +93,7 @@
* Prototypes for functions internal to launcher.
*/
static void SetClassPath(const char *s);
+static void SetModulesBootClassPath(const char *s);
static void SelectVersion(int argc, char **argv, char **main_class);
static jboolean ParseArguments(int *pargc, char ***pargv, char **pjarfile,
char **pclassname, int *pret, const char *jvmpath);
@@ -277,6 +278,9 @@
return(ret);
}
+ /* Set bootclasspath for modules */
+ SetModulesBootClassPath(jrepath);
+
/* Override class path if -jar flag was specified */
if (jarfile != 0) {
SetClassPath(jarfile);
@@ -694,6 +698,44 @@
}
/*
+ * Set the bootclasspath for modules.
+ * A temporary workaround until jigsaw is integrated into JDK 7.
+ */
+static void
+SetModulesBootClassPath(const char *jrepath)
+{
+ char *def, *s;
+ char pathname[MAXPATHLEN];
+ const char separator[] = { FILE_SEPARATOR, '\0' };
+ const char *orig = jrepath;
+ static const char format[] = "-Xbootclasspath/p:%s";
+ struct stat statbuf;
+
+ /* return if jre/lib/rt.jar exists */
+ sprintf(pathname, "%s%slib%srt.jar", jrepath, separator, separator);
+ if (stat(pathname, &statbuf) == 0) {
+ return;
+ }
+
+ /* return if jre/classes exists */
+ sprintf(pathname, "%s%sclasses", jrepath, separator);
+ if (stat(pathname, &statbuf) == 0) {
+ return;
+ }
+
+ /* modularized jre */
+ sprintf(pathname, "%s%slib%s*", jrepath, separator, separator);
+ s = (char *) JLI_WildcardExpandClasspath(pathname);
+ def = JLI_MemAlloc(sizeof(format)
+ - 2 /* strlen("%s") */
+ + JLI_StrLen(s));
+ sprintf(def, format, s);
+ AddOption(def, NULL);
+ if (s != orig)
+ JLI_MemFree((char *) s);
+}
+
+/*
* The SelectVersion() routine ensures that an appropriate version of
* the JRE is running. The specification for the appropriate version
* is obtained from either the manifest of a jar file (preferred) or
--- a/jdk/src/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java Wed Jul 05 17:04:56 2017 +0200
@@ -33,10 +33,10 @@
import java.util.Hashtable;
import java.util.Properties;
import java.util.Enumeration;
-import java.applet.Applet;
import org.omg.CORBA.ORB;
+import javax.naming.Context;
import javax.naming.ConfigurationException;
/**
@@ -191,16 +191,48 @@
}
// Get Applet from environment
- Applet applet = null;
if (env != null) {
- applet = (Applet) env.get("java.naming.applet");
+ Object applet = env.get(Context.APPLET);
+ if (applet != null) {
+ // Create ORBs for an applet
+ return initAppletORB(applet, orbProp);
+ }
}
- // Create ORBs using applet and orbProp
- if (applet != null) {
- return ORB.init(applet, orbProp);
- } else {
- return ORB.init(new String[0], orbProp);
+ // Create ORBs using orbProp for a standalone application
+ return ORB.init(new String[0], orbProp);
+ }
+
+ /**
+ * This method returns a new ORB instance for the given applet
+ * without creating a static dependency on java.applet.
+ */
+ private static ORB initAppletORB(Object applet, Properties orbProp) {
+ try {
+ Class<?> appletClass = Class.forName("java.applet.Applet", true, null);
+ if (!appletClass.isInstance(applet)) {
+ throw new ClassCastException(applet.getClass().getName());
+ }
+
+ // invoke the static method ORB.init(applet, orbProp);
+ Method method = ORB.class.getMethod("init", appletClass, Properties.class);
+ return (ORB) method.invoke(null, applet, orbProp);
+ } catch (ClassNotFoundException e) {
+ // java.applet.Applet doesn't exist and the applet parameter is
+ // non-null; so throw CCE
+ throw new ClassCastException(applet.getClass().getName());
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ }
+ throw new AssertionError(e);
+ } catch (IllegalAccessException iae) {
+ throw new AssertionError(iae);
}
}
--- a/jdk/src/share/classes/java/dyn/CallSite.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/CallSite.java Wed Jul 05 17:04:56 2017 +0200
@@ -26,6 +26,9 @@
package java.dyn;
import sun.dyn.util.BytecodeName;
+import sun.dyn.Access;
+import sun.dyn.CallSiteImpl;
+import sun.dyn.MethodHandleImpl;
/**
* An {@code invokedynamic} call site, as reified by the
@@ -52,15 +55,25 @@
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG
*/
-public class CallSite {
+public class CallSite
+ // Note: This is an implementation inheritance hack, and will be removed
+ // with a JVM change which moves the required hidden state onto this class.
+ extends CallSiteImpl
+{
+ private static final Access IMPL_TOKEN = Access.getToken();
+
+ /*
+
// Fields used only by the JVM. Do not use or change.
private Object vmmethod;
int callerMID, callerBCI; // supplied by the JVM
- MethodHandle target;
+ private MethodHandle target;
+
final Object caller; // usually a class
final String name;
final MethodType type;
+ */
/**
* Make a call site given the parameters from a call to the bootstrap method.
@@ -72,16 +85,21 @@
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
*/
public CallSite(Object caller, String name, MethodType type) {
- this.caller = caller;
- this.name = name;
- this.type = type;
+ super(IMPL_TOKEN, caller, name, type);
}
private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) {
site.callerMID = callerMID;
site.callerBCI = callerBCI;
- if (site.target == null)
- site.setTarget(site.initialTarget());
+ site.ensureTarget();
+ }
+ private void ensureTarget() {
+ // Note use of super, which accesses the field directly,
+ // without deferring to possible subclass overrides.
+ if (super.getTarget() == null) {
+ super.setTarget(this.initialTarget());
+ super.getTarget().type(); // provoke NPE if still null
+ }
}
/**
@@ -102,10 +120,11 @@
/**
* Report the current linkage state of the call site. (This is mutable.)
- * The value maybe null only if the call site is currently unlinked.
- * When a linked call site is invoked, the target method is used directly.
- * When an unlinked call site is invoked, its bootstrap method receives
- * the call, as if via {@link Linkage#bootstrapInvokeDynamic}.
+ * The value may not be null after the {@code CallSite} object is returned
+ * from the bootstrap method of the {@code invokedynamic} instruction.
+ * When an {@code invokedynamic} instruction is executed, the target method
+ * of its associated {@code call site} object is invoked directly,
+ * as if via {@link MethodHandle}{@code .invoke}.
* <p>
* The interactions of {@code getTarget} with memory are the same
* as of a read from an ordinary variable, such as an array element or a
@@ -118,7 +137,7 @@
* @see #setTarget
*/
public MethodHandle getTarget() {
- return target;
+ return super.getTarget();
}
/**
@@ -140,13 +159,13 @@
*/
public void setTarget(MethodHandle target) {
checkTarget(target);
- this.target = target;
+ super.setTarget(target);
}
protected void checkTarget(MethodHandle target) {
target.type(); // provoke NPE
if (!canSetTarget(target))
- throw new WrongMethodTypeException(String.valueOf(target));
+ throw new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type());
}
protected boolean canSetTarget(MethodHandle target) {
@@ -219,6 +238,10 @@
@Override
public String toString() {
- return "CallSite#"+hashCode()+"["+name+type+" => "+target+"]";
+ return "CallSite#"+hashCode()+"["+name+type+" => "+getTarget()+"]";
}
+
+ // Package-local constant:
+ static final MethodHandle GET_TARGET = MethodHandleImpl.getLookup(IMPL_TOKEN).
+ findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
}
--- a/jdk/src/share/classes/java/dyn/InvokeDynamic.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/InvokeDynamic.java Wed Jul 05 17:04:56 2017 +0200
@@ -45,6 +45,24 @@
* class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods.
* It may be viewed as a pure syntactic marker (an importable one) of static calls.
+ * <p>
+ * Here are some examples of usage:
+ * <p><blockquote><pre>
+ * Object x; String s; int i;
+ * x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
+ * s = InvokeDynamic.<String>hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
+ * InvokeDynamic.<void>cogito(); // cogito()V
+ * i = InvokeDynamic.<int>#"op:+"(2, 3); // "op:+"(II)I
+ * </pre></blockquote>
+ * Each of the above calls generates a single invokedynamic instruction
+ * with the name-and-type descriptors indicated in the comments.
+ * The argument types are taken directly from the actual arguments,
+ * while the return type is taken from the type parameter.
+ * (This type parameter may be a primtive, and it defaults to {@code Object}.)
+ * The final example uses a special syntax for uttering non-Java names.
+ * Any name legal to the JVM may be given between the double quotes.
+ * None of these calls is complete without a bootstrap method,
+ * which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG
*/
public final class InvokeDynamic {
--- a/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java Wed Jul 05 17:04:56 2017 +0200
@@ -52,4 +52,16 @@
public InvokeDynamicBootstrapError(String s) {
super(s);
}
+
+ /**
+ * Constructs a {@code InvokeDynamicBootstrapError} with the specified
+ * detail message and cause.
+ *
+ * @param s the detail message.
+ * @param cause the cause.
+ */
+ public InvokeDynamicBootstrapError(String s, Throwable cause) {
+ super(s);
+ this.initCause(cause);
+ }
}
--- a/jdk/src/share/classes/java/dyn/JavaMethodHandle.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/JavaMethodHandle.java Wed Jul 05 17:04:56 2017 +0200
@@ -25,6 +25,8 @@
package java.dyn;
+import sun.dyn.Access;
+
/**
* A Java method handle extends the basic method handle type with additional
* programmer defined methods and fields.
@@ -39,31 +41,105 @@
* of the entry point method handle, with the leading parameter type
* omitted.
* <p>
- * Here is an example of usage:
+ * Here is an example of usage, creating a hybrid object/functional datum:
* <p><blockquote><pre>
- * class Greeter extends JavaMethodHandle {
+ * class Greeter extends JavaMethodHandle {
+ * private String greeting = "hello";
+ * public void setGreeting(String s) { greeting = s; }
+ * public void run() { System.out.println(greeting+", "+greetee); }
+ * private final String greetee;
+ * Greeter(String greetee) {
+ * super(RUN); // alternatively, super("run")
+ * this.greetee = greetee;
+ * }
+ * // the entry point function is computed once:
+ * private static final MethodHandle RUN
+ * = MethodHandles.lookup().findVirtual(Greeter.class, "run",
+ * MethodType.make(void.class));
+ * }
+ * // class Main { public static void main(String... av) { ...
+ * Greeter greeter = new Greeter("world");
+ * greeter.run(); // prints "hello, world"
+ * // Statically typed method handle invocation (most direct):
+ * MethodHandle mh = greeter;
+ * mh.<void>invoke(); // also prints "hello, world"
+ * // Dynamically typed method handle invocation:
+ * MethodHandles.invoke(greeter); // also prints "hello, world"
+ * greeter.setGreeting("howdy");
+ * mh.invoke(); // prints "howdy, world" (object-like mutable behavior)
+ * </pre></blockquote>
+ * <p>
+ * In the example of {@code Greeter}, the method {@code run} provides the entry point.
+ * The entry point need not be a constant value; it may be independently
+ * computed in each call to the constructor. The entry point does not
+ * even need to be a method on the {@code Greeter} class, though
+ * that is the typical case.
+ * <p>
+ * The entry point may also be provided symbolically, in which case the the
+ * {@code JavaMethodHandle} constructor performs the lookup of the entry point.
+ * This makes it possible to use {@code JavaMethodHandle} to create an anonymous
+ * inner class:
+ * <p><blockquote><pre>
+ * // We can also do this with symbolic names and/or inner classes:
+ * MethodHandles.invoke(new JavaMethodHandle("yow") {
+ * void yow() { System.out.println("yow, world"); }
+ * });
+ * </pre></blockquote>
+ * <p>
+ * Here is similar lower-level code which works in terms of a bound method handle.
+ * <p><blockquote><pre>
+ * class Greeter {
* public void run() { System.out.println("hello, "+greetee); }
* private final String greetee;
- * Greeter(String greetee) {
- * super(RUN);
- * this.greetee = greetee;
- * }
+ * Greeter(String greetee) { this.greetee = greetee; }
* // the entry point function is computed once:
* private static final MethodHandle RUN
- * = MethodHandles.findVirtual(MyMethodHandle.class, "run",
+ * = MethodHandles.findVirtual(Greeter.class, "run",
* MethodType.make(void.class));
* }
+ * // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
- * MethodHandle mh = greeter;
+ * MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
* mh.invoke(); // also prints "hello, world"
* </pre></blockquote>
+ * Note that the method handle must be separately created as a view on the base object.
+ * This increases footprint, complexity, and dynamic indirections.
+ * <p>
+ * Here is a pure functional value expressed most concisely as an anonymous inner class:
+ * <p><blockquote><pre>
+ * // class Main { public static void main(String... av) { ...
+ * final String greetee = "world";
+ * MethodHandle greeter = new JavaMethodHandle("run") {
+ * private void run() { System.out.println("hello, "+greetee); }
+ * }
+ * greeter.invoke(); // prints "hello, world"
+ * </pre></blockquote>
* <p>
- * In this example, the method {@code run} provides the entry point.
- * The entry point need not be a constant value; it may be independently
- * computed in each call to the constructor. The entry point does not
- * even need to be a method on the Java method handle class, though
- * that is the typical case.
+ * Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
+ * and instantiated as an anonymous class. The data structure is a handle to 1-D array,
+ * with a specialized index type (long). It is created by inner class, and uses
+ * signature-polymorphic APIs throughout.
+ * <p><blockquote><pre>
+ * abstract class AssignableMethodHandle extends JavaMethodHandle {
+ * private final MethodHandle setter;
+ * public MethodHandle setter() { return setter; }
+ * public AssignableMethodHandle(String get, String set) {
+ * super(get);
+ * MethodType getType = this.type();
+ * MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
+ * this.setter = MethodHandles.publicLookup().bind(this, set, setType);
+ * }
+ * }
+ * // class Main { public static void main(String... av) { ...
+ * final Number[] stuff = { 123, 456 };
+ * AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
+ * public Number get(long i) { return stuff[(int)i]; }
+ * public void set(long i, Object x) { stuff[(int)i] = x; }
+ * }
+ * int x = (Integer) stuffPtr.<Number>invoke(1L); // 456
+ * stuffPtr.setter().<void>invoke(0L, (Number) 789); // replaces 123 with 789
+ * </pre></blockquote>
* @see MethodHandle
* @author John Rose, JSR 292 EG
*/
@@ -72,12 +148,87 @@
// with a JVM change which moves the required hidden behavior onto this class.
extends sun.dyn.BoundMethodHandle
{
+ private static final Access IMPL_TOKEN = Access.getToken();
+
/**
- * When creating a, pass in {@code entryPoint}, any method handle which
- * can take the current object
- * @param entryPoint
+ * When creating a {@code JavaMethodHandle}, the actual method handle
+ * invocation behavior will be delegated to the specified {@code entryPoint}.
+ * This may be any method handle which can take the newly constructed object
+ * as a leading parameter.
+ * <p>
+ * The method handle type of {@code this} (i.e, the fully constructed object)
+ * will be {@code entryPoint}, minus the leading argument.
+ * The leading argument will be bound to {@code this} on every method
+ * handle invocation.
+ * @param entryPoint the method handle to handle calls
*/
protected JavaMethodHandle(MethodHandle entryPoint) {
- super(entryPoint, 0);
+ super(entryPoint);
+ }
+
+ /**
+ * Create a method handle whose entry point is a non-static method
+ * visible in the exact (most specific) class of
+ * the newly constructed object.
+ * <p>
+ * The method is specified by name and type, as if via this expression:
+ * {@code MethodHandles.lookup().findVirtual(this.getClass(), name, type)}.
+ * The class defining the method might be an anonymous inner class.
+ * <p>
+ * The method handle type of {@code this} (i.e, the fully constructed object)
+ * will be the given method handle type.
+ * A call to {@code this} will invoke the selected method.
+ * The receiver argument will be bound to {@code this} on every method
+ * handle invocation.
+ * <p>
+ * <i>Rationale:</i>
+ * Although this constructor may seem to be a mere luxury,
+ * it is not subsumed by the more general constructor which
+ * takes any {@code MethodHandle} as the entry point argument.
+ * In order to convert an entry point name to a method handle,
+ * the self-class of the object is required (in order to do
+ * the lookup). The self-class, in turn, is generally not
+ * available at the time of the constructor invocation,
+ * due to the rules of Java and the JVM verifier.
+ * One cannot call {@code this.getClass()}, because
+ * the value of {@code this} is inaccessible at the point
+ * of the constructor call. (Changing this would require
+ * change to the Java language, verifiers, and compilers.)
+ * In particular, this constructor allows {@code JavaMethodHandle}s
+ * to be created in combination with the anonymous inner class syntax.
+ * @param entryPointName the name of the entry point method
+ * @param type (optional) the desired type of the method handle
+ */
+ protected JavaMethodHandle(String entryPointName, MethodType type) {
+ super(entryPointName, type, true);
+
+ }
+
+ /**
+ * Create a method handle whose entry point is a non-static method
+ * visible in the exact (most specific) class of
+ * the newly constructed object.
+ * <p>
+ * The method is specified only by name.
+ * There must be exactly one method of that name visible in the object class,
+ * either inherited or locally declared.
+ * (That is, the method must not be overloaded.)
+ * <p>
+ * The method handle type of {@code this} (i.e, the fully constructed object)
+ * will be the same as the type of the selected non-static method.
+ * The receiver argument will be bound to {@code this} on every method
+ * handle invocation.
+ * <p>ISSUE: This signature wildcarding feature does not correspond to
+ * any MethodHandles.Lookup API element. Can we eliminate it?
+ * Alternatively, it is useful for naming non-overloaded methods.
+ * Shall we make type arguments optional in the Lookup methods,
+ * throwing an error in cases of ambiguity?
+ * <p>
+ * For this method's rationale, see the documentation
+ * for {@link #JavaMethodHandle(String,MethodType)}.
+ * @param entryPointName the name of the entry point method
+ */
+ protected JavaMethodHandle(String entryPointName) {
+ super(entryPointName, (MethodType) null, false);
}
}
--- a/jdk/src/share/classes/java/dyn/Linkage.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/Linkage.java Wed Jul 05 17:04:56 2017 +0200
@@ -25,7 +25,9 @@
package java.dyn;
+import java.dyn.MethodHandles.Lookup;
import java.util.WeakHashMap;
+import sun.dyn.Access;
import sun.reflect.Reflection;
import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
@@ -34,6 +36,8 @@
* @author John Rose, JSR 292 EG
*/
public class Linkage {
+ private static final Access IMPL_TOKEN = Access.getToken();
+
private Linkage() {} // do not instantiate
/**
@@ -53,19 +57,23 @@
* call to this method.
* <li>The given class is already fully initialized.
* <li>The given class is in the process of initialization, in another thread.
+ * <li>The same {@code CallSite} object has already been returned from
+ * a bootstrap method call to another {@code invokedynamic} call site.
* </ul>
* Because of these rules, a class may install its own bootstrap method in
* a static initializer.
+ * @param callerClass a class that may have {@code invokedynamic} sites
+ * @param bootstrapMethod the method to use to bootstrap all such sites
*/
public static
- void registerBootstrapMethod(Class callerClass, MethodHandle mh) {
+ void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
- checkBSM(mh);
+ checkBSM(bootstrapMethod);
synchronized (bootstrapMethods) {
if (bootstrapMethods.containsKey(callerClass))
throw new IllegalStateException("bootstrap method already declared in "+callerClass);
- bootstrapMethods.put(callerClass, mh);
+ bootstrapMethods.put(callerClass, bootstrapMethod);
}
}
@@ -88,8 +96,9 @@
public static
void registerBootstrapMethod(Class<?> runtime, String name) {
Class callc = Reflection.getCallerClass(2);
+ Lookup lookup = new Lookup(IMPL_TOKEN, callc);
MethodHandle bootstrapMethod =
- MethodHandles.findStaticFrom(callc, runtime, name, BOOTSTRAP_METHOD_TYPE);
+ lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
@@ -106,8 +115,9 @@
public static
void registerBootstrapMethod(String name) {
Class callc = Reflection.getCallerClass(2);
+ Lookup lookup = new Lookup(IMPL_TOKEN, callc);
MethodHandle bootstrapMethod =
- MethodHandles.findStaticFrom(callc, callc, name, BOOTSTRAP_METHOD_TYPE);
+ lookup.findStatic(callc, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
@@ -116,8 +126,7 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Report the bootstrap method registered for a given class.
- * Returns null if the class has never yet registered a bootstrap method,
- * or if the class has explicitly registered a null bootstrap method.
+ * Returns null if the class has never yet registered a bootstrap method.
* Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry
* point into its class.
@@ -137,12 +146,12 @@
* {@code (Class, String, MethodType)} returning a {@code CallSite}.
*/
public static final MethodType BOOTSTRAP_METHOD_TYPE
- = MethodType.make(CallSite.class,
- Class.class, String.class, MethodType.class);
+ = MethodType.methodType(CallSite.class,
+ Class.class, String.class, MethodType.class);
private static final MethodType OLD_BOOTSTRAP_METHOD_TYPE
- = MethodType.make(Object.class,
- CallSite.class, Object[].class);
+ = MethodType.methodType(Object.class,
+ CallSite.class, Object[].class);
private static final WeakHashMap<Class, MethodHandle> bootstrapMethods =
new WeakHashMap<Class, MethodHandle>();
@@ -173,8 +182,8 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * Invalidate all <code>invokedynamic</code> call sites associated
- * with the given class.
+ * Invalidate all <code>invokedynamic</code> call sites in the bytecodes
+ * of any methods of the given class.
* (These are exactly those sites which report the given class
* via the {@link CallSite#callerClass()} method.)
* <p>
--- a/jdk/src/share/classes/java/dyn/LinkagePermission.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/LinkagePermission.java Wed Jul 05 17:04:56 2017 +0200
@@ -88,7 +88,7 @@
/**
* Create a new LinkagePermission with the given name.
* The name is the symbolic name of the LinkagePermission, such as
- * "registerBootstrapMethod", "invalidateClass.*", etc. An asterisk
+ * "registerBootstrapMethod", "invalidateCallerClass.*", etc. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
*
--- a/jdk/src/share/classes/java/dyn/MethodHandle.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/MethodHandle.java Wed Jul 05 17:04:56 2017 +0200
@@ -30,6 +30,9 @@
import sun.dyn.Access;
import sun.dyn.MethodHandleImpl;
+import static java.dyn.MethodHandles.invokers; // package-private API
+import static sun.dyn.MemberName.newIllegalArgumentException; // utility
+
/**
* A method handle is a typed reference to the entry point of a method.
* <p>
@@ -45,8 +48,9 @@
* Every method handle appears as an object containing a method named
* <code>invoke</code>, whose signature exactly matches
* the method handle's type.
- * A normal Java method call (using the <code>invokevirtual</code> instruction)
- * can invoke this method from Java source code (if language support is present).
+ * A Java method call expression, which compiles to an
+ * <code>invokevirtual</code> instruction,
+ * can invoke this method from Java source code.
* <p>
* Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle.
@@ -57,6 +61,10 @@
* The call fails with a {@link WrongMethodTypeException}
* if the method does not exist, even if there is an <code>invoke</code>
* method of a closely similar signature.
+ * As with other kinds
+ * of methods in the JVM, signature matching during method linkage
+ * is exact, and does not allow for language-level implicit conversions
+ * such as {@code String} to {@code Object} or {@code short} to {@code int}.
* <p>
* A method handle is an unrestricted capability to call a method.
* A method handle can be formed on a non-public method by a class
@@ -74,6 +82,15 @@
* (after resolving symbolic type names) must exactly match the method type
* of the target method.
* <p>
+ * Every <code>invoke</code> method always throws {@link Exception},
+ * which is to say that there is no static restriction on what a method handle
+ * can throw. Since the JVM does not distinguish between checked
+ * and unchecked exceptions (other than by their class, of course),
+ * there is no particular effect on bytecode shape from ascribing
+ * checked exceptions to method handle invocations. But in Java source
+ * code, methods which perform method handle calls must either explicitly
+ * throw {@code Exception}, or else must catch all checked exceptions locally.
+ * <p>
* Bytecode in an extended JVM can directly obtain a method handle
* for any accessible method from a <code>ldc</code> instruction
* which refers to a <code>CONSTANT_Methodref</code> or
@@ -97,6 +114,59 @@
* can also be created. These do not perform virtual lookup based on
* receiver type. Such a method handle simulates the effect of
* an <code>invokespecial</code> instruction to the same method.
+ * <p>
+ * Here are some examples of usage:
+ * <p><blockquote><pre>
+ * Object x, y; String s; int i;
+ * MethodType mt; MethodHandle mh;
+ * MethodHandles.Lookup lookup = MethodHandles.lookup();
+ * // mt is {(char,char) => String}
+ * mt = MethodType.make(String.class, char.class, char.class);
+ * mh = lookup.findVirtual(String.class, "replace", mt);
+ * // (Ljava/lang/String;CC)Ljava/lang/String;
+ * s = mh.<String>invoke("daddy",'d','n');
+ * assert(s.equals("nanny"));
+ * // weakly typed invocation (using MHs.invoke)
+ * s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v');
+ * assert(s.equals("savvy"));
+ * // mt is {Object[] => List}
+ * mt = MethodType.make(java.util.List.class, Object[].class);
+ * mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
+ * // mt is {(Object,Object,Object) => Object}
+ * mt = MethodType.makeGeneric(3);
+ * mh = MethodHandles.collectArguments(mh, mt);
+ * // mt is {(Object,Object,Object) => Object}
+ * // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+ * x = mh.invoke((Object)1, (Object)2, (Object)3);
+ * assert(x.equals(java.util.Arrays.asList(1,2,3)));
+ * // mt is { => int}
+ * mt = MethodType.make(int.class);
+ * mh = lookup.findVirtual(java.util.List.class, "size", mt);
+ * // (Ljava/util/List;)I
+ * i = mh.<int>invoke(java.util.Arrays.asList(1,2,3));
+ * assert(i == 3);
+ * </pre></blockquote>
+ * Each of the above calls generates a single invokevirtual instruction
+ * with the name {@code invoke} and the type descriptors indicated in the comments.
+ * The argument types are taken directly from the actual arguments,
+ * while the return type is taken from the type parameter.
+ * (This type parameter may be a primitive, and it defaults to {@code Object}.)
+ * <p>
+ * <em>A note on generic typing:</em> Method handles do not represent
+ * their function types in terms of Java parameterized (generic) types,
+ * because there are three mismatches between function types and parameterized
+ * Java types.
+ * <ol>
+ * <li>Method types range over all possible arities,
+ * from no arguments to an arbitrary number of arguments.
+ * Generics are not variadic, and so cannot represent this.</li>
+ * <li>Method types can specify arguments of primitive types,
+ * which Java generic types cannot range over.</li>
+ * <li>Higher order functions over method handles (combinators) are
+ * often generic across a wide range of function types, including
+ * those of multiple arities. It is impossible to represent such
+ * genericity with a Java type parameter.</li>
+ * </ol>
*
* @see MethodType
* @see MethodHandles
@@ -107,17 +177,19 @@
// with a JVM change which moves the required hidden state onto this class.
extends MethodHandleImpl
{
- // interface MethodHandle<T extends MethodType<R,A...>>
- // { T type(); <R,A...> public R invoke(A...); }
+ private static Access IMPL_TOKEN = Access.getToken();
- final private MethodType type;
+ // interface MethodHandle<R throws X extends Exception,A...>
+ // { MethodType<R throws X,A...> type(); public R invoke(A...) throws X; }
+
+ private MethodType type;
/**
* Report the type of this method handle.
* Every invocation of this method handle must exactly match this type.
* @return the method handle type
*/
- public MethodType type() {
+ public final MethodType type() {
return type;
}
@@ -130,6 +202,369 @@
*/
protected MethodHandle(Access token, MethodType type) {
super(token);
+ Access.check(token);
+ this.type = type;
+ }
+
+ private void initType(MethodType type) {
+ type.getClass(); // elicit NPE
+ if (this.type != null) throw new InternalError();
this.type = type;
}
+
+ static {
+ // This hack allows the implementation package special access to
+ // the internals of MethodHandle. In particular, the MTImpl has all sorts
+ // of cached information useful to the implementation code.
+ MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
+ public void initType(MethodHandle mh, MethodType type) { mh.initType(type); }
+ });
+ }
+
+ /** The string of a direct method handle is the simple name of its target method.
+ * The string of an adapter or bound method handle is the string of its
+ * target method handle.
+ * The string of a Java method handle is the string of its entry point method,
+ * unless the Java method handle overrides the toString method.
+ */
+ @Override
+ public String toString() {
+ return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
+ }
+
+ //// First draft of the "Method Handle Kernel API" discussed at the JVM Language Summit, 9/2009.
+ //// Implementations here currently delegate to statics in MethodHandles. Some of those statics
+ //// will be deprecated. Others will be kept as "algorithms" to supply degrees of freedom
+ //// not present in the Kernel API.
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Perform an exact invocation. The signature at the call site of {@code invokeExact} must
+ * exactly match this method handle's {@code type}.
+ * No conversions are allowed on arguments or return values.
+ * <em>This is not yet implemented, pending required compiler and JVM support.</em>
+ */
+ public final <T> T invokeExact(Object... arguments) throws Throwable {
+ // This is an approximate implementation, which discards the caller's signature and refuses the call.
+ throw new InternalError("not yet implemented");
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Perform a generic invocation. The signature at the call site of {@code invokeExact} must
+ * have the same arity as this method handle's {@code type}.
+ * The same conversions are allowed on arguments or return values as are supported by
+ * by {@link MethodHandles#convertArguments}.
+ * If the call site signature exactly matches this method handle's {@code type},
+ * the call proceeds as if by {@link #invokeExact}.
+ * <em>This is not fully implemented, pending required compiler and JVM support.</em>
+ */
+ // This is an approximate implementation, which discards the caller's signature.
+ // When it is made signature polymorphic, the overloadings will disappear.
+ public final <T> T invokeGeneric() throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this);
+ }
+ public final <T> T invokeGeneric(Object a0) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3, a4);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7, a8);
+ }
+ public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable {
+ MethodHandle invoker = invokers(this.type()).genericInvoker();
+ return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Perform a varargs invocation, passing the arguments in the given array
+ * to the method handle, as if via {@link #invokeGeneric} from a call site
+ * which mentions only the type {@code Object}, and whose arity is the length
+ * of the argument array.
+ * <p>
+ * The length of the arguments array must equal the parameter count
+ * of the target's type.
+ * The arguments array is spread into separate arguments.
+ * <p>
+ * In order to match the type of the target, the following argument
+ * conversions are applied as necessary:
+ * <ul>
+ * <li>reference casting
+ * <li>unboxing
+ * </ul>
+ * The following conversions are not applied:
+ * <ul>
+ * <li>primitive conversions (e.g., {@code byte} to {@code int}
+ * <li>varargs conversions other than the initial spread
+ * <li>any application-specific conversions (e.g., string to number)
+ * </ul>
+ * The result returned by the call is boxed if it is a primitive,
+ * or forced to null if the return type is void.
+ * <p>
+ * This call is equivalent to the following code:
+ * <p><blockquote><pre>
+ * MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
+ * Object result = invoker.invoke(this, arguments);
+ * </pre></blockquote>
+ * @param arguments the arguments to pass to the target
+ * @return the result returned by the target
+ * @see MethodHandles#genericInvoker
+ */
+ public final Object invokeVarargs(Object[] arguments) throws Throwable {
+ int argc = arguments == null ? 0 : arguments.length;
+ MethodType type = type();
+ if (argc <= 10) {
+ MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
+ switch (argc) {
+ case 0: return invoker.invoke(this);
+ case 1: return invoker.invoke(this,
+ arguments[0]);
+ case 2: return invoker.invoke(this,
+ arguments[0], arguments[1]);
+ case 3: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2]);
+ case 4: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3]);
+ case 5: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4]);
+ case 6: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5]);
+ case 7: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6]);
+ case 8: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6], arguments[7]);
+ case 9: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6], arguments[7], arguments[8]);
+ case 10: return invoker.invoke(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6], arguments[7], arguments[8],
+ arguments[9]);
+ }
+ }
+
+ // more than ten arguments get boxed in a varargs list:
+ MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
+ return invoker.invoke(this, arguments);
+ }
+ /** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
+ public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
+ return invokeVarargs(arguments.toArray());
+ }
+
+ /* --- this is intentionally NOT a javadoc yet ---
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce an adapter method handle which adapts the type of the
+ * current method handle to a new type by pairwise argument conversion.
+ * The original type and new type must have the same number of arguments.
+ * The resulting method handle is guaranteed to confess a type
+ * which is equal to the desired new type.
+ * <p>
+ * If the original type and new type are equal, returns {@code this}.
+ * <p>
+ * The following conversions are applied as needed both to
+ * arguments and return types. Let T0 and T1 be the differing
+ * new and old parameter types (or old and new return types)
+ * for corresponding values passed by the new and old method types.
+ * Given those types T0, T1, one of the following conversions is applied
+ * if possible:
+ * <ul>
+ * <li>If T0 and T1 are references, and T1 is not an interface type,
+ * then a cast to T1 is applied.
+ * (The types do not need to be related in any particular way.)
+ * <li>If T0 and T1 are references, and T1 is an interface type,
+ * then the value of type T0 is passed as a T1 without a cast.
+ * (This treatment of interfaces follows the usage of the bytecode verifier.)
+ * <li>If T0 and T1 are primitives, then a Java casting
+ * conversion (JLS 5.5) is applied, if one exists.
+ * <li>If T0 and T1 are primitives and one is boolean,
+ * the boolean is treated as a one-bit unsigned integer.
+ * (This treatment follows the usage of the bytecode verifier.)
+ * A conversion from another primitive type behaves as if
+ * it first converts to byte, and then masks all but the low bit.
+ * <li>If T0 is a primitive and T1 a reference, a boxing
+ * conversion is applied if one exists, possibly followed by
+ * an reference conversion to a superclass.
+ * T1 must be a wrapper class or a supertype of one.
+ * If T1 is a wrapper class, T0 is converted if necessary
+ * to T1's primitive type by one of the preceding conversions.
+ * Otherwise, T0 is boxed, and its wrapper converted to T1.
+ * <li>If T0 is a reference and T1 a primitive, an unboxing
+ * conversion is applied if one exists, possibly preceded by
+ * a reference conversion to a wrapper class.
+ * T0 must be a wrapper class or a supertype of one.
+ * If T0 is a wrapper class, its primitive value is converted
+ * if necessary to T1 by one of the preceding conversions.
+ * Otherwise, T0 is converted directly to the wrapper type for T1,
+ * which is then unboxed.
+ * <li>If the return type T1 is void, any returned value is discarded
+ * <li>If the return type T0 is void and T1 a reference, a null value is introduced.
+ * <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
+ * </ul>
+ * <p>
+ */
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce an adapter method handle which adapts the type of the
+ * current method handle to a new type by pairwise argument conversion.
+ * The original type and new type must have the same number of arguments.
+ * The resulting method handle is guaranteed to confess a type
+ * which is equal to the desired new type.
+ * <p>
+ * If the original type and new type are equal, returns {@code this}.
+ * <p>
+ * This method is equivalent to {@link MethodHandles#convertArguments}.
+ * @param newType the expected type of the new method handle
+ * @return a method handle which delegates to {@code this} after performing
+ * any necessary argument conversions, and arranges for any
+ * necessary return value conversions
+ * @throws IllegalArgumentException if the conversion cannot be made
+ * @see MethodHandles#convertArguments
+ */
+ public final MethodHandle asType(MethodType newType) {
+ return MethodHandles.convertArguments(this, newType);
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce a method handle which adapts, as its <i>target</i>,
+ * the current method handle. The type of the adapter will be
+ * the same as the type of the target, except that all but the first
+ * {@code keepPosArgs} parameters of the target's type are replaced
+ * by a single array parameter of type {@code Object[]}.
+ * Thus, if {@code keepPosArgs} is zero, the adapter will take all
+ * arguments in a single object array.
+ * <p>
+ * When called, the adapter replaces a trailing array argument
+ * by the array's elements, each as its own argument to the target.
+ * (The order of the arguments is preserved.)
+ * They are converted pairwise by casting and/or unboxing
+ * (as if by {@link MethodHandles#convertArguments})
+ * to the types of the trailing parameters of the target.
+ * Finally the target is called.
+ * What the target eventually returns is returned unchanged by the adapter.
+ * <p>
+ * Before calling the target, the adapter verifies that the array
+ * contains exactly enough elements to provide a correct argument count
+ * to the target method handle.
+ * (The array may also be null when zero elements are required.)
+ * @param keepPosArgs the number of leading positional arguments to preserve
+ * @return a new method handle which spreads its final argument,
+ * before calling the original method handle
+ * @throws IllegalArgumentException if target does not have at least
+ * {@code keepPosArgs} parameter types
+ */
+ public final MethodHandle asSpreader(int keepPosArgs) {
+ MethodType oldType = type();
+ int nargs = oldType.parameterCount();
+ MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
+ newType = newType.insertParameterTypes(keepPosArgs, Object[].class);
+ return MethodHandles.spreadArguments(this, newType);
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce a method handle which adapts, as its <i>target</i>,
+ * the current method handle. The type of the adapter will be
+ * the same as the type of the target, except that a single trailing
+ * array parameter of type {@code Object[]} is replaced by
+ * {@code spreadArrayArgs} parameters of type {@code Object}.
+ * <p>
+ * When called, the adapter replaces its trailing {@code spreadArrayArgs}
+ * arguments by a single new {@code Object} array, whose elements
+ * comprise (in order) the replaced arguments.
+ * Finally the target is called.
+ * What the target eventually returns is returned unchanged by the adapter.
+ * <p>
+ * (The array may also be a shared constant when {@code spreadArrayArgs} is zero.)
+ * @param spreadArrayArgs the number of arguments to spread from the trailing array
+ * @return a new method handle which collects some trailing argument
+ * into an array, before calling the original method handle
+ * @throws IllegalArgumentException if the last argument of the target
+ * is not {@code Object[]}
+ * @throws IllegalArgumentException if {@code spreadArrayArgs} is not
+ * a legal array size
+ * @deprecated Provisional and unstable; use {@link MethodHandles#collectArguments}.
+ */
+ public final MethodHandle asCollector(int spreadArrayArgs) {
+ MethodType oldType = type();
+ int nargs = oldType.parameterCount();
+ MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
+ newType = newType.insertParameterTypes(nargs-1, MethodType.genericMethodType(spreadArrayArgs).parameterArray());
+ return MethodHandles.collectArguments(this, newType);
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce a method handle which binds the given argument
+ * to the current method handle as <i>target</i>.
+ * The type of the bound handle will be
+ * the same as the type of the target, except that a single leading
+ * reference parameter will be omitted.
+ * <p>
+ * When called, the bound handle inserts the given value {@code x}
+ * as a new leading argument to the target. The other arguments are
+ * also passed unchanged.
+ * What the target eventually returns is returned unchanged by the bound handle.
+ * <p>
+ * The reference {@code x} must be convertible to the first parameter
+ * type of the target.
+ * @param x the value to bind to the first argument of the target
+ * @return a new method handle which collects some trailing argument
+ * into an array, before calling the original method handle
+ * @throws IllegalArgumentException if the target does not have a
+ * leading parameter type that is a reference type
+ * @throws ClassCastException if {@code x} cannot be converted
+ * to the leading parameter type of the target
+ * @deprecated Provisional and unstable; use {@link MethodHandles#insertArguments}.
+ */
+ public final MethodHandle bindTo(Object x) {
+ return MethodHandles.insertArguments(this, 0, x);
+ }
}
--- a/jdk/src/share/classes/java/dyn/MethodHandles.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/MethodHandles.java Wed Jul 05 17:04:56 2017 +0200
@@ -34,6 +34,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import sun.dyn.Invokers;
@@ -44,17 +45,14 @@
/**
* Fundamental operations and utilities for MethodHandle.
+ * They fall into several categories:
+ * <ul>
+ * <li>Reifying methods and fields. This is subject to access checks.
+ * <li>Invoking method handles on dynamically typed arguments and/or varargs arrays.
+ * <li>Combining or transforming pre-existing method handles into new ones.
+ * <li>Miscellaneous emulation of common JVM operations or control flow patterns.
+ * </ul>
* <p>
- * <em>API Note:</em> The matching of method types in this API cannot
- * be completely checked by Java's generic type system for three reasons:
- * <ol>
- * <li>Method types range over all possible arities,
- * from no arguments to an arbitrary number of arguments.
- * Generics are not variadic, and so cannot represent this.</li>
- * <li>Method types can specify arguments of primitive types,
- * which Java generic types cannot range over.</li>
- * <li>Method types can optionally specify varargs (ellipsis).</li>
- * </ol>
* @author John Rose, JSR 292 EG
*/
public class MethodHandles {
@@ -68,12 +66,22 @@
//// Method handle creation from ordinary methods.
+ /** Create a {@link Lookup} lookup object on the caller.
+ *
+ */
public static Lookup lookup() {
return new Lookup();
}
+ /** Version of lookup which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible members.
+ */
+ public static Lookup publicLookup() {
+ return Lookup.PUBLIC_LOOKUP;
+ }
+
/**
- * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* A factory object for creating method handles, when the creation
* requires access checking. Method handles do not perform
* access checks when they are called; this is a major difference
@@ -121,7 +129,8 @@
/** Which class is performing the lookup? It is this class against
* which checks are performed for visibility and access permissions.
* <p>
- * This value is null if and only if this lookup is {@link #PUBLIC_LOOKUP}.
+ * This value is null if and only if this lookup was produced
+ * by {@link MethodHandles#publicLookup}.
*/
public Class<?> lookupClass() {
return lookupClass;
@@ -135,23 +144,46 @@
* an access$N method.
*/
Lookup() {
- Class caller = getCallerClassAtEntryPoint();
- // make sure we haven't accidentally picked up this class:
- checkUnprivilegedlookupClass(caller);
- this.lookupClass = caller;
+ this(IMPL_TOKEN, getCallerClassAtEntryPoint());
+ }
+
+ Lookup(Access token, Class<?> lookupClass) {
+ // make sure we haven't accidentally picked up a privileged class:
+ checkUnprivilegedlookupClass(lookupClass);
+ this.lookupClass = lookupClass;
+ }
+
+ /**
+ * Create a lookup on the specified class.
+ * The result is guaranteed to have no more access privileges
+ * than the original.
+ */
+ public Lookup in(Class<?> newLookupClass) {
+ if (this == PUBLIC_LOOKUP) return PUBLIC_LOOKUP;
+ if (newLookupClass == null) return PUBLIC_LOOKUP;
+ if (newLookupClass == lookupClass) return this;
+ if (this != IMPL_LOOKUP) {
+ if (!VerifyAccess.isSamePackage(lookupClass, newLookupClass))
+ throw newNoAccessException(new MemberName(newLookupClass), this);
+ checkUnprivilegedlookupClass(newLookupClass);
+ }
+ return new Lookup(newLookupClass);
}
private Lookup(Class<?> lookupClass) {
this.lookupClass = lookupClass;
}
+ // Make sure outer class is initialized first.
+ static { IMPL_TOKEN.getClass(); }
+
private static final Class<?> PUBLIC_ONLY = sun.dyn.empty.Empty.class;
/** Version of lookup which is trusted minimally.
* It can only be used to create method handles to
* publicly accessible members.
*/
- public static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
+ static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
/** Package-private version of lookup which is trusted. */
static final Lookup IMPL_LOOKUP = new Lookup(null);
@@ -178,12 +210,16 @@
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
// 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
// Note: This should be the only use of getCallerClass in this file.
+ assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
return Reflection.getCallerClass(CALLER_DEPTH);
}
/**
* Produce a method handle for a static method.
* The type of the method handle will be that of the method.
+ * (Since static methods do not take receivers, there is no
+ * additional receiver argument inserted into the method handle type,
+ * as there would be with {@linkplain #findVirtual} or {@linkplain #findSpecial}.)
* The method and all its argument types must be accessible to the lookup class.
* If the method's class has not yet been initialized, that is done
* immediately, before the method handle is returned.
@@ -196,10 +232,11 @@
*/
public
MethodHandle findStatic(Class<?> defc, String name, MethodType type) throws NoAccessException {
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass);
- checkStatic(true, method, lookupClass);
+ MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass());
+ VerifyAccess.checkName(method, this);
+ checkStatic(true, method, this);
//throw NoSuchMethodException
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass);
+ return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass());
}
/**
@@ -228,9 +265,10 @@
* @exception NoAccessException if the method does not exist or access checking fails
*/
public MethodHandle findVirtual(Class<?> defc, String name, MethodType type) throws NoAccessException {
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), true, lookupClass);
- checkStatic(false, method, lookupClass);
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass);
+ MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), true, lookupClass());
+ VerifyAccess.checkName(method, this);
+ checkStatic(false, method, this);
+ return MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass());
}
/**
@@ -259,15 +297,17 @@
*/
public MethodHandle findSpecial(Class<?> defc, String name, MethodType type,
Class<?> specialCaller) throws NoAccessException {
- checkSpecialCaller(specialCaller, lookupClass);
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), false, specialCaller);
- checkStatic(false, method, lookupClass);
+ checkSpecialCaller(specialCaller, this);
+ Lookup slookup = this.in(specialCaller);
+ MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), false, slookup.lookupClass());
+ VerifyAccess.checkName(method, this);
+ checkStatic(false, method, this);
if (name.equals("<init>")) {
throw newNoAccessException("cannot directly invoke a constructor", method, null);
} else if (defc.isInterface() || !defc.isAssignableFrom(specialCaller)) {
- throw newNoAccessException("method must be in a superclass of lookup class", method, lookupClass);
+ throw newNoAccessException("method must be in a superclass of lookup class", method, slookup.lookupClass());
}
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, specialCaller);
+ return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, slookup.lookupClass());
}
/**
@@ -275,13 +315,19 @@
* The receiver must have a supertype {@code defc} in which a method
* of the given name and type is accessible to the lookup class.
* The method and all its argument types must be accessible to the lookup class.
- * The type of the method handle will be that of the method.
- * The given receiver will be bound into the method handle.
+ * The type of the method handle will be that of the method,
+ * without any insertion of an additional receiver parameter.
+ * The given receiver will be bound into the method handle,
+ * so that every call to the method handle will invoke the
+ * requested method on the given receiver.
* <p>
- * Equivalent to the following expression:
+ * This is equivalent to the following expression:
* <code>
- * {@link #insertArgument}({@link #findVirtual}(defc, name, type), receiver)
+ * {@link #insertArguments}({@link #findVirtual}(defc, name, type), receiver)
* </code>
+ * where {@code defc} is either {@code receiver.getClass()} or a super
+ * type of that class, in which the requested method is accessible
+ * to the lookup class.
* @param receiver the object from which the method is accessed
* @param name the name of the method
* @param type the type of the method, with the receiver argument omitted
@@ -292,16 +338,18 @@
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoAccessException {
Class<? extends Object> rcvc = receiver.getClass(); // may get NPE
MemberName reference = new MemberName(rcvc, name, type);
- MemberName method = IMPL_NAMES.resolveOrFail(reference, true, lookupClass);
- checkStatic(false, method, lookupClass);
- MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass);
+ MemberName method = IMPL_NAMES.resolveOrFail(reference, true, lookupClass());
+ VerifyAccess.checkName(method, this);
+ checkStatic(false, method, this);
+ MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass());
MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver);
if (bmh == null)
- throw newNoAccessException(method, lookupClass);
+ throw newNoAccessException(method, this);
return bmh;
}
/**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Make a direct method handle to <i>m</i>, if the lookup class has permission.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is virtual, overriding is respected on every call.
@@ -316,10 +364,11 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflect(Method m) throws NoAccessException {
- return unreflectImpl(new MemberName(m), m.isAccessible(), true, lookupClass);
+ return unreflectImpl(new MemberName(m), m.isAccessible(), true, false, this);
}
/**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle for a reflected method.
* It will bypass checks for overriding methods on the receiver,
* as if by the {@code invokespecial} instruction.
@@ -333,37 +382,41 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws NoAccessException {
- checkSpecialCaller(specialCaller, lookupClass);
+ checkSpecialCaller(specialCaller, this);
+ Lookup slookup = this.in(specialCaller);
MemberName mname = new MemberName(m);
- checkStatic(false, mname, lookupClass);
- return unreflectImpl(mname, m.isAccessible(), false, specialCaller);
+ checkStatic(false, mname, this);
+ return unreflectImpl(mname, m.isAccessible(), false, false, slookup);
}
/**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle for a reflected constructor.
- * The type of the method handle will be that of the constructor.
+ * The type of the method handle will be that of the constructor,
+ * with the return type changed to the declaring class.
* The method handle will perform a {@code newInstance} operation,
* creating a new instance of the constructor's class on the
* arguments passed to the method handle.
* <p>
* If the constructor's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class,
- * as if {@code invokespecial} instruction were being linked.
+ * access checking is performed immediately on behalf of the lookup class.
* @param ctor the reflected constructor
* @return a method handle which can invoke the reflected constructor
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectConstructor(Constructor ctor) throws NoAccessException {
MemberName m = new MemberName(ctor);
- return unreflectImpl(m, ctor.isAccessible(), false, lookupClass);
+ return unreflectImpl(m, ctor.isAccessible(), false, false, this);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving read access to a reflected field.
* The type of the method handle will have a return type of the field's
- * value type. Its sole argument will be the field's containing class
- * (but only if it is non-static).
+ * value type.
+ * If the field is static, the method handle will take no arguments.
+ * Otherwise, its single argument will be the instance containing
+ * the field.
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
@@ -371,16 +424,18 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectGetter(Field f) throws NoAccessException {
- return MethodHandleImpl.accessField(IMPL_TOKEN, new MemberName(f), false, lookupClass);
+ MemberName m = new MemberName(f);
+ return unreflectImpl(m, f.isAccessible(), false, false, this);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving write access to a reflected field.
* The type of the method handle will have a void return type.
- * Its last argument will be the field's value type.
- * Its other argument will be the field's containing class
- * (but only if it is non-static).
+ * If the field is static, the method handle will take a single
+ * argument, of the field's value type, the value to be stored.
+ * Otherwise, the two arguments will be the instance containing
+ * the field, and the value to be stored.
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
@@ -388,59 +443,75 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSetter(Field f) throws NoAccessException {
- return MethodHandleImpl.accessField(IMPL_TOKEN, new MemberName(f), true, lookupClass);
+ MemberName m = new MemberName(f);
+ return unreflectImpl(m, f.isAccessible(), false, true, this);
}
}
static /*must not be public*/
- MethodHandle findStaticFrom(Class<?> lookupClass,
+ MethodHandle findStaticFrom(Lookup lookup,
Class<?> defc, String name, MethodType type) throws NoAccessException {
- MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass);
- checkStatic(true, method, lookupClass);
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass);
+ MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookup.lookupClass());
+ VerifyAccess.checkName(method, lookup);
+ checkStatic(true, method, lookup);
+ return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookup.lookupClass());
}
- static void checkStatic(boolean wantStatic, MemberName m, Class<?> lookupClass) {
+ static void checkStatic(boolean wantStatic, MemberName m, Lookup lookup) {
if (wantStatic != m.isStatic()) {
String message = wantStatic ? "expected a static method" : "expected a non-static method";
- throw newNoAccessException(message, m, lookupClass);
+ throw newNoAccessException(message, m, lookup.lookupClass());
}
}
- static void checkSpecialCaller(Class<?> specialCaller, Class<?> lookupClass) {
- if (lookupClass == Lookup.IMPL_LOOKUP.lookupClass())
+ static void checkSpecialCaller(Class<?> specialCaller, Lookup lookup) {
+ if (lookup == Lookup.IMPL_LOOKUP)
return; // privileged action
- if (lookupClass == null || // public-only access
- !VerifyAccess.isSamePackageMember(specialCaller, lookupClass))
- throw newNoAccessException("no private access", new MemberName(specialCaller), lookupClass);
+ assert(lookup.lookupClass() != null);
+ if (!VerifyAccess.isSamePackageMember(specialCaller, lookup.lookupClass()))
+ throw newNoAccessException("no private access", new MemberName(specialCaller), lookup.lookupClass());
}
// Helper for creating handles on reflected methods and constructors.
static MethodHandle unreflectImpl(MemberName m, boolean isAccessible,
- boolean doDispatch, Class<?> lookupClass) {
- MethodType mtype = m.getInvocationType();
+ boolean doDispatch, boolean isSetter, Lookup lookup) {
+ MethodType narrowMethodType = null;
Class<?> defc = m.getDeclaringClass();
+ boolean isSpecialInvoke = m.isInvocable() && !doDispatch;
int mods = m.getModifiers();
if (m.isStatic()) {
if (!isAccessible &&
- VerifyAccess.isAccessible(defc, mods, false, lookupClass) == null)
- throw newNoAccessException(m, lookupClass);
+ VerifyAccess.isAccessible(defc, mods, lookup.lookupClass(), false) == null)
+ throw newNoAccessException(m, lookup);
} else {
Class<?> constraint;
if (isAccessible) {
// abbreviated access check for "unlocked" method
- constraint = doDispatch ? defc : lookupClass;
+ constraint = doDispatch ? defc : lookup.lookupClass();
} else {
- constraint = VerifyAccess.isAccessible(defc, mods, doDispatch, lookupClass);
+ constraint = VerifyAccess.isAccessible(defc, mods, lookup.lookupClass(), isSpecialInvoke);
+ }
+ if (constraint == null) {
+ throw newNoAccessException(m, lookup);
}
if (constraint != defc && !constraint.isAssignableFrom(defc)) {
if (!defc.isAssignableFrom(constraint))
- throw newNoAccessException("receiver must be in caller class", m, lookupClass);
- mtype = mtype.changeParameterType(0, constraint);
+ throw newNoAccessException("receiver must be in caller class", m, lookup.lookupClass());
+ if (m.isInvocable())
+ narrowMethodType = m.getInvocationType().changeParameterType(0, constraint);
+ else if (m.isField())
+ narrowMethodType = (!isSetter
+ ? MethodType.methodType(m.getFieldType(), constraint)
+ : MethodType.methodType(void.class, constraint, m.getFieldType()));
}
}
- return MethodHandleImpl.findMethod(IMPL_TOKEN, m, doDispatch, lookupClass);
+ if (m.isInvocable())
+ return MethodHandleImpl.findMethod(IMPL_TOKEN, m, doDispatch, lookup.lookupClass());
+ else if (m.isField())
+ return MethodHandleImpl.accessField(IMPL_TOKEN, m, isSetter, lookup.lookupClass());
+ else
+ throw new InternalError();
}
/**
@@ -472,138 +543,104 @@
return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, true);
}
-
/// method handle invocation (reflective style)
/**
- * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * Call the {@code invoke} method of a given method handle,
- * with arguments that exactly match the parameter types of the method handle.
- * The length of the arguments array must equal the parameter count
- * of the target's type.
- * The arguments array is spread into separate arguments, and
- * basic reference and unboxing conversions are applied.
- * <p>
- * In order to match the type of the target, the following argument
- * conversions are applied as necessary:
- * <ul>
- * <li>reference casting
- * <li>unboxing
- * </ul>
- * The following conversions are not applied:
- * <ul>
- * <li>primitive conversions (e.g., {@code byte} to {@code int}
- * <li>varargs conversions other than the initial spread
- * <li>any application-specific conversions (e.g., string to number)
- * </ul>
- * The result returned by the call is boxed if it is a primitive,
- * or forced to null if the return type is void.
- * <p>
- * This call is a convenience method for the following code:
- * <pre>
- * MethodHandle invoker = MethodHandles.genericInvoker(target.type(), 0, true);
- * Object result = invoker.invoke(arguments);
- * </pre>
- * @param target the method handle to invoke
- * @param arguments the arguments to pass to the target
- * @return the result returned by the target
+ * @deprecated Alias for MethodHandle.invokeVarargs.
*/
+ @Deprecated
public static
- Object invoke(MethodHandle target, Object... arguments) {
- int argc = arguments == null ? 0 : arguments.length;
- MethodType type = target.type();
- if (argc <= 4) {
- MethodHandle invoker = invokers(type).genericInvoker();
- switch (argc) {
- case 0: return invoker.<Object>invoke(target);
- case 1: return invoker.<Object>invoke(target,
- arguments[0]);
- case 2: return invoker.<Object>invoke(target,
- arguments[0], arguments[1]);
- case 3: return invoker.<Object>invoke(target,
- arguments[0], arguments[1], arguments[2]);
- case 4: return invoker.<Object>invoke(target,
- arguments[0], arguments[1], arguments[2], arguments[3]);
- }
- }
- MethodHandle invoker = invokers(type).varargsInvoker();
- return invoker.<Object>invoke(target, arguments);
+ Object invokeVarargs(MethodHandle target, Object... arguments) throws Throwable {
+ return target.invokeVarargs(arguments);
}
- public static
- Object invoke_0(MethodHandle target) {
- MethodHandle invoker = invokers(target.type()).genericInvoker();
- return invoker.<Object>invoke(target);
- }
- public static
- Object invoke_1(MethodHandle target, Object a0) {
- MethodHandle invoker = invokers(target.type()).genericInvoker();
- return invoker.<Object>invoke(target, a0);
- }
+ /**
+ * @deprecated Alias for MethodHandle.invokeVarargs.
+ */
+ @Deprecated
public static
- Object invoke_2(MethodHandle target, Object a0, Object a1) {
- MethodHandle invoker = invokers(target.type()).genericInvoker();
- return invoker.<Object>invoke(target, a0, a1);
- }
- public static
- Object invoke_3(MethodHandle target, Object a0, Object a1, Object a2) {
- MethodHandle invoker = invokers(target.type()).genericInvoker();
- return invoker.<Object>invoke(target, a0, a1, a2);
- }
- public static
- Object invoke_4(MethodHandle target, Object a0, Object a1, Object a2, Object a3) {
- MethodHandle invoker = invokers(target.type()).genericInvoker();
- return invoker.<Object>invoke(target, a0, a1, a2, a3);
+ Object invoke(MethodHandle target, Object... arguments) throws Throwable {
+ return target.invokeVarargs(arguments);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * Give a method handle which will invoke any method handle of the
+ * Produce a method handle which will invoke any method handle of the
* given type on a standard set of {@code Object} type arguments.
- * The the resulting invoker will be a method handle with the following
+ * The resulting invoker will be a method handle with the following
* arguments:
* <ul>
* <li>a single {@code MethodHandle} target
- * <li>zero or more {@code Object} values
- * <li>an optional {@code Object[]} array containing more arguments
+ * <li>zero or more {@code Object} values (one for each argument in {@code type})
* </ul>
- * The invoker will spread the varargs array (if present), apply
+ * The invoker will apply reference casts as necessary and unbox primitive arguments,
+ * as if by {@link #convertArguments}.
+ * The return value of the invoker will be an {@code Object} reference,
+ * boxing a primitive value if the original type returns a primitive,
+ * and always null if the original type returns void.
+ * <p>
+ * This method is equivalent to the following code (though it may be more efficient):
+ * <p><blockquote><pre>
+ * MethodHandle invoker = exactInvoker(type);
+ * MethodType genericType = type.generic();
+ * genericType = genericType.insertParameterType(0, MethodHandle.class);
+ * return convertArguments(invoker, genericType);
+ * </pre></blockquote>
+ * @param type the type of target methods which the invoker will apply to
+ * @return a method handle suitable for invoking any method handle of the given type
+ */
+ static public
+ MethodHandle genericInvoker(MethodType type) {
+ return invokers(type).genericInvoker();
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce a method handle which will invoke any method handle of the
+ * given type on a standard set of {@code Object} type arguments
+ * and a single trailing {@code Object[]} array.
+ * The resulting invoker will be a method handle with the following
+ * arguments:
+ * <ul>
+ * <li>a single {@code MethodHandle} target
+ * <li>zero or more {@code Object} values (counted by {@code objectArgCount})
+ * <li>an {@code Object[]} array containing more arguments
+ * </ul>
+ * The invoker will spread the varargs array, apply
* reference casts as necessary, and unbox primitive arguments.
* The return value of the invoker will be an {@code Object} reference,
* boxing a primitive value if the original type returns a primitive,
* and always null if the original type returns void.
* <p>
- * This is a convenience method equivalent to the following code:
- * <pre>
+ * This method is equivalent to the following code (though it may be more efficient):
+ * <p><blockquote><pre>
* MethodHandle invoker = exactInvoker(type);
- * MethodType genericType = MethodType.makeGeneric(objectArgCount, varargs);
- * genericType = genericType.insertParameterType(0, MethodHandle.class);
- * if (!varargs)
- * return convertArguments(invoker, genericType);
- * else
- * return spreadArguments(invoker, genericType);
- * </pre>
+ * MethodType vaType = MethodType.makeGeneric(objectArgCount, true);
+ * vaType = vaType.insertParameterType(0, MethodHandle.class);
+ * return spreadArguments(invoker, vaType);
+ * </pre></blockquote>
* @param type the desired target type
* @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
- * @param varargs if true, the invoker will accept a final {@code Object[]} argument
* @return a method handle suitable for invoking any method handle of the given type
*/
static public
- MethodHandle genericInvoker(MethodType type, int objectArgCount, boolean varargs) {
- return invokers(type).genericInvoker();
+ MethodHandle varargsInvoker(MethodType type, int objectArgCount) {
+ if (objectArgCount < 0 || objectArgCount > type.parameterCount())
+ throw new IllegalArgumentException("bad argument count "+objectArgCount);
+ return invokers(type).varargsInvoker(objectArgCount);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * Give a method handle which will take a invoke any method handle of the
+ * Produce a method handle which will take a invoke any method handle of the
* given type. The resulting invoker will have a type which is
* exactly equal to the desired type, except that it will accept
* an additional leading argument of type {@code MethodHandle}.
* <p>
- * This is a convenience method equivalent to the following code:
- * <pre>
- * MethodHandles.lookup().findVirtual(MethodHandle.class, "invoke", type);
- * </pre>
+ * This method is equivalent to the following code (though it may be more efficient):
+ * <p><blockquote><pre>
+ * lookup().findVirtual(MethodHandle.class, "invoke", type);
+ * </pre></blockquote>
* @param type the desired target type
* @return a method handle suitable for invoking any method handle of the given type
*/
@@ -612,7 +649,30 @@
return invokers(type).exactInvoker();
}
- static private Invokers invokers(MethodType type) {
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Produce a method handle equivalent to an invokedynamic instruction
+ * which has been linked to the given call site.
+ * Along with {@link Lookup#findVirtual}, {@link Lookup#findStatic},
+ * and {@link Lookup#findSpecial}, this completes the emulation
+ * of the JVM's {@code invoke} instructions.
+ * <p>This method is equivalent to the following code:
+ * <p><blockquote><pre>
+ * MethodHandle getTarget, invoker, result;
+ * getTarget = lookup().bind(site, "getTarget", methodType(MethodHandle.class));
+ * invoker = exactInvoker(site.type());
+ * result = foldArguments(invoker, getTarget)
+ * </pre></blockquote>
+ * @return a method handle which always invokes the call site's target
+ */
+ public static
+ MethodHandle dynamicInvoker(CallSite site) {
+ MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, CallSite.GET_TARGET, site);
+ MethodHandle invoker = exactInvoker(site.type());
+ return foldArguments(invoker, getTarget);
+ }
+
+ static Invokers invokers(MethodType type) {
return MethodTypeImpl.invokers(IMPL_TOKEN, type);
}
@@ -688,14 +748,11 @@
/// method handle modification (creation from other method handles)
/**
- * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
- * given method handle to a new type, by pairwise argument conversion,
- * and/or varargs conversion.
- * The original type and new type must have the same number of
- * arguments, or else one or both them the must be varargs types.
+ * given method handle to a new type by pairwise argument conversion.
+ * The original type and new type must have the same number of arguments.
* The resulting method handle is guaranteed to confess a type
- * which is equal to the desired new type, with any varargs property erased.
+ * which is equal to the desired new type.
* <p>
* If the original type and new type are equal, returns target.
* <p>
@@ -703,26 +760,15 @@
* arguments and return types. Let T0 and T1 be the differing
* new and old parameter types (or old and new return types)
* for corresponding values passed by the new and old method types.
- * <p>
- * If an ordinary (non-varargs) parameter of the new type is
- * to be boxed in a varargs parameter of the old type of type T1[],
- * then T1 is the element type of the varargs array.
- * Otherwise, if a varargs parameter of the new type of type T0[]
- * is to be spread into one or more outgoing old type parameters,
- * then T0 is the element type of the
- * If the new type is varargs and the old type is not, the varargs
- * argument will be checked and must be a non-null array of exactly
- * the right length. If there are no parameters in the old type
- * corresponding to the new varargs parameter, the varargs argument
- * is also allowed to be null.
- * <p>
* Given those types T0, T1, one of the following conversions is applied
* if possible:
* <ul>
- * <li>If T0 and T1 are references, then a cast to T2 is applied,
- * where T2 is Object if T1 is an interface, else T1.
- * (The types do not need to be related in any particular way.
- * The treatment of interfaces follows the usage of the bytecode verifier.)
+ * <li>If T0 and T1 are references, and T1 is not an interface type,
+ * then a cast to T1 is applied.
+ * (The types do not need to be related in any particular way.)
+ * <li>If T0 and T1 are references, and T1 is an interface type,
+ * then the value of type T0 is passed as a T1 without a cast.
+ * (This treatment of interfaces follows the usage of the bytecode verifier.)
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* <li>If T0 and T1 are primitives and one is boolean,
@@ -745,16 +791,17 @@
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
- * <li>If T1 is void, any returned value is discarded
- * <li>If T0 is void and T1 a reference, a null value is introduced.
- * <li>If T0 is void and T1 a primitive, a zero value is introduced.
+ * <li>If the return type T1 is void, any returned value is discarded
+ * <li>If the return type T0 is void and T1 a reference, a null value is introduced.
+ * <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
* </ul>
* @param target the method handle to invoke after arguments are retyped
* @param newType the expected type of the new method handle
* @return a method handle which delegates to {@code target} after performing
* any necessary argument conversions, and arranges for any
* necessary return value conversions
- * @throws WrongMethodTypeException if the conversion cannot be made
+ * @throws IllegalArgumentException if the conversion cannot be made
+ * @see MethodHandle#asType
*/
public static
MethodHandle convertArguments(MethodHandle target, MethodType newType) {
@@ -872,23 +919,17 @@
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* given method handle to a new type, by collecting a series of
- * trailing arguments into an array.
- * The resulting method handle is guaranteed to confess a type
- * which is equal to the desired new type.
+ * trailing arguments as elements to a single argument array.
* <p>
- * This method is inverse to {@link #spreadArguments}.
+ * This method may be used as an inverse to {@link #spreadArguments}.
* The final parameter type of the old type must be an array type T[],
* which is the type of what is called the <i>spread</i> argument.
* The trailing arguments of the new type which correspond to
* the spread argument are all converted to type T and collected
* into an array before the original method is called.
- * <p>
- * ISSUE: Unify this with combineArguments. CollectArguments
- * is combineArguments with (a) new Object[]{...} as a combiner,
- * and (b) the combined arguments dropped, in favor of the combined result.
* @param target the method handle to invoke after the argument is prepended
* @param newType the expected type of the new method handle
- * @return a new method handle which collects some trailings argument
+ * @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
*/
public static
@@ -900,50 +941,72 @@
int numCollect = (inargs - collectPos);
if (collectPos < 0 || numCollect < 0)
throw newIllegalArgumentException("wrong number of arguments");
- return MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos);
+ MethodHandle res = MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos, null);
+ if (res == null) {
+ throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
+ }
+ return res;
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * Produce a method handle which calls the original method handle,
- * after inserting the given argument at the given position.
- * The type of the new method handle will drop the corresponding argument
- * type from the original handle's type.
+ * Produce a method handle which calls the original method handle {@code target},
+ * after inserting the given argument(s) at the given position.
+ * The formal parameters to {@code target} which will be supplied by those
+ * arguments are called <em>bound parameters</em>, because the new method
+ * will contain bindings for those parameters take from {@code values}.
+ * The type of the new method handle will drop the types for the bound
+ * parameters from the original target type, since the new method handle
+ * will no longer require those arguments to be supplied by its callers.
* <p>
- * The given argument object must match the dropped argument type.
- * If the dropped argument type is a primitive, the argument object
- * must be a wrapper, and is unboxed to produce the primitive.
+ * Each given argument object must match the corresponding bound parameter type.
+ * If a bound parameter type is a primitive, the argument object
+ * must be a wrapper, and will be unboxed to produce the primitive value.
* <p>
* The <i>pos</i> may range between zero and <i>N</i> (inclusively),
- * where <i>N</i> is the number of argument types in <i>target</i>,
- * meaning to insert the new argument as the first or last (respectively),
- * or somewhere in between.
+ * where <i>N</i> is the number of argument types in resulting method handle
+ * (after bound parameter types are dropped).
* @param target the method handle to invoke after the argument is inserted
* @param pos where to insert the argument (zero for the first)
- * @param value the argument to insert
+ * @param values the series of arguments to insert
* @return a new method handle which inserts an additional argument,
* before calling the original method handle
*/
public static
- MethodHandle insertArgument(MethodHandle target, int pos, Object value) {
+ MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
+ int insCount = values.length;
MethodType oldType = target.type();
ArrayList<Class<?>> ptypes =
new ArrayList<Class<?>>(oldType.parameterList());
int outargs = oldType.parameterCount();
- int inargs = outargs - 1;
- if (pos < 0 || pos >= outargs)
+ int inargs = outargs - insCount;
+ if (inargs < 0)
+ throw newIllegalArgumentException("too many values to insert");
+ if (pos < 0 || pos > inargs)
throw newIllegalArgumentException("no argument type to append");
- Class<?> valueType = ptypes.remove(pos);
- value = checkValue(valueType, value);
- if (pos == 0 && !valueType.isPrimitive()) {
- // At least for now, make bound method handles a special case.
- // This lets us get by with minimal JVM support, at the expense
- // of generating signature-specific adapters as Java bytecodes.
- MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, target, value);
- if (bmh != null) return bmh;
- // else fall through to general adapter machinery
+ MethodHandle result = target;
+ for (int i = 0; i < insCount; i++) {
+ Object value = values[i];
+ Class<?> valueType = oldType.parameterType(pos+i);
+ value = checkValue(valueType, value);
+ if (pos == 0 && !valueType.isPrimitive()) {
+ // At least for now, make bound method handles a special case.
+ MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, result, value);
+ if (bmh != null) {
+ result = bmh;
+ continue;
+ }
+ // else fall through to general adapter machinery
+ }
+ result = MethodHandleImpl.bindArgument(IMPL_TOKEN, result, pos, value);
}
- return MethodHandleImpl.bindArgument(IMPL_TOKEN, target, pos, value);
+ return result;
+ }
+
+ @Deprecated // "use MethodHandles.insertArguments instead"
+ public static
+ MethodHandle insertArgument(MethodHandle target, int pos, Object value) {
+ return insertArguments(target, pos, value);
}
/**
@@ -953,10 +1016,25 @@
* The type of the new method handle will insert the given argument
* type(s), at that position, into the original handle's type.
* <p>
- * The <i>pos</i> may range between zero and <i>N-1</i>,
+ * The <i>pos</i> may range between zero and <i>N</i>,
* where <i>N</i> is the number of argument types in <i>target</i>,
* meaning to drop the first or last argument (respectively),
* or an argument somewhere in between.
+ * <p>
+ * <b>Example:</b>
+ * <p><blockquote><pre>
+ * MethodHandle cat = MethodHandles.lookup().
+ * findVirtual(String.class, "concat", String.class, String.class);
+ * System.out.println(cat.<String>invoke("x", "y")); // xy
+ * MethodHandle d0 = dropArguments(cat, 0, String.class);
+ * System.out.println(d0.<String>invoke("x", "y", "z")); // xy
+ * MethodHandle d1 = dropArguments(cat, 1, String.class);
+ * System.out.println(d1.<String>invoke("x", "y", "z")); // xz
+ * MethodHandle d2 = dropArguments(cat, 2, String.class);
+ * System.out.println(d2.<String>invoke("x", "y", "z")); // yz
+ * MethodHandle d12 = dropArguments(cat, 1, String.class, String.class);
+ * System.out.println(d12.<String>invoke("w", "x", "y", "z")); // wz
+ * </pre></blockquote>
* @param target the method handle to invoke after the argument is dropped
* @param valueTypes the type(s) of the argument to drop
* @param pos which argument to drop (zero for the first)
@@ -964,20 +1042,150 @@
* before calling the original method handle
*/
public static
- MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
- if (valueTypes.length == 0) return target;
+ MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
+ if (valueTypes.size() == 0) return target;
MethodType oldType = target.type();
int outargs = oldType.parameterCount();
- int inargs = outargs + valueTypes.length;
+ int inargs = outargs + valueTypes.size();
if (pos < 0 || pos >= inargs)
throw newIllegalArgumentException("no argument type to remove");
ArrayList<Class<?>> ptypes =
new ArrayList<Class<?>>(oldType.parameterList());
- ptypes.addAll(pos, Arrays.asList(valueTypes));
- MethodType newType = MethodType.make(oldType.returnType(), ptypes);
+ ptypes.addAll(pos, valueTypes);
+ MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
return MethodHandleImpl.dropArguments(IMPL_TOKEN, target, newType, pos);
}
+ public static
+ MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
+ return dropArguments(target, pos, Arrays.asList(valueTypes));
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Adapt a target method handle {@code target} by pre-processing
+ * one or more of its arguments, each with its own unary filter function,
+ * and then calling the target with each pre-processed argument
+ * replaced by the result of its corresponding filter function.
+ * <p>
+ * The pre-processing is performed by one or more method handles,
+ * specified in the non-null elements of the {@code filters} array.
+ * (If there are no such elements, the original target is returned.)
+ * Each filter (that is, each non-null element of {@code filters})
+ * is applied to the corresponding argument of the adapter.
+ * <p>
+ * If a filter {@code F} applies to the {@code N}th argument of
+ * the method handle, then {@code F} must be a method handle which
+ * takes exactly one argument. The type of {@code F}'s sole argument
+ * replaces the corresponding argument type of the target
+ * in the resulting adapted method handle.
+ * The return type of {@code F} must be identical to the corresponding
+ * parameter type of the target.
+ * <p>
+ * It is an error if there are non-null elements of {@code filters}
+ * which do not correspond to argument positions in the target.
+ * The actual length of the target array may be any number, it need
+ * not be the same as the parameter count of the target type.
+ * (This provides an easy way to filter just the first argument or two
+ * of a target method handle.)
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>
+ * // there are N arguments in the A sequence
+ * T target(A[N]...);
+ * [i<N] V[i] filter[i](B[i]) = filters[i] ?: identity;
+ * T adapter(B[N]... b) {
+ * A[N] a...;
+ * [i<N] a[i] = filter[i](b[i]);
+ * return target(a...);
+ * }
+ * </pre></blockquote>
+ * @param target the method handle to invoke after arguments are filtered
+ * @param filters method handles to call initially on filtered arguments
+ * @return method handle which incorporates the specified argument filtering logic
+ * @throws IllegalArgumentException if a non-null element of {@code filters}
+ * does not match a corresponding argument type of {@code target}
+ */
+ public static
+ MethodHandle filterArguments(MethodHandle target, MethodHandle... filters) {
+ MethodType targetType = target.type();
+ MethodHandle adapter = target;
+ MethodType adapterType = targetType;
+ int pos = -1, maxPos = targetType.parameterCount();
+ for (MethodHandle filter : filters) {
+ pos += 1;
+ if (filter == null) continue;
+ if (pos >= maxPos)
+ throw newIllegalArgumentException("too many filters");
+ MethodType filterType = filter.type();
+ if (filterType.parameterCount() != 1
+ || filterType.returnType() != targetType.parameterType(pos))
+ throw newIllegalArgumentException("target and filter types do not match");
+ adapterType = adapterType.changeParameterType(pos, filterType.parameterType(0));
+ adapter = MethodHandleImpl.filterArgument(IMPL_TOKEN, adapter, pos, filter);
+ }
+ MethodType midType = adapter.type();
+ if (midType != adapterType)
+ adapter = MethodHandleImpl.convertArguments(IMPL_TOKEN, adapter, adapterType, midType, null);
+ return adapter;
+ }
+
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * Adapt a target method handle {@code target} by pre-processing
+ * some of its arguments, and then calling the target with
+ * the result of the pre-processing, plus all original arguments.
+ * <p>
+ * The pre-processing is performed by a second method handle, the {@code combiner}.
+ * The first {@code N} arguments passed to the adapter,
+ * are copied to the combiner, which then produces a result.
+ * (Here, {@code N} is defined as the parameter count of the adapter.)
+ * After this, control passes to the {@code target}, with both the result
+ * of the combiner, and all the original incoming arguments.
+ * <p>
+ * The first argument type of the target must be identical with the
+ * return type of the combiner.
+ * The resulting adapter is the same type as the target, except that the
+ * initial argument type of the target is dropped.
+ * <p>
+ * (Note that {@link #dropArguments} can be used to remove any arguments
+ * that either the {@code combiner} or {@code target} does not wish to receive.
+ * If some of the incoming arguments are destined only for the combiner,
+ * consider using {@link #collectArguments} instead, since those
+ * arguments will not need to be live on the stack on entry to the
+ * target.)
+ * <p>
+ * The first argument of the target must be identical with the
+ * return value of the combiner.
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>
+ * // there are N arguments in the A sequence
+ * T target(V, A[N]..., B...);
+ * V combiner(A...);
+ * T adapter(A... a, B... b) {
+ * V v = combiner(a...);
+ * return target(v, a..., b...);
+ * }
+ * </pre></blockquote>
+ * @param target the method handle to invoke after arguments are combined
+ * @param combiner method handle to call initially on the incoming arguments
+ * @return method handle which incorporates the specified argument folding logic
+ * @throws IllegalArgumentException if the first argument type of
+ * {@code target} is not the same as {@code combiner}'s return type,
+ * or if the next {@code foldArgs} argument types of {@code target}
+ * are not identical with the argument types of {@code combiner}
+ */
+ public static
+ MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
+ MethodType targetType = target.type();
+ MethodType combinerType = combiner.type();
+ int foldArgs = combinerType.parameterCount();
+ boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
+ if (!ok)
+ throw misMatchedTypes("target and combiner types", targetType, combinerType);
+ MethodType newType = targetType.dropParameterTypes(0, 1);
+ return MethodHandleImpl.foldArguments(IMPL_TOKEN, target, newType, combiner);
+ }
+
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Make a method handle which adapts a target method handle,
@@ -985,18 +1193,18 @@
* If the guard fails, a fallback handle is called instead.
* All three method handles must have the same corresponding
* argument and return types, except that the return type
- * of the test must be boolean.
+ * of the test must be boolean, and the test is allowed
+ * to have fewer arguments than the other two method handles.
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
- * signature T(A...);
* boolean test(A...);
- * T target(A...);
- * T fallback(A...);
- * T adapter(A... a) {
+ * T target(A...,B...);
+ * T fallback(A...,B...);
+ * T adapter(A... a,B... b) {
* if (test(a...))
- * return target(a...);
+ * return target(a..., b...);
* else
- * return fallback(a...);
+ * return fallback(a..., b...);
* }
* </pre></blockquote>
* @param test method handle used for test, must return boolean
@@ -1011,10 +1219,23 @@
MethodHandle guardWithTest(MethodHandle test,
MethodHandle target,
MethodHandle fallback) {
- if (target.type() != fallback.type())
- throw newIllegalArgumentException("target and fallback types do not match");
- if (target.type().changeReturnType(boolean.class) != test.type())
- throw newIllegalArgumentException("target and test types do not match");
+ MethodType gtype = test.type();
+ MethodType ttype = target.type();
+ MethodType ftype = fallback.type();
+ if (ttype != ftype)
+ throw misMatchedTypes("target and fallback types", ttype, ftype);
+ MethodType gtype2 = ttype.changeReturnType(boolean.class);
+ if (gtype2 != gtype) {
+ if (gtype.returnType() != boolean.class)
+ throw newIllegalArgumentException("guard type is not a predicate "+gtype);
+ int gpc = gtype.parameterCount(), tpc = ttype.parameterCount();
+ if (gpc < tpc) {
+ test = dropArguments(test, gpc, ttype.parameterList().subList(gpc, tpc));
+ gtype = test.type();
+ }
+ if (gtype2 != gtype)
+ throw misMatchedTypes("target and test types", ttype, gtype);
+ }
/* {
MethodHandle invoke = findVirtual(MethodHandle.class, "invoke", target.type());
static MethodHandle choose(boolean z, MethodHandle t, MethodHandle f) {
@@ -1027,7 +1248,7 @@
}
// choose = \z.(z ? target : fallback)
MethodHandle choose = findVirtual(MethodHandles.class, "choose",
- MethodType.make(boolean.class, MethodHandle.class, MethodHandle.class));
+ MethodType.methodType(boolean.class, MethodHandle.class, MethodHandle.class));
choose = appendArgument(choose, target);
choose = appendArgument(choose, fallback);
MethodHandle dispatch = compose(choose, test);
@@ -1038,67 +1259,88 @@
return MethodHandleImpl.makeGuardWithTest(IMPL_TOKEN, test, target, fallback);
}
+ static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
+ return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
+ }
+
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * Adapt a target method handle {@code target} by first processing
- * its arguments, and then calling the target.
- * The initial processing is performed by a second method handle, the {@code combiner}.
- * After this, control passes to the {@code target}, with the same arguments.
+ * Make a method handle which adapts a target method handle,
+ * by running it inside an exception handler.
+ * If the target returns normally, the adapter returns that value.
+ * If an exception matching the specified type is thrown, the fallback
+ * handle is called instead on the exception, plus the original arguments.
* <p>
- * The return value of the {@code combiner} is inserted into the argument list
- * for the {@code target} at the indicated position {@code pos}, if it is non-negative.
- * Except for this inserted argument (if any), the argument types of
- * the target {@code target} and the {@code combiner} must be identical.
- * <p>
- * (Note that {@link #dropArguments} can be used to remove any arguments
- * that either the {@code combiner} or {@code target} does not wish to receive.)
- * <p>
- * The combiner handle must have the same argument types as the
- * target handle, but must return {@link MethodHandle} instead of
- * the ultimate return type. The returned method handle, in turn,
- * is required to have exactly the given final method type.
+ * The handler must have leading parameter of {@code exType} or a supertype,
+ * followed by arguments which correspond <em>(how? TBD)</em> to
+ * all the parameters of the target.
+ * The target and handler must return the same type.
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
- * signature V(A[pos]..., B...);
- * signature T(A[pos]..., V, B...);
- * T target(A... a, V v, B... b);
- * V combiner(A..., B...);
- * T adapter(A... a, B... b) {
- * V v = combiner(a..., b...);
- * return target(a..., v, b...);
+ * T target(A...);
+ * T handler(ExType, A...);
+ * T adapter(A... a) {
+ * try {
+ * return target(a...);
+ * } catch (ExType ex) {
+ * return handler(ex, a...);
+ * }
* }
* </pre></blockquote>
- * @param target the method handle to invoke after arguments are combined
- * @param pos where the return value of {@code combiner} is to
- * be inserted as an argument to {@code target}
- * @param combiner method handle to call initially on the incoming arguments
- * @return method handle which incorporates the specified dispatch logic
- * @throws IllegalArgumentException if {@code combiner} does not itself
- * return either void or the {@code pos}-th argument of {@code target},
- * or does not have the same argument types as {@code target}
- * (minus the inserted argument)
+ * @param target method handle to call
+ * @param exType the type of exception which the handler will catch
+ * @param handler method handle to call if a matching exception is thrown
+ * @return method handle which incorporates the specified try/catch logic
+ * @throws IllegalArgumentException if {@code handler} does not accept
+ * the given exception type, or if the method handle types do
+ * not match in their return types and their
+ * corresponding parameters
*/
public static
- MethodHandle combineArguments(MethodHandle target, int pos, MethodHandle combiner) {
- MethodType mhType = target.type();
- Class<?> combineType = combiner.type().returnType();
- MethodType incomingArgs;
- if (pos < 0) {
- // No inserted argument; target & combiner must have same argument types.
- incomingArgs = mhType;
- if (!incomingArgs.changeReturnType(combineType).equals(combiner.type()))
- throw newIllegalArgumentException("target and combiner types do not match");
- } else {
- // Inserted argument.
- if (pos >= mhType.parameterCount()
- || mhType.parameterType(pos) != combineType)
- throw newIllegalArgumentException("inserted combiner argument does not match target");
- incomingArgs = mhType.dropParameterType(pos);
- }
- if (!incomingArgs.changeReturnType(combineType).equals(combiner.type())) {
- throw newIllegalArgumentException("target and combiner types do not match");
- }
- return MethodHandleImpl.combineArguments(IMPL_TOKEN, target, combiner, pos);
+ MethodHandle catchException(MethodHandle target,
+ Class<? extends Throwable> exType,
+ MethodHandle handler) {
+ MethodType targetType = target.type();
+ MethodType handlerType = handler.type();
+ boolean ok = (targetType.parameterCount() ==
+ handlerType.parameterCount() - 1);
+// for (int i = 0; ok && i < numExArgs; i++) {
+// if (targetType.parameterType(i) != handlerType.parameterType(1+i))
+// ok = false;
+// }
+ if (!ok)
+ throw newIllegalArgumentException("target and handler types do not match");
+ return MethodHandleImpl.makeGuardWithCatch(IMPL_TOKEN, target, exType, handler);
}
+ /**
+ * Produce a method handle which will throw exceptions of the given {@code exType}.
+ * The method handle will accept a single argument of {@code exType},
+ * and immediately throw it as an exception.
+ * The method type will nominally specify a return of {@code returnType}.
+ * The return type may be anything convenient: It doesn't matter to the
+ * method handle's behavior, since it will never return normally.
+ */
+ public static
+ MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
+ return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
+ }
+
+ /** Alias for {@link MethodType#methodType}. */
+ @Deprecated // "use MethodType.methodType instead"
+ public static MethodType methodType(Class<?> rtype) {
+ return MethodType.methodType(rtype);
+ }
+
+ /** Alias for {@link MethodType#methodType}. */
+ @Deprecated // "use MethodType.methodType instead"
+ public static MethodType methodType(Class<?> rtype, Class<?> ptype) {
+ return MethodType.methodType(rtype, ptype);
+ }
+
+ /** Alias for {@link MethodType#methodType}. */
+ @Deprecated // "use MethodType.methodType instead"
+ public static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
+ return MethodType.methodType(rtype, ptype0, ptypes);
+ }
}
--- a/jdk/src/share/classes/java/dyn/MethodType.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/MethodType.java Wed Jul 05 17:04:56 2017 +0200
@@ -32,7 +32,7 @@
import sun.dyn.Access;
import sun.dyn.Invokers;
import sun.dyn.MethodTypeImpl;
-import sun.dyn.util.BytecodeSignature;
+import sun.dyn.util.BytecodeDescriptor;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
@@ -63,7 +63,7 @@
static {
// This hack allows the implementation package special access to
- // the internals of MethodType. In particular, the Form has all sorts
+ // the internals of MethodType. In particular, the MTImpl has all sorts
// of cached information useful to the implementation code.
MethodTypeImpl.setMethodTypeFriend(IMPL_TOKEN, new MethodTypeImpl.MethodTypeFriend() {
public Class<?>[] ptypes(MethodType mt) { return mt.ptypes; }
@@ -114,50 +114,75 @@
* @throws IllegalArgumentException if any of the ptypes is void
*/
public static
+ MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
+ return makeImpl(rtype, ptypes, false);
+ }
+ @Deprecated public static
MethodType make(Class<?> rtype, Class<?>[] ptypes) {
- return makeImpl(rtype, ptypes, false);
+ return methodType(rtype, ptypes);
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}. */
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}. */
public static
+ MethodType methodType(Class<?> rtype, List<? extends Class<?>> ptypes) {
+ boolean notrust = false; // random List impl. could return evil ptypes array
+ return makeImpl(rtype, ptypes.toArray(NO_PTYPES), notrust);
+ }
+ @Deprecated public static
MethodType make(Class<?> rtype, List<? extends Class<?>> ptypes) {
- return makeImpl(rtype, ptypes.toArray(NO_PTYPES), true);
+ return methodType(rtype, ptypes);
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The leading parameter type is prepended to the remaining array.
*/
public static
- MethodType make(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
+ MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
ptypes1[0] = ptype0;
System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
return makeImpl(rtype, ptypes1, true);
}
+ @Deprecated public static
+ MethodType make(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
+ return methodType(rtype, ptype0, ptypes);
+ }
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The resulting method has no parameter types.
*/
public static
- MethodType make(Class<?> rtype) {
+ MethodType methodType(Class<?> rtype) {
return makeImpl(rtype, NO_PTYPES, true);
}
+ @Deprecated public static
+ MethodType make(Class<?> rtype) {
+ return methodType(rtype);
+ }
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The resulting method has the single given parameter type.
*/
public static
- MethodType make(Class<?> rtype, Class<?> ptype0) {
+ MethodType methodType(Class<?> rtype, Class<?> ptype0) {
return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
}
+ @Deprecated public static
+ MethodType make(Class<?> rtype, Class<?> ptype0) {
+ return methodType(rtype, ptype0);
+ }
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The resulting method has the same parameter types as {@code ptypes},
* and the specified return type.
*/
public static
+ MethodType methodType(Class<?> rtype, MethodType ptypes) {
+ return makeImpl(rtype, ptypes.ptypes, true);
+ }
+ @Deprecated public static
MethodType make(Class<?> rtype, MethodType ptypes) {
- return makeImpl(rtype, ptypes.ptypes, true);
+ return methodType(rtype, ptypes);
}
/**
@@ -202,15 +227,16 @@
private static final MethodType[] objectOnlyTypes = new MethodType[20];
/**
- * Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
- * All parameters and the return type will be Object, except the final varargs parameter if any.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+ * All parameters and the return type will be {@code Object},
+ * except the final varargs parameter if any, which will be {@code Object[]}.
* @param objectArgCount number of parameters (excluding the varargs parameter if any)
- * @param varargs whether there will be a varargs parameter, of type Object[]
+ * @param varargs whether there will be a varargs parameter, of type {@code Object[]}
* @return a totally generic method type, given only its count of parameters and varargs
- * @see #makeGeneric(int)
+ * @see #genericMethodType(int)
*/
public static
- MethodType makeGeneric(int objectArgCount, boolean varargs) {
+ MethodType genericMethodType(int objectArgCount, boolean varargs) {
MethodType mt;
int ivarargs = (!varargs ? 0 : 1);
int ootIndex = objectArgCount*2 + ivarargs;
@@ -227,19 +253,27 @@
}
return mt;
}
+ @Deprecated public static
+ MethodType makeGeneric(int objectArgCount, boolean varargs) {
+ return genericMethodType(objectArgCount, varargs);
+ }
/**
* All parameters and the return type will be Object.
* @param objectArgCount number of parameters
* @return a totally generic method type, given only its count of parameters
- * @see #makeGeneric(int, boolean)
+ * @see #genericMethodType(int, boolean)
*/
public static
+ MethodType genericMethodType(int objectArgCount) {
+ return genericMethodType(objectArgCount, false);
+ }
+ @Deprecated public static
MethodType makeGeneric(int objectArgCount) {
- return makeGeneric(objectArgCount, false);
+ return genericMethodType(objectArgCount);
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the index (zero-based) of the parameter type to change
* @param nptype a new parameter type to replace the old one with
* @return the same type, except with the selected parameter changed
@@ -251,11 +285,10 @@
return makeImpl(rtype, nptypes, true);
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
- * @param num the position (zero-based) of the inserted parameter type
- * @param nptype a new parameter type to insert into the parameter list
- * @return the same type, except with the selected parameter inserted
+ /** Convenience method for {@link #insertParameterTypes}.
+ * @deprecated Use {@link #insertParameterTypes} instead.
*/
+ @Deprecated
public MethodType insertParameterType(int num, Class<?> nptype) {
int len = ptypes.length;
Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+1);
@@ -264,23 +297,73 @@
return makeImpl(rtype, nptypes, true);
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
- * @param num the index (zero-based) of the parameter type to remove
- * @return the same type, except with the selected parameter removed
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+ * @param num the position (zero-based) of the inserted parameter type(s)
+ * @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) inserted
*/
- public MethodType dropParameterType(int num) {
+ public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
int len = ptypes.length;
+ if (num < 0 || num > len)
+ throw newIllegalArgumentException("num="+num); //SPECME
+ int ilen = ptypesToInsert.length;
+ if (ilen == 0) return this;
+ Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
+ System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
+ System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+ * @param num the position (zero-based) of the inserted parameter type(s)
+ * @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) inserted
+ */
+ public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
+ return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
+ }
+
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+ * @param start the index (zero-based) of the first parameter type to remove
+ * @param end the index (greater than {@code start}) of the first parameter type after not to remove
+ * @return the same type, except with the selected parameter(s) removed
+ */
+ public MethodType dropParameterTypes(int start, int end) {
+ int len = ptypes.length;
+ if (!(0 <= start && start <= end && end <= len))
+ throw newIllegalArgumentException("start="+start+" end="+end); //SPECME
+ if (start == end) return this;
Class<?>[] nptypes;
- if (num == 0) {
- nptypes = Arrays.copyOfRange(ptypes, 1, len);
+ if (start == 0) {
+ if (end == len) {
+ // drop all parameters
+ nptypes = NO_PTYPES;
+ } else {
+ // drop initial parameter(s)
+ nptypes = Arrays.copyOfRange(ptypes, end, len);
+ }
} else {
- nptypes = Arrays.copyOfRange(ptypes, 0, len-1);
- System.arraycopy(ptypes, num+1, nptypes, num, (len-1)-num);
+ if (end == len) {
+ // drop trailing parameter(s)
+ nptypes = Arrays.copyOfRange(ptypes, 0, start);
+ } else {
+ int tail = len - end;
+ nptypes = Arrays.copyOfRange(ptypes, 0, start + tail);
+ System.arraycopy(ptypes, end, nptypes, start, tail);
+ }
}
return makeImpl(rtype, nptypes, true);
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
+ /** Convenience method for {@link #dropParameterTypes}.
+ * @deprecated Use {@link #dropParameterTypes} instead.
+ */
+ @Deprecated
+ public MethodType dropParameterType(int num) {
+ return dropParameterTypes(num, num+1);
+ }
+
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param nrtype a return parameter type to replace the old one with
* @return the same type, except with the return type change
*/
@@ -291,6 +374,7 @@
/** Convenience method.
* Report if this type contains a primitive argument or return value.
+ * The return type {@code void} counts as a primitive.
* @return true if any of the types are primitives
*/
public boolean hasPrimitives() {
@@ -300,39 +384,47 @@
/** Convenience method.
* Report if this type contains a wrapper argument or return value.
* Wrappers are types which box primitive values, such as {@link Integer}.
+ * The reference type {@code java.lang.Void} counts as a wrapper.
* @return true if any of the types are wrappers
*/
public boolean hasWrappers() {
return unwrap() != this;
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
- * Erase all reference types to Object.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+ * Erase all reference types to {@code Object}.
+ * All primitive types (including {@code void}) will remain unchanged.
* @return a version of the original type with all reference types replaced
*/
public MethodType erase() {
return form.erasedType();
}
- /** Convenience method for {@link #makeGeneric(int)}.
- * Convert all types, both reference and primitive, to Object.
+ /** Convenience method for {@link #genericMethodType(int)}.
+ * Convert all types, both reference and primitive, to {@code Object}.
+ * The expression {@code type.wrap().erase()} produces the same value
+ * as {@code type.generic()}.
* @return a version of the original type with all types replaced
*/
public MethodType generic() {
- return makeGeneric(parameterCount());
+ return genericMethodType(parameterCount());
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Convert all primitive types to their corresponding wrapper types.
+ * All reference types (including wrapper types) will remain unchanged.
* A {@code void} return type is changed to the type {@code java.lang.Void}.
+ * The expression {@code type.wrap().erase()} produces the same value
+ * as {@code type.generic()}.
* @return a version of the original type with all primitive types replaced
*/
public MethodType wrap() {
return hasPrimitives() ? wrapWithPrims(this) : this;
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Convert all wrapper types to their corresponding primitive types.
+ * All primitive types (including {@code void}) will remain unchanged.
* A return type of {@code java.lang.Void} is changed to {@code void}.
* @return a version of the original type with all wrapper types replaced
*/
@@ -391,6 +483,7 @@
/**
* Convenience method to present the arguments as an array.
+ * Changes to the array will not result in changes to the type.
* @return the parameter types (as a fresh copy if necessary)
*/
public Class<?>[] parameterArray() {
@@ -491,7 +584,7 @@
return form.parameterSlotCount();
}
- /** Number of JVM stack slots which carry all parameters after
+ /** Number of JVM stack slots which carry all parameters including and after
* the given position, which must be in the range of 0 to
* {@code parameterCount} inclusive. Successive parameters are
* more shallowly stacked, and parameters are indexed in the bytecodes
@@ -532,7 +625,7 @@
return form.returnSlotCount();
}
- /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
+ /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Find or create an instance (interned) of the given method type.
* Any class or interface name embedded in the signature string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
@@ -544,16 +637,16 @@
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
- * @param bytecodeSignature a bytecode-level signature string "(T...)T"
+ * @param descriptor a bytecode-level signature string "(T...)T"
* @param loader the class loader in which to look up the types
* @return a method type matching the bytecode-level signature
* @throws IllegalArgumentException if the string is not well-formed
* @throws TypeNotPresentException if a named type cannot be found
*/
- public static MethodType fromBytecodeString(String bytecodeSignature, ClassLoader loader)
+ public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
throws IllegalArgumentException, TypeNotPresentException
{
- List<Class<?>> types = BytecodeSignature.parseMethod(bytecodeSignature, loader);
+ List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
Class<?> rtype = types.remove(types.size() - 1);
Class<?>[] ptypes = types.toArray(NO_PTYPES);
return makeImpl(rtype, ptypes, true);
@@ -565,11 +658,21 @@
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
- * {@link #fromBytecodeString(java.lang.String, java.lang.ClassLoader)},
+ * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader)},
* because the latter requires a suitable class loader argument.
* @return the bytecode signature representation
*/
+ public String toMethodDescriptorString() {
+ return BytecodeDescriptor.unparse(this);
+ }
+
+ /** Temporary alias for toMethodDescriptorString; delete after M3. */
public String toBytecodeString() {
- return BytecodeSignature.unparse(this);
+ return toMethodDescriptorString();
+ }
+ /** Temporary alias for fromMethodDescriptorString; delete after M3. */
+ public static MethodType fromBytecodeString(String descriptor, ClassLoader loader)
+ throws IllegalArgumentException, TypeNotPresentException {
+ return fromMethodDescriptorString(descriptor, loader);
}
}
--- a/jdk/src/share/classes/java/dyn/package-info.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/dyn/package-info.java Wed Jul 05 17:04:56 2017 +0200
@@ -24,6 +24,7 @@
*/
/**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* This package contains dynamic language support provided directly by
* the Java core class libraries and virtual machine.
* @author John Rose, JSR 292 EG
--- a/jdk/src/share/classes/java/lang/StrictMath.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/lang/StrictMath.java Wed Jul 05 17:04:56 2017 +0200
@@ -26,6 +26,7 @@
package java.lang;
import java.util.Random;
import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
/**
* The class {@code StrictMath} contains methods for performing basic
@@ -316,7 +317,9 @@
* floating-point value that is greater than or equal to
* the argument and is equal to a mathematical integer.
*/
- public static native double ceil(double a);
+ public static double ceil(double a) {
+ return floorOrCeil(a, -0.0, 1.0, 1.0);
+ }
/**
* Returns the largest (closest to positive infinity)
@@ -333,7 +336,54 @@
* floating-point value that less than or equal to the argument
* and is equal to a mathematical integer.
*/
- public static native double floor(double a);
+ public static double floor(double a) {
+ return floorOrCeil(a, -1.0, 0.0, -1.0);
+ }
+
+ /**
+ * Internal method to share logic between floor and ceil.
+ *
+ * @param a the value to be floored or ceiled
+ * @param negativeBoundary result for values in (-1, 0)
+ * @param positiveBoundary result for values in (0, 1)
+ * @param increment value to add when the argument is non-integral
+ */
+ private static double floorOrCeil(double a,
+ double negativeBoundary,
+ double positiveBoundary,
+ double sign) {
+ int exponent = Math.getExponent(a);
+
+ if (exponent < 0) {
+ /*
+ * Absolute value of argument is less than 1.
+ * floorOrceil(-0.0) => -0.0
+ * floorOrceil(+0.0) => +0.0
+ */
+ return ((a == 0.0) ? a :
+ ( (a < 0.0) ? negativeBoundary : positiveBoundary) );
+ } else if (exponent >= 52) {
+ /*
+ * Infinity, NaN, or a value so large it must be integral.
+ */
+ return a;
+ }
+ // Else the argument is either an integral value already XOR it
+ // has to be rounded to one.
+ assert exponent >= 0 && exponent <= 51;
+
+ long doppel = Double.doubleToRawLongBits(a);
+ long mask = DoubleConsts.SIGNIF_BIT_MASK >> exponent;
+
+ if ( (mask & doppel) == 0L )
+ return a; // integral value
+ else {
+ double result = Double.longBitsToDouble(doppel & (~mask));
+ if (sign*a > 0.0)
+ result = result + sign;
+ return result;
+ }
+ }
/**
* Returns the {@code double} value that is closest in value
--- a/jdk/src/share/classes/java/lang/management/PlatformManagedObject.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/lang/management/PlatformManagedObject.java Wed Jul 05 17:04:56 2017 +0200
@@ -32,7 +32,7 @@
* for monitoring and managing a component in the Java platform.
* Each platform managed object has a unique
* <a href="ManagementFactory.html#MXBean">object name</a>
- * for the {@linkplain ManagementFactory.getPlatformMBeanServer
+ * for the {@linkplain ManagementFactory#getPlatformMBeanServer
* platform MBeanServer} access.
* All platform MXBeans will implement this interface.
*
--- a/jdk/src/share/classes/java/nio/X-Buffer.java.template Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/nio/X-Buffer.java.template Wed Jul 05 17:04:56 2017 +0200
@@ -32,24 +32,24 @@
#end[char]
/**
- * $A$ $fulltype$ buffer.
+ * $A$ $type$ buffer.
*
* <p> This class defines {#if[byte]?six:four} categories of operations upon
- * $fulltype$ buffers:
+ * $type$ buffers:
*
* <ul>
*
* <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
* {@link #put($type$) </code><i>put</i><code>} methods that read and write
- * single $fulltype$s; </p></li>
+ * single $type$s; </p></li>
*
* <li><p> Relative {@link #get($type$[]) </code><i>bulk get</i><code>}
- * methods that transfer contiguous sequences of $fulltype$s from this buffer
+ * methods that transfer contiguous sequences of $type$s from this buffer
* into an array; {#if[!byte]?and}</p></li>
*
* <li><p> Relative {@link #put($type$[]) </code><i>bulk put</i><code>}
- * methods that transfer contiguous sequences of $fulltype$s from $a$
- * $fulltype$ array{#if[char]?, a string,} or some other $fulltype$
+ * methods that transfer contiguous sequences of $type$s from $a$
+ * $type$ array{#if[char]?, a string,} or some other $type$
* buffer into this buffer;{#if[!byte]? and} </p></li>
*
#if[byte]
@@ -67,22 +67,22 @@
*
* <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
* #duplicate </code>duplicating<code>}, and {@link #slice
- * </code>slicing<code>} $a$ $fulltype$ buffer. </p></li>
+ * </code>slicing<code>} $a$ $type$ buffer. </p></li>
*
* </ul>
*
- * <p> $Fulltype$ buffers can be created either by {@link #allocate
+ * <p> $Type$ buffers can be created either by {@link #allocate
* </code><i>allocation</i><code>}, which allocates space for the buffer's
*
#if[byte]
*
* content, or by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an
- * existing $fulltype$ array {#if[char]?or string} into a buffer.
+ * existing $type$ array {#if[char]?or string} into a buffer.
*
#else[byte]
*
* content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing
- * $fulltype$ array {#if[char]?or string} into a buffer, or by creating a
+ * $type$ array {#if[char]?or string} into a buffer, or by creating a
* <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
*
#end[byte]
@@ -189,12 +189,12 @@
*
#if[!byte]
*
- * <p> Like a byte buffer, $a$ $fulltype$ buffer is either <a
+ * <p> Like a byte buffer, $a$ $type$ buffer is either <a
* href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
- * $fulltype$ buffer created via the <tt>wrap</tt> methods of this class will
- * be non-direct. $A$ $fulltype$ buffer created as a view of a byte buffer will
+ * $type$ buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. $A$ $type$ buffer created as a view of a byte buffer will
* be direct if, and only if, the byte buffer itself is direct. Whether or not
- * $a$ $fulltype$ buffer is direct may be determined by invoking the {@link
+ * $a$ $type$ buffer is direct may be determined by invoking the {@link
* #isDirect isDirect} method. </p>
*
#end[!byte]
@@ -287,7 +287,7 @@
#if[byte]
/**
- * Allocates a new direct $fulltype$ buffer.
+ * Allocates a new direct $type$ buffer.
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
@@ -295,9 +295,9 @@
* {@link #hasArray </code>backing array<code>} is unspecified.
*
* @param capacity
- * The new buffer's capacity, in $fulltype$s
+ * The new buffer's capacity, in $type$s
*
- * @return The new $fulltype$ buffer
+ * @return The new $type$ buffer
*
* @throws IllegalArgumentException
* If the <tt>capacity</tt> is a negative integer
@@ -309,7 +309,7 @@
#end[byte]
/**
- * Allocates a new $fulltype$ buffer.
+ * Allocates a new $type$ buffer.
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
@@ -318,9 +318,9 @@
* offset<code>} will be zero.
*
* @param capacity
- * The new buffer's capacity, in $fulltype$s
+ * The new buffer's capacity, in $type$s
*
- * @return The new $fulltype$ buffer
+ * @return The new $type$ buffer
*
* @throws IllegalArgumentException
* If the <tt>capacity</tt> is a negative integer
@@ -332,9 +332,9 @@
}
/**
- * Wraps $a$ $fulltype$ array into a buffer.
+ * Wraps $a$ $type$ array into a buffer.
*
- * <p> The new buffer will be backed by the given $fulltype$ array;
+ * <p> The new buffer will be backed by the given $type$ array;
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity will be
* <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
@@ -356,7 +356,7 @@
* <tt>array.length - offset</tt>.
* The new buffer's limit will be set to <tt>offset + length</tt>.
*
- * @return The new $fulltype$ buffer
+ * @return The new $type$ buffer
*
* @throws IndexOutOfBoundsException
* If the preconditions on the <tt>offset</tt> and <tt>length</tt>
@@ -373,9 +373,9 @@
}
/**
- * Wraps $a$ $fulltype$ array into a buffer.
+ * Wraps $a$ $type$ array into a buffer.
*
- * <p> The new buffer will be backed by the given $fulltype$ array;
+ * <p> The new buffer will be backed by the given $type$ array;
* that is, modifications to the buffer will cause the array to be modified
* and vice versa. The new buffer's capacity and limit will be
* <tt>array.length</tt>, its position will be zero, and its mark will be
@@ -386,7 +386,7 @@
* @param array
* The array that will back this buffer
*
- * @return The new $fulltype$ buffer
+ * @return The new $type$ buffer
*/
public static $Type$Buffer wrap($type$[] array) {
return wrap(array, 0, array.length);
@@ -486,7 +486,7 @@
#end[char]
/**
- * Creates a new $fulltype$ buffer whose content is a shared subsequence of
+ * Creates a new $type$ buffer whose content is a shared subsequence of
* this buffer's content.
*
* <p> The content of the new buffer will start at this buffer's current
@@ -495,17 +495,17 @@
* values will be independent.
*
* <p> The new buffer's position will be zero, its capacity and its limit
- * will be the number of $fulltype$s remaining in this buffer, and its mark
+ * will be the number of $type$s remaining in this buffer, and its mark
* will be undefined. The new buffer will be direct if, and only if, this
* buffer is direct, and it will be read-only if, and only if, this buffer
* is read-only. </p>
*
- * @return The new $fulltype$ buffer
+ * @return The new $type$ buffer
*/
public abstract $Type$Buffer slice();
/**
- * Creates a new $fulltype$ buffer that shares this buffer's content.
+ * Creates a new $type$ buffer that shares this buffer's content.
*
* <p> The content of the new buffer will be that of this buffer. Changes
* to this buffer's content will be visible in the new buffer, and vice
@@ -517,12 +517,12 @@
* and only if, this buffer is direct, and it will be read-only if, and
* only if, this buffer is read-only. </p>
*
- * @return The new $fulltype$ buffer
+ * @return The new $type$ buffer
*/
public abstract $Type$Buffer duplicate();
/**
- * Creates a new, read-only $fulltype$ buffer that shares this buffer's
+ * Creates a new, read-only $type$ buffer that shares this buffer's
* content.
*
* <p> The content of the new buffer will be that of this buffer. Changes
@@ -537,7 +537,7 @@
* <p> If this buffer is itself read-only then this method behaves in
* exactly the same way as the {@link #duplicate duplicate} method. </p>
*
- * @return The new, read-only $fulltype$ buffer
+ * @return The new, read-only $type$ buffer
*/
public abstract $Type$Buffer asReadOnlyBuffer();
@@ -545,10 +545,10 @@
// -- Singleton get/put methods --
/**
- * Relative <i>get</i> method. Reads the $fulltype$ at this buffer's
+ * Relative <i>get</i> method. Reads the $type$ at this buffer's
* current position, and then increments the position. </p>
*
- * @return The $fulltype$ at the buffer's current position
+ * @return The $type$ at the buffer's current position
*
* @throws BufferUnderflowException
* If the buffer's current position is not smaller than its limit
@@ -558,11 +558,11 @@
/**
* Relative <i>put</i> method <i>(optional operation)</i>.
*
- * <p> Writes the given $fulltype$ into this buffer at the current
+ * <p> Writes the given $type$ into this buffer at the current
* position, and then increments the position. </p>
*
* @param $x$
- * The $fulltype$ to be written
+ * The $type$ to be written
*
* @return This buffer
*
@@ -575,13 +575,13 @@
public abstract $Type$Buffer put($type$ $x$);
/**
- * Absolute <i>get</i> method. Reads the $fulltype$ at the given
+ * Absolute <i>get</i> method. Reads the $type$ at the given
* index. </p>
*
* @param index
- * The index from which the $fulltype$ will be read
+ * The index from which the $type$ will be read
*
- * @return The $fulltype$ at the given index
+ * @return The $type$ at the given index
*
* @throws IndexOutOfBoundsException
* If <tt>index</tt> is negative
@@ -592,14 +592,14 @@
/**
* Absolute <i>put</i> method <i>(optional operation)</i>.
*
- * <p> Writes the given $fulltype$ into this buffer at the given
+ * <p> Writes the given $type$ into this buffer at the given
* index. </p>
*
* @param index
- * The index at which the $fulltype$ will be written
+ * The index at which the $type$ will be written
*
* @param $x$
- * The $fulltype$ value to be written
+ * The $type$ value to be written
*
* @return This buffer
*
@@ -618,14 +618,14 @@
/**
* Relative bulk <i>get</i> method.
*
- * <p> This method transfers $fulltype$s from this buffer into the given
- * destination array. If there are fewer $fulltype$s remaining in the
+ * <p> This method transfers $type$s from this buffer into the given
+ * destination array. If there are fewer $type$s remaining in the
* buffer than are required to satisfy the request, that is, if
* <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
- * $fulltype$s are transferred and a {@link BufferUnderflowException} is
+ * $type$s are transferred and a {@link BufferUnderflowException} is
* thrown.
*
- * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from this
+ * <p> Otherwise, this method copies <tt>length</tt> $type$s from this
* buffer into the given array, starting at the current position of this
* buffer and at the given offset in the array. The position of this
* buffer is then incremented by <tt>length</tt>.
@@ -638,26 +638,26 @@
* for (int i = off; i < off + len; i++)
* dst[i] = src.get(); </pre>
*
- * except that it first checks that there are sufficient $fulltype$s in
+ * except that it first checks that there are sufficient $type$s in
* this buffer and it is potentially much more efficient. </p>
*
* @param dst
- * The array into which $fulltype$s are to be written
+ * The array into which $type$s are to be written
*
* @param offset
- * The offset within the array of the first $fulltype$ to be
+ * The offset within the array of the first $type$ to be
* written; must be non-negative and no larger than
* <tt>dst.length</tt>
*
* @param length
- * The maximum number of $fulltype$s to be written to the given
+ * The maximum number of $type$s to be written to the given
* array; must be non-negative and no larger than
* <tt>dst.length - offset</tt>
*
* @return This buffer
*
* @throws BufferUnderflowException
- * If there are fewer than <tt>length</tt> $fulltype$s
+ * If there are fewer than <tt>length</tt> $type$s
* remaining in this buffer
*
* @throws IndexOutOfBoundsException
@@ -677,7 +677,7 @@
/**
* Relative bulk <i>get</i> method.
*
- * <p> This method transfers $fulltype$s from this buffer into the given
+ * <p> This method transfers $type$s from this buffer into the given
* destination array. An invocation of this method of the form
* <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
*
@@ -687,7 +687,7 @@
* @return This buffer
*
* @throws BufferUnderflowException
- * If there are fewer than <tt>length</tt> $fulltype$s
+ * If there are fewer than <tt>length</tt> $type$s
* remaining in this buffer
*/
public $Type$Buffer get($type$[] dst) {
@@ -700,15 +700,15 @@
/**
* Relative bulk <i>put</i> method <i>(optional operation)</i>.
*
- * <p> This method transfers the $fulltype$s remaining in the given source
- * buffer into this buffer. If there are more $fulltype$s remaining in the
+ * <p> This method transfers the $type$s remaining in the given source
+ * buffer into this buffer. If there are more $type$s remaining in the
* source buffer than in this buffer, that is, if
* <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
- * then no $fulltype$s are transferred and a {@link
+ * then no $type$s are transferred and a {@link
* BufferOverflowException} is thrown.
*
* <p> Otherwise, this method copies
- * <i>n</i> = <tt>src.remaining()</tt> $fulltype$s from the given
+ * <i>n</i> = <tt>src.remaining()</tt> $type$s from the given
* buffer into this buffer, starting at each buffer's current position.
* The positions of both buffers are then incremented by <i>n</i>.
*
@@ -723,14 +723,14 @@
* buffer and it is potentially much more efficient. </p>
*
* @param src
- * The source buffer from which $fulltype$s are to be read;
+ * The source buffer from which $type$s are to be read;
* must not be this buffer
*
* @return This buffer
*
* @throws BufferOverflowException
* If there is insufficient space in this buffer
- * for the remaining $fulltype$s in the source buffer
+ * for the remaining $type$s in the source buffer
*
* @throws IllegalArgumentException
* If the source buffer is this buffer
@@ -752,14 +752,14 @@
/**
* Relative bulk <i>put</i> method <i>(optional operation)</i>.
*
- * <p> This method transfers $fulltype$s into this buffer from the given
- * source array. If there are more $fulltype$s to be copied from the array
+ * <p> This method transfers $type$s into this buffer from the given
+ * source array. If there are more $type$s to be copied from the array
* than remain in this buffer, that is, if
* <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
- * $fulltype$s are transferred and a {@link BufferOverflowException} is
+ * $type$s are transferred and a {@link BufferOverflowException} is
* thrown.
*
- * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from the
+ * <p> Otherwise, this method copies <tt>length</tt> $type$s from the
* given array into this buffer, starting at the given offset in the array
* and at the current position of this buffer. The position of this buffer
* is then incremented by <tt>length</tt>.
@@ -776,14 +776,14 @@
* buffer and it is potentially much more efficient. </p>
*
* @param src
- * The array from which $fulltype$s are to be read
+ * The array from which $type$s are to be read
*
* @param offset
- * The offset within the array of the first $fulltype$ to be read;
+ * The offset within the array of the first $type$ to be read;
* must be non-negative and no larger than <tt>array.length</tt>
*
* @param length
- * The number of $fulltype$s to be read from the given array;
+ * The number of $type$s to be read from the given array;
* must be non-negative and no larger than
* <tt>array.length - offset</tt>
*
@@ -813,7 +813,7 @@
* Relative bulk <i>put</i> method <i>(optional operation)</i>.
*
* <p> This method transfers the entire content of the given source
- * $fulltype$ array into this buffer. An invocation of this method of the
+ * $type$ array into this buffer. An invocation of this method of the
* form <tt>dst.put(a)</tt> behaves in exactly the same way as the
* invocation
*
@@ -837,15 +837,15 @@
/**
* Relative bulk <i>put</i> method <i>(optional operation)</i>.
*
- * <p> This method transfers $fulltype$s from the given string into this
- * buffer. If there are more $fulltype$s to be copied from the string than
+ * <p> This method transfers $type$s from the given string into this
+ * buffer. If there are more $type$s to be copied from the string than
* remain in this buffer, that is, if
* <tt>end - start</tt> <tt>></tt> <tt>remaining()</tt>,
- * then no $fulltype$s are transferred and a {@link
+ * then no $type$s are transferred and a {@link
* BufferOverflowException} is thrown.
*
* <p> Otherwise, this method copies
- * <i>n</i> = <tt>end</tt> - <tt>start</tt> $fulltype$s
+ * <i>n</i> = <tt>end</tt> - <tt>start</tt> $type$s
* from the given string into this buffer, starting at the given
* <tt>start</tt> index and at the current position of this buffer. The
* position of this buffer is then incremented by <i>n</i>.
@@ -862,15 +862,15 @@
* buffer and it is potentially much more efficient. </p>
*
* @param src
- * The string from which $fulltype$s are to be read
+ * The string from which $type$s are to be read
*
* @param start
- * The offset within the string of the first $fulltype$ to be read;
+ * The offset within the string of the first $type$ to be read;
* must be non-negative and no larger than
* <tt>string.length()</tt>
*
* @param end
- * The offset within the string of the last $fulltype$ to be read,
+ * The offset within the string of the last $type$ to be read,
* plus one; must be non-negative and no larger than
* <tt>string.length()</tt>
*
@@ -921,7 +921,7 @@
// -- Other stuff --
/**
- * Tells whether or not this buffer is backed by an accessible $fulltype$
+ * Tells whether or not this buffer is backed by an accessible $type$
* array.
*
* <p> If this method returns <tt>true</tt> then the {@link #array() array}
@@ -936,7 +936,7 @@
}
/**
- * Returns the $fulltype$ array that backs this
+ * Returns the $type$ array that backs this
* buffer <i>(optional operation)</i>.
*
* <p> Modifications to this buffer's content will cause the returned
@@ -993,17 +993,17 @@
/**
* Compacts this buffer <i>(optional operation)</i>.
*
- * <p> The $fulltype$s between the buffer's current position and its limit,
+ * <p> The $type$s between the buffer's current position and its limit,
* if any, are copied to the beginning of the buffer. That is, the
- * $fulltype$ at index <i>p</i> = <tt>position()</tt> is copied
- * to index zero, the $fulltype$ at index <i>p</i> + 1 is copied
- * to index one, and so forth until the $fulltype$ at index
+ * $type$ at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the $type$ at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the $type$ at index
* <tt>limit()</tt> - 1 is copied to index
* <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
* The buffer's position is then set to <i>n+1</i> and its limit is set to
* its capacity. The mark, if defined, is discarded.
*
- * <p> The buffer's position is set to the number of $fulltype$s copied,
+ * <p> The buffer's position is set to the number of $type$s copied,
* rather than to zero, so that an invocation of this method can be
* followed immediately by an invocation of another relative <i>put</i>
* method. </p>
@@ -1032,7 +1032,7 @@
public abstract $Type$Buffer compact();
/**
- * Tells whether or not this $fulltype$ buffer is direct. </p>
+ * Tells whether or not this $type$ buffer is direct. </p>
*
* @return <tt>true</tt> if, and only if, this buffer is direct
*/
@@ -1098,6 +1098,13 @@
*
* <li><p> The two sequences of remaining elements, considered
* independently of their starting positions, are pointwise equal.
+#if[floatingPointType]
+ * This method considers two $type$ elements {@code a} and {@code b}
+ * to be equal if
+ * {@code (a == b) || ($Fulltype$.isNaN(a) && $Fulltype$.isNaN(b))}.
+ * The values {@code -0.0} and {@code +0.0} are considered to be
+ * equal, unlike {@link $Fulltype$#equals(Object)}.
+#end[floatingPointType]
* </p></li>
*
* </ol>
@@ -1118,24 +1125,37 @@
if (this.remaining() != that.remaining())
return false;
int p = this.position();
- for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
- $type$ v1 = this.get(i);
- $type$ v2 = that.get(j);
- if (v1 != v2) {
- if ((v1 != v1) && (v2 != v2)) // For float and double
- continue;
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
return false;
- }
- }
return true;
}
+ private static boolean equals($type$ x, $type$ y) {
+#if[floatingPointType]
+ return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y));
+#else[floatingPointType]
+ return x == y;
+#end[floatingPointType]
+ }
+
/**
* Compares this buffer to another.
*
* <p> Two $type$ buffers are compared by comparing their sequences of
* remaining elements lexicographically, without regard to the starting
* position of each sequence within its corresponding buffer.
+#if[floatingPointType]
+ * Pairs of {@code $type$} elements are compared as if by invoking
+ * {@link $Fulltype$#compare($type$,$type$)}, except that
+ * {@code -0.0} and {@code 0.0} are considered to be equal.
+ * {@code $Fulltype$.NaN} is considered by this method to be equal
+ * to itself and greater than all other {@code $type$} values
+ * (including {@code $Fulltype$.POSITIVE_INFINITY}).
+#else[floatingPointType]
+ * Pairs of {@code $type$} elements are compared as if by invoking
+ * {@link $Fulltype$#compare($type$,$type$)}.
+#end[floatingPointType]
*
* <p> A $type$ buffer is not comparable to any other type of object.
*
@@ -1145,20 +1165,23 @@
public int compareTo($Type$Buffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
- $type$ v1 = this.get(i);
- $type$ v2 = that.get(j);
- if (v1 == v2)
- continue;
- if ((v1 != v1) && (v2 != v2)) // For float and double
- continue;
- if (v1 < v2)
- return -1;
- return +1;
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
}
return this.remaining() - that.remaining();
}
-
+ private static int compare($type$ x, $type$ y) {
+#if[floatingPointType]
+ return ((x < y) ? -1 :
+ (x > y) ? +1 :
+ (x == y) ? 0 :
+ $Fulltype$.isNaN(x) ? ($Fulltype$.isNaN(y) ? 0 : +1) : -1);
+#else[floatingPointType]
+ return $Fulltype$.compare(x, y);
+#end[floatingPointType]
+ }
// -- Other char stuff --
@@ -1326,7 +1349,7 @@
}
/**
- * Appends the specified $fulltype$ to this
+ * Appends the specified $type$ to this
* buffer <i>(optional operation)</i>.
*
* <p> An invocation of this method of the form <tt>dst.append($x$)</tt>
@@ -1336,7 +1359,7 @@
* dst.put($x$) </pre>
*
* @param $x$
- * The 16-bit $fulltype$ to append
+ * The 16-bit $type$ to append
*
* @return This buffer
*
@@ -1362,10 +1385,10 @@
/**
* Retrieves this buffer's byte order.
*
- * <p> The byte order of $a$ $fulltype$ buffer created by allocation or by
+ * <p> The byte order of $a$ $type$ buffer created by allocation or by
* wrapping an existing <tt>$type$</tt> array is the {@link
* ByteOrder#nativeOrder </code>native order<code>} of the underlying
- * hardware. The byte order of $a$ $fulltype$ buffer created as a <a
+ * hardware. The byte order of $a$ $type$ buffer created as a <a
* href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
* byte buffer at the moment that the view is created. </p>
*
--- a/jdk/src/share/classes/java/rmi/activation/Activatable.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/rmi/activation/Activatable.java Wed Jul 05 17:04:56 2017 +0200
@@ -73,7 +73,7 @@
* can be handled properly.
*
* <p>This method invokes the {@link
- * exportObject(Remote,String,MarshalledObject,boolean,port)
+ * #exportObject(Remote,String,MarshalledObject,boolean,int)
* exportObject} method with this object, and the specified location,
* data, restart mode, and port. Subsequent calls to {@link #getID}
* will return the activation identifier returned from the call to
@@ -120,7 +120,7 @@
* can be handled properly.
*
* <p>This method invokes the {@link
- * exportObject(Remote,String,MarshalledObject,boolean,port,RMIClientSocketFactory,RMIServerSocketFactory)
+ * #exportObject(Remote,String,MarshalledObject,boolean,int,RMIClientSocketFactory,RMIServerSocketFactory)
* exportObject} method with this object, and the specified location,
* data, restart mode, port, and client and server socket factories.
* Subsequent calls to {@link #getID} will return the activation
@@ -312,7 +312,7 @@
* separately, so that exceptions can be handled properly.
*
* <p>This method invokes the {@link
- * exportObject(Remote,String,MarshalledObject,boolean,port,RMIClientSocketFactory,RMIServerSocketFactory)
+ * #exportObject(Remote,String,MarshalledObject,boolean,int,RMIClientSocketFactory,RMIServerSocketFactory)
* exportObject} method with the specified object, location, data,
* restart mode, and port, and <code>null</code> for both client and
* server socket factories, and then returns the resulting activation
--- a/jdk/src/share/classes/java/rmi/registry/LocateRegistry.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/rmi/registry/LocateRegistry.java Wed Jul 05 17:04:56 2017 +0200
@@ -187,7 +187,7 @@
* host that accepts requests on the specified <code>port</code>.
*
* <p>The <code>Registry</code> instance is exported as if the static
- * {@link UnicastRemoteObject.exportObject(Remote,int)
+ * {@link UnicastRemoteObject#exportObject(Remote,int)
* UnicastRemoteObject.exportObject} method is invoked, passing the
* <code>Registry</code> instance and the specified <code>port</code> as
* arguments, except that the <code>Registry</code> instance is
@@ -213,7 +213,7 @@
*
* <p>The <code>Registry</code> instance is exported as if
* the static {@link
- * UnicastRemoteObject.exportObject(Remote,int,RMIClientSocketFactory,RMIServerSocketFactory)
+ * UnicastRemoteObject#exportObject(Remote,int,RMIClientSocketFactory,RMIServerSocketFactory)
* UnicastRemoteObject.exportObject} method is invoked, passing the
* <code>Registry</code> instance, the specified <code>port</code>, the
* specified <code>RMIClientSocketFactory</code>, and the specified
--- a/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java Wed Jul 05 17:04:56 2017 +0200
@@ -138,7 +138,6 @@
* instance
* @throws Throwable the exception to throw from the method invocation
* on the proxy instance
- * @see
**/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
--- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Wed Jul 05 17:04:56 2017 +0200
@@ -216,7 +216,7 @@
/**
* Returns the reason that the validation failed. The reason is
* associated with the index of the certificate returned by
- * {@link getIndex}.
+ * {@link #getIndex}.
*
* @return the reason that the validation failed, or
* <code>BasicReason.UNSPECIFIED</code> if a reason has not been
--- a/jdk/src/share/classes/java/text/Bidi.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/text/Bidi.java Wed Jul 05 17:04:56 2017 +0200
@@ -121,9 +121,9 @@
*
* @param paragraph a paragraph of text with optional character and paragraph attribute information
*
- * @see TextAttribute#BIDI_EMBEDDING
- * @see TextAttribute#NUMERIC_SHAPING
- * @see TextAttribute#RUN_DIRECTION
+ * @see java.awt.font.TextAttribute#BIDI_EMBEDDING
+ * @see java.awt.font.TextAttribute#NUMERIC_SHAPING
+ * @see java.awt.font.TextAttribute#RUN_DIRECTION
*/
public Bidi(AttributedCharacterIterator paragraph) {
if (paragraph == null) {
--- a/jdk/src/share/classes/java/util/Objects.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/util/Objects.java Wed Jul 05 17:04:56 2017 +0200
@@ -119,7 +119,7 @@
*
* @param values the values to be hashed
* @return a hash value of the sequence of input values
- * @see Arrays#hashCode
+ * @see Arrays#hashCode(Object[])
* @see List#hashCode
*/
public static int hash(Object... values) {
--- a/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java Wed Jul 05 17:04:56 2017 +0200
@@ -51,7 +51,7 @@
* The {@link PlatformManagedObject#getObjectName} method
* can be used to obtain its {@code ObjectName}.
*
- * @See java.lang.management.PlatformManagedObject
+ * @see java.lang.management.PlatformManagedObject
*
* @author Mandy Chung
* @since 1.7
--- a/jdk/src/share/classes/javax/accessibility/AccessibleContext.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/javax/accessibility/AccessibleContext.java Wed Jul 05 17:04:56 2017 +0200
@@ -296,7 +296,7 @@
*
* @see #getAccessibleText
* @see #addPropertyChangeListener
- * @see #AccessibleText.AccessibleTextSequence
+ * @see AccessibleTextSequence
*/
public static final String ACCESSIBLE_TEXT_PROPERTY
= "AccessibleText";
@@ -311,7 +311,7 @@
*
* @see #getAccessibleText
* @see #addPropertyChangeListener
- * @see #AccessibleText.AccessibleTextSequence
+ * @see AccessibleTextSequence
*
* @since 1.5
*/
@@ -334,7 +334,7 @@
*
* @see #getAccessibleText
* @see #addPropertyChangeListener
- * @see #AccessibleText.AccessibleAttributeSequence
+ * @see AccessibleAttributeSequence
*
* @since 1.5
*/
--- a/jdk/src/share/classes/javax/accessibility/AccessibleExtendedText.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/javax/accessibility/AccessibleExtendedText.java Wed Jul 05 17:04:56 2017 +0200
@@ -45,7 +45,6 @@
* @see Accessible#getAccessibleContext
* @see AccessibleContext
* @see AccessibleContext#getAccessibleText
- * @see AccessibleText.AccessibleTextChunk
*
* @author Peter Korn
* @author Lynn Monsanto
--- a/jdk/src/share/classes/javax/accessibility/AccessibleKeyBinding.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/javax/accessibility/AccessibleKeyBinding.java Wed Jul 05 17:04:56 2017 +0200
@@ -32,16 +32,11 @@
* the standard mechanism for an assistive technology to determine the
* key bindings which exist for this object.
* Any object that has such key bindings should support this
- * interface. Applications can determine if an object supports the
- * AccessibleKeyBinding interface by first obtaining its AccessibleContext
- * (see @link Accessible} and then calling the
- * {@link AccessibleContext#getAccessibleKeyBinding} method. If the return
- * value is not null, the object supports this interface.
+ * interface.
*
* @see Accessible
* @see Accessible#getAccessibleContext
* @see AccessibleContext
- * @see AccessibleContext#getAccessibleKeyBinding
*
* @author Lynn Monsanto
* @since 1.4
@@ -58,21 +53,7 @@
/**
* Returns a key binding for this object. The value returned is an
* java.lang.Object which must be cast to appropriate type depending
- * on the underlying implementation of the key. For example, if the
- * Object returned is a javax.swing.KeyStroke, the user of this
- * method should do the following:
- * <nf><code>
- * Component c = <get the component that has the key bindings>
- * AccessibleContext ac = c.getAccessibleContext();
- * AccessibleKeyBinding akb = ac.getAccessibleKeyBinding();
- * for (int i = 0; i < akb.getAccessibleKeyBindingCount(); i++) {
- * Object o = akb.getAccessibleKeyBinding(i);
- * if (o instanceof javax.swing.KeyStroke) {
- * javax.swing.KeyStroke keyStroke = (javax.swing.KeyStroke)o;
- * <do something with the key binding>
- * }
- * }
- * </code></nf>
+ * on the underlying implementation of the key.
*
* @param i zero-based index of the key bindings
* @return a javax.lang.Object which specifies the key binding
--- a/jdk/src/share/classes/org/ietf/jgss/GSSName.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/org/ietf/jgss/GSSName.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -103,11 +103,12 @@
* follows: service@hostname.<p>
*
* It represents the following Oid value:<br>
- * <code>{ 1(iso), 3(org), 6(dod), 1(internet), 5(security),
- * 6(nametypes), 2(gss-host-based-services) }</code>
+ * <code>{ iso(1) member-body(2) United
+ * States(840) mit(113554) infosys(1) gssapi(2) generic(1) service_name(4)
+ * }</code>
*/
public static final Oid NT_HOSTBASED_SERVICE
- = Oid.getInstance("1.3.6.1.5.6.2");
+ = Oid.getInstance("1.2.840.113554.1.2.1.4");
/**
* Name type to indicate a named user on a local system.<p>
--- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java Wed Jul 05 17:04:56 2017 +0200
@@ -326,7 +326,7 @@
}
// generate references and signature value
- List allReferences = new ArrayList(si.getReferences());
+ List allReferences = new ArrayList();
// traverse the Signature and register all objects with IDs that
// may contain References
@@ -356,6 +356,9 @@
}
}
}
+ // always add SignedInfo references after Manifest references so
+ // that Manifest reference are digested first
+ allReferences.addAll(si.getReferences());
// generate/digest each reference
for (int i = 0, size = allReferences.size(); i < size; i++) {
--- a/jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java Wed Jul 05 17:04:56 2017 +0200
@@ -30,7 +30,7 @@
import java.dyn.*;
import java.util.Arrays;
import static sun.dyn.MethodHandleNatives.Constants.*;
-import static sun.dyn.MethodHandleImpl.newIllegalArgumentException;
+import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* This method handle performs simple conversion or checking of a single argument.
@@ -302,7 +302,22 @@
*/
private static int type2size(int type) {
assert(type >= T_BOOLEAN && type <= T_OBJECT);
- return (type == T_FLOAT || type == T_DOUBLE) ? 2 : 1;
+ return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
+ }
+ private static int type2size(Class<?> type) {
+ return type2size(basicType(type));
+ }
+
+ /** The given stackMove is the number of slots pushed.
+ * It might be negative. Scale it (multiply) by the
+ * VM's notion of how an address changes with a push,
+ * to get the raw SP change for stackMove.
+ * Then shift and mask it into the correct field.
+ */
+ private static long insertStackMove(int stackMove) {
+ // following variable must be long to avoid sign extension after '<<'
+ long spChange = stackMove * MethodHandleNatives.JVM_STACK_MOVE_UNIT;
+ return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
}
/** Construct an adapter conversion descriptor for a single-argument conversion. */
@@ -310,16 +325,16 @@
assert(src == (src & 0xF));
assert(dest == (dest & 0xF));
assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
- long stackMove = type2size(dest) - type2size(src);
+ int stackMove = type2size(dest) - type2size(src);
return ((long) argnum << 32 |
(long) convOp << CONV_OP_SHIFT |
(int) src << CONV_SRC_TYPE_SHIFT |
(int) dest << CONV_DEST_TYPE_SHIFT |
- stackMove << CONV_STACK_MOVE_SHIFT
+ insertStackMove(stackMove)
);
}
private static long makeConv(int convOp, int argnum, int stackMove) {
- assert(convOp >= OP_SWAP_ARGS && convOp <= OP_SPREAD_ARGS);
+ assert(convOp >= OP_DUP_ARGS && convOp <= OP_SPREAD_ARGS);
byte src = 0, dest = 0;
if (convOp >= OP_COLLECT_ARGS && convOp <= OP_SPREAD_ARGS)
src = dest = T_OBJECT;
@@ -327,12 +342,21 @@
(long) convOp << CONV_OP_SHIFT |
(int) src << CONV_SRC_TYPE_SHIFT |
(int) dest << CONV_DEST_TYPE_SHIFT |
- stackMove << CONV_STACK_MOVE_SHIFT
+ insertStackMove(stackMove)
+ );
+ }
+ private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
+ assert(convOp >= OP_SWAP_ARGS && convOp <= OP_ROT_ARGS);
+ return ((long) srcArg << 32 |
+ (long) convOp << CONV_OP_SHIFT |
+ (int) type << CONV_SRC_TYPE_SHIFT |
+ (int) type << CONV_DEST_TYPE_SHIFT |
+ (int) destSlot << CONV_VMINFO_SHIFT
);
}
private static long makeConv(int convOp) {
- assert(convOp == OP_RETYPE_ONLY);
- return (long) convOp << CONV_OP_SHIFT; // stackMove, src, dst, argnum all zero
+ assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
+ return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT); // stackMove, src, dst all zero
}
private static int convCode(long conv) {
return (int)conv;
@@ -348,16 +372,6 @@
/** One of OP_RETYPE_ONLY, etc. */
int conversionOp() { return (conversion & CONV_OP_MASK) >> CONV_OP_SHIFT; }
- @Override
- public String toString() {
- return addTypeString(this, "Adapted[" + basicToString(nonAdapter((MethodHandle)vmtarget)) + "]");
- }
-
- private static MethodHandle nonAdapter(MethodHandle mh) {
- return (MethodHandle)
- MethodHandleNatives.getTarget(mh, ETF_DIRECT_HANDLE);
- }
-
/* Return one plus the position of the first non-trivial difference
* between the given types. This is not a symmetric operation;
* we are considering adapting the targetType to adapterType.
@@ -399,14 +413,14 @@
//if (false) return 1; // never adaptable!
return -1; // some significant difference
}
- private static int diffParamTypes(MethodType adapterType, int tstart,
- MethodType targetType, int astart,
+ private static int diffParamTypes(MethodType adapterType, int astart,
+ MethodType targetType, int tstart,
int nargs, boolean raw) {
assert(nargs >= 0);
int res = 0;
for (int i = 0; i < nargs; i++) {
- Class<?> src = adapterType.parameterType(tstart+i);
- Class<?> dest = targetType.parameterType(astart+i);
+ Class<?> src = adapterType.parameterType(astart+i);
+ Class<?> dest = targetType.parameterType(tstart+i);
if ((!raw
? VerifyType.canPassUnchecked(src, dest)
: VerifyType.canPassRaw(src, dest)
@@ -422,7 +436,7 @@
/** Can a retyping adapter (alone) validly convert the target to newType? */
public static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
- return canRetypeOnly(newType, targetType, false);
+ return canRetype(newType, targetType, false);
}
/** Can a retyping adapter (alone) convert the target to newType?
* It is allowed to widen subword types and void to int, to make bitwise
@@ -430,14 +444,14 @@
* reference conversions on return. This last feature requires that the
* caller be trusted, and perform explicit cast conversions on return values.
*/
- static boolean canRawRetypeOnly(MethodType newType, MethodType targetType) {
- return canRetypeOnly(newType, targetType, true);
+ public static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
+ return canRetype(newType, targetType, true);
}
- static boolean canRetypeOnly(MethodType newType, MethodType targetType, boolean raw) {
- if (!convOpSupported(OP_RETYPE_ONLY)) return false;
+ static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
+ if (!convOpSupported(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY)) return false;
int diff = diffTypes(newType, targetType, raw);
// %%% This assert is too strong. Factor diff into VerifyType and reconcile.
- assert((diff == 0) == VerifyType.isNullConversion(newType, targetType));
+ assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
return diff == 0;
}
@@ -447,19 +461,21 @@
*/
public static MethodHandle makeRetypeOnly(Access token,
MethodType newType, MethodHandle target) {
- return makeRetypeOnly(token, newType, target, false);
+ return makeRetype(token, newType, target, false);
}
- public static MethodHandle makeRawRetypeOnly(Access token,
+ public static MethodHandle makeRetypeRaw(Access token,
MethodType newType, MethodHandle target) {
- return makeRetypeOnly(token, newType, target, true);
+ return makeRetype(token, newType, target, true);
}
- static MethodHandle makeRetypeOnly(Access token,
+ static MethodHandle makeRetype(Access token,
MethodType newType, MethodHandle target, boolean raw) {
Access.check(token);
- if (!canRetypeOnly(newType, target.type(), raw))
+ MethodType oldType = target.type();
+ if (oldType == newType) return target;
+ if (!canRetype(newType, oldType, raw))
return null;
// TO DO: clone the target guy, whatever he is, with new type.
- return new AdapterMethodHandle(target, newType, makeConv(OP_RETYPE_ONLY));
+ return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
}
/** Can a checkcast adapter validly convert the target to newType?
@@ -492,7 +508,7 @@
Access.check(token);
if (!canCheckCast(newType, target.type(), arg, castType))
return null;
- long conv = makeConv(OP_CHECK_CAST, arg, 0);
+ long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
return new AdapterMethodHandle(target, newType, conv, castType);
}
@@ -537,10 +553,9 @@
int arg, Class<?> convType) {
Access.check(token);
MethodType oldType = target.type();
- Class<?> src = newType.parameterType(arg);
- Class<?> dst = oldType.parameterType(arg);
if (!canPrimCast(newType, oldType, arg, convType))
return null;
+ Class<?> src = newType.parameterType(arg);
long conv = makeConv(OP_PRIM_TO_PRIM, arg, basicType(src), basicType(convType));
return new AdapterMethodHandle(target, newType, conv);
}
@@ -607,8 +622,6 @@
return null;
}
- // TO DO: makeSwapArguments, makeRotateArguments, makeDuplicateArguments
-
/** Can an adapter simply drop arguments to convert the target to newType? */
public static boolean canDropArguments(MethodType newType, MethodType targetType,
int dropArgPos, int dropArgCount) {
@@ -643,26 +656,195 @@
Access.check(token);
if (dropArgCount == 0)
return makeRetypeOnly(IMPL_TOKEN, newType, target);
- MethodType mt = target.type();
- int argCount = mt.parameterCount();
- if (!canDropArguments(newType, mt, dropArgPos, dropArgCount))
+ if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
+ return null;
+ // in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
+ // out arglist: [0: ...keep1 | dpos: keep2... ]
+ int keep2InPos = dropArgPos + dropArgCount;
+ int dropSlot = newType.parameterSlotDepth(keep2InPos);
+ int keep1InSlot = newType.parameterSlotDepth(dropArgPos);
+ int slotCount = keep1InSlot - dropSlot;
+ assert(slotCount >= dropArgCount);
+ assert(target.type().parameterSlotCount() + slotCount == newType.parameterSlotCount());
+ long conv = makeConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ /** Can an adapter duplicate an argument to convert the target to newType? */
+ public static boolean canDupArguments(MethodType newType, MethodType targetType,
+ int dupArgPos, int dupArgCount) {
+ if (!convOpSupported(OP_DUP_ARGS)) return false;
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ int nptypes = newType.parameterCount();
+ if (dupArgCount < 0 || dupArgPos + dupArgCount > nptypes)
+ return false;
+ if (targetType.parameterCount() != nptypes + dupArgCount)
+ return false;
+ // parameter types must be the same up to the duplicated arguments
+ if (diffParamTypes(newType, 0, targetType, 0, nptypes, false) != 0)
+ return false;
+ // duplicated types must be, well, duplicates
+ if (diffParamTypes(newType, dupArgPos, targetType, nptypes, dupArgCount, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Duplicate the selected argument.
+ * Return null if this is not possible.
+ */
+ public static MethodHandle makeDupArguments(Access token,
+ MethodType newType, MethodHandle target,
+ int dupArgPos, int dupArgCount) {
+ Access.check(token);
+ if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
return null;
- int dropSlotCount, dropSlotPos;
- if (dropArgCount >= argCount) {
- assert(dropArgPos == argCount-1);
- dropSlotPos = 0;
- dropSlotCount = mt.parameterSlotCount();
+ if (dupArgCount == 0)
+ return target;
+ // in arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
+ // out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
+ int keep2InPos = dupArgPos + dupArgCount;
+ int dupSlot = newType.parameterSlotDepth(keep2InPos);
+ int keep1InSlot = newType.parameterSlotDepth(dupArgPos);
+ int slotCount = keep1InSlot - dupSlot;
+ assert(target.type().parameterSlotCount() - slotCount == newType.parameterSlotCount());
+ long conv = makeConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ /** Can an adapter swap two arguments to convert the target to newType? */
+ public static boolean canSwapArguments(MethodType newType, MethodType targetType,
+ int swapArg1, int swapArg2) {
+ if (!convOpSupported(OP_SWAP_ARGS)) return false;
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ if (swapArg1 >= swapArg2) return false; // caller resp
+ int nptypes = newType.parameterCount();
+ if (targetType.parameterCount() != nptypes)
+ return false;
+ if (swapArg1 < 0 || swapArg2 >= nptypes)
+ return false;
+ if (diffParamTypes(newType, 0, targetType, 0, swapArg1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg1, targetType, swapArg2, 1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg1+1, targetType, swapArg1+1, swapArg2-swapArg1-1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg2, targetType, swapArg1, 1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg2+1, targetType, swapArg2+1, nptypes-swapArg2-1, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Swap the selected arguments.
+ * Return null if this is not possible.
+ */
+ public static MethodHandle makeSwapArguments(Access token,
+ MethodType newType, MethodHandle target,
+ int swapArg1, int swapArg2) {
+ Access.check(token);
+ if (swapArg1 == swapArg2)
+ return target;
+ if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
+ if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
+ return null;
+ Class<?> swapType = newType.parameterType(swapArg1);
+ // in arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
+ // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
+ int swapSlot2 = newType.parameterSlotDepth(swapArg2 + 1);
+ long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(swapType), swapSlot2);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ static int positiveRotation(int argCount, int rotateBy) {
+ assert(argCount > 0);
+ if (rotateBy >= 0) {
+ if (rotateBy < argCount)
+ return rotateBy;
+ return rotateBy % argCount;
+ } else if (rotateBy >= -argCount) {
+ return rotateBy + argCount;
} else {
- // arglist: [0: keep... | dpos: drop... | dpos+dcount: keep... ]
- int lastDroppedArg = dropArgPos + dropArgCount - 1;
- int lastKeptArg = dropArgPos - 1; // might be -1, which is OK
- dropSlotPos = mt.parameterSlotDepth(1+lastDroppedArg);
- int lastKeptSlot = mt.parameterSlotDepth(1+lastKeptArg);
- dropSlotCount = lastKeptSlot - dropSlotPos;
- assert(dropSlotCount >= dropArgCount);
+ return (-1-((-1-rotateBy) % argCount)) + argCount;
}
- long conv = makeConv(OP_DROP_ARGS, dropArgPos, +dropSlotCount);
- return new AdapterMethodHandle(target, newType, dropSlotCount, conv);
+ }
+
+ final static int MAX_ARG_ROTATION = 1;
+
+ /** Can an adapter rotate arguments to convert the target to newType? */
+ public static boolean canRotateArguments(MethodType newType, MethodType targetType,
+ int firstArg, int argCount, int rotateBy) {
+ if (!convOpSupported(OP_ROT_ARGS)) return false;
+ if (argCount <= 2) return false; // must be a swap, not a rotate
+ rotateBy = positiveRotation(argCount, rotateBy);
+ if (rotateBy == 0) return false; // no rotation
+ if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
+ return false; // too many argument positions
+ // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ int nptypes = newType.parameterCount();
+ if (targetType.parameterCount() != nptypes)
+ return false;
+ if (firstArg < 0 || firstArg >= nptypes) return false;
+ int argLimit = firstArg + argCount;
+ if (argLimit > nptypes) return false;
+ if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
+ return false;
+ int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
+ // swap new chunk1 with target chunk2
+ if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
+ return false;
+ // swap new chunk2 with target chunk1
+ if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Rotate the selected argument range.
+ * Return null if this is not possible.
+ */
+ public static MethodHandle makeRotateArguments(Access token,
+ MethodType newType, MethodHandle target,
+ int firstArg, int argCount, int rotateBy) {
+ Access.check(token);
+ rotateBy = positiveRotation(argCount, rotateBy);
+ if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
+ return null;
+ // Decide whether it should be done as a right or left rotation,
+ // on the JVM stack. Return the number of stack slots to rotate by,
+ // positive if right, negative if left.
+ int limit = firstArg + argCount;
+ int depth0 = newType.parameterSlotDepth(firstArg);
+ int depth1 = newType.parameterSlotDepth(limit-rotateBy);
+ int depth2 = newType.parameterSlotDepth(limit);
+ int chunk1Slots = depth0 - depth1; assert(chunk1Slots > 0);
+ int chunk2Slots = depth1 - depth2; assert(chunk2Slots > 0);
+ // From here on out, it assumes a single-argument shift.
+ assert(MAX_ARG_ROTATION == 1);
+ int srcArg, dstArg;
+ byte basicType;
+ if (chunk2Slots <= chunk1Slots) {
+ // Rotate right/down N (rotateBy = +N, N small, c2 small):
+ // in arglist: [0: ...keep1 | arg1: c1... | limit-N: c2 | limit: keep2... ]
+ // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1... | limit: keep2... ]
+ srcArg = limit-1;
+ dstArg = firstArg;
+ basicType = basicType(newType.parameterType(srcArg));
+ assert(chunk2Slots == type2size(basicType));
+ } else {
+ // Rotate left/up N (rotateBy = -N, N small, c1 small):
+ // in arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2... | limit: keep2... ]
+ // out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
+ srcArg = firstArg;
+ dstArg = limit-1;
+ basicType = basicType(newType.parameterType(srcArg));
+ assert(chunk1Slots == type2size(basicType));
+ }
+ int dstSlot = newType.parameterSlotDepth(dstArg + 1);
+ long conv = makeSwapConv(OP_ROT_ARGS, srcArg, basicType, dstSlot);
+ return new AdapterMethodHandle(target, newType, conv);
}
/** Can an adapter spread an argument to convert the target to newType? */
@@ -676,10 +858,10 @@
if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
return false;
int afterPos = spreadArgPos + spreadArgCount;
- int afterCount = nptypes - afterPos;
+ int afterCount = nptypes - (spreadArgPos + 1);
if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
spreadArgCount < 0 ||
- targetType.parameterCount() != nptypes - 1 + spreadArgCount)
+ targetType.parameterCount() != afterPos + afterCount)
return false;
// parameter types after the spread point must also be the same
if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
@@ -697,32 +879,40 @@
return true;
}
+
/** Factory method: Spread selected argument. */
public static MethodHandle makeSpreadArguments(Access token,
MethodType newType, MethodHandle target,
Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
Access.check(token);
- MethodType mt = target.type();
- int argCount = mt.parameterCount();
- if (!canSpreadArguments(newType, mt, spreadArgType, spreadArgPos, spreadArgCount))
+ MethodType targetType = target.type();
+ if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
return null;
- int spreadSlotCount, spreadSlotPos;
- if (spreadArgCount >= argCount) {
- assert(spreadArgPos == argCount-1);
- spreadSlotPos = 0;
- spreadSlotCount = mt.parameterSlotCount();
- } else {
- // arglist: [0: keep... | dpos: spread... | dpos+dcount: keep... ]
- int lastSpreadArg = spreadArgPos + spreadArgCount - 1;
- int lastKeptArg = spreadArgPos - 1; // might be -1, which is OK
- spreadSlotPos = mt.parameterSlotDepth(1+lastSpreadArg);
- int lastKeptSlot = mt.parameterSlotDepth(1+lastKeptArg);
- spreadSlotCount = lastKeptSlot - spreadSlotPos;
- assert(spreadSlotCount >= spreadArgCount);
- }
- long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, spreadSlotCount);
- return new AdapterMethodHandle(target, newType, conv, spreadArgType);
+ // in arglist: [0: ...keep1 | spos: spreadArg | spos+1: keep2... ]
+ // out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
+ int keep2OutPos = spreadArgPos + spreadArgCount;
+ int spreadSlot = targetType.parameterSlotDepth(keep2OutPos);
+ int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);
+ int slotCount = keep1OutSlot - spreadSlot;
+ assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+1));
+ assert(slotCount >= spreadArgCount);
+ long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, slotCount-1);
+ MethodHandle res = new AdapterMethodHandle(target, newType, conv, spreadArgType);
+ assert(res.type().parameterType(spreadArgPos) == spreadArgType);
+ return res;
}
// TO DO: makeCollectArguments, makeFlyby, makeRicochet
+
+ @Override
+ public String toString() {
+ return nonAdapter((MethodHandle)vmtarget).toString();
+ }
+
+ private static MethodHandle nonAdapter(MethodHandle mh) {
+ while (mh instanceof AdapterMethodHandle) {
+ mh = (MethodHandle) mh.vmtarget;
+ }
+ return mh;
+ }
}
--- a/jdk/src/share/classes/sun/dyn/BoundMethodHandle.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/BoundMethodHandle.java Wed Jul 05 17:04:56 2017 +0200
@@ -28,6 +28,10 @@
import sun.dyn.util.VerifyType;
import sun.dyn.util.Wrapper;
import java.dyn.*;
+import java.util.List;
+import sun.dyn.MethodHandleNatives.Constants;
+import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP;
+import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* The flavor of method handle which emulates an invoke instruction
@@ -35,18 +39,23 @@
* when the handle is created, not when it is invoked.
* @author jrose
*/
-public class BoundMethodHandle extends MethodHandle {
+public class BoundMethodHandle extends MethodHandle {
//MethodHandle vmtarget; // next BMH or final DMH or methodOop
private final Object argument; // argument to insert
private final int vmargslot; // position at which it is inserted
+ private static final Access IMPL_TOKEN = Access.getToken();
+ private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
+
// Constructors in this class *must* be package scoped or private.
+ // Exception: JavaMethodHandle constructors are protected.
+ // (The link between JMH and BMH is temporary.)
/** Bind a direct MH to its receiver (or first ref. argument).
* The JVM will pre-dispatch the MH if it is not already static.
*/
BoundMethodHandle(DirectMethodHandle mh, Object argument) {
- super(Access.TOKEN, mh.type().dropParameterType(0));
+ super(Access.TOKEN, mh.type().dropParameterTypes(0, 1));
// check the type now, once for all:
this.argument = checkReferenceArgument(argument, mh, 0);
this.vmargslot = this.type().parameterSlotCount();
@@ -56,32 +65,34 @@
} else {
this.vmtarget = mh;
}
- }
-
- private static final int REF_ARG = 0, PRIM_ARG = 1, SELF_ARG = 2;
+ }
/** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc.
* The argument type must be a reference.
*/
BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
- this(mh, argument, argnum, mh.type().parameterType(argnum).isPrimitive() ? PRIM_ARG : REF_ARG);
+ this(mh.type().dropParameterTypes(argnum, argnum+1),
+ mh, argument, argnum);
}
/** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc.
*/
- BoundMethodHandle(MethodHandle mh, Object argument, int argnum, int whichArg) {
- super(Access.TOKEN, mh.type().dropParameterType(argnum));
- if (whichArg == PRIM_ARG)
+ BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
+ super(Access.TOKEN, type);
+ if (mh.type().parameterType(argnum).isPrimitive())
this.argument = bindPrimitiveArgument(argument, mh, argnum);
else {
- if (whichArg == SELF_ARG) argument = this;
this.argument = checkReferenceArgument(argument, mh, argnum);
}
- this.vmargslot = this.type().parameterSlotDepth(argnum);
+ this.vmargslot = type.parameterSlotDepth(argnum);
+ initTarget(mh, argnum);
+ }
+
+ private void initTarget(MethodHandle mh, int argnum) {
if (MethodHandleNatives.JVM_SUPPORT) {
- this.vmtarget = null; // maybe updated by JVM
+ this.vmtarget = null; // maybe updated by JVM
MethodHandleNatives.init(this, mh, argnum);
} else {
this.vmtarget = mh;
@@ -97,29 +108,65 @@
assert(this.getClass() == AdapterMethodHandle.class);
}
- /** Initialize the current object as a method handle, binding it
- * as the {@code argnum}th argument of the method handle {@code entryPoint}.
- * The invocation type of the resulting method handle will be the
- * same as {@code entryPoint}, except that the {@code argnum}th argument
- * type will be dropped.
- */
- public BoundMethodHandle(MethodHandle entryPoint, int argnum) {
- this(entryPoint, null, argnum, SELF_ARG);
-
- // Note: If the conversion fails, perhaps because of a bad entryPoint,
- // the MethodHandle.type field will not be filled in, and therefore
- // no MH.invoke call will ever succeed. The caller may retain a pointer
- // to the broken method handle, but no harm can be done with it.
- }
-
- /** Initialize the current object as a method handle, binding it
+ /** Initialize the current object as a Java method handle, binding it
* as the first argument of the method handle {@code entryPoint}.
* The invocation type of the resulting method handle will be the
* same as {@code entryPoint}, except that the first argument
* type will be dropped.
*/
- public BoundMethodHandle(MethodHandle entryPoint) {
- this(entryPoint, null, 0, SELF_ARG);
+ protected BoundMethodHandle(MethodHandle entryPoint) {
+ super(Access.TOKEN, entryPoint.type().dropParameterTypes(0, 1));
+ this.argument = this; // kludge; get rid of
+ this.vmargslot = this.type().parameterSlotDepth(0);
+ initTarget(entryPoint, 0);
+ assert(this instanceof JavaMethodHandle);
+ }
+
+ /** Initialize the current object as a Java method handle.
+ */
+ protected BoundMethodHandle(String entryPointName, MethodType type, boolean matchArity) {
+ super(Access.TOKEN, null);
+ MethodHandle entryPoint
+ = findJavaMethodHandleEntryPoint(this.getClass(),
+ entryPointName, type, matchArity);
+ MethodHandleImpl.initType(this, entryPoint.type().dropParameterTypes(0, 1));
+ this.argument = this; // kludge; get rid of
+ this.vmargslot = this.type().parameterSlotDepth(0);
+ initTarget(entryPoint, 0);
+ assert(this instanceof JavaMethodHandle);
+ }
+
+ private static
+ MethodHandle findJavaMethodHandleEntryPoint(Class<?> caller,
+ String name,
+ MethodType type,
+ boolean matchArity) {
+ if (matchArity) type.getClass(); // elicit NPE
+ List<MemberName> methods = IMPL_NAMES.getMethods(caller, true, name, null, caller);
+ MethodType foundType = null;
+ MemberName foundMethod = null;
+ for (MemberName method : methods) {
+ MethodType mtype = method.getMethodType();
+ if (type != null && type.parameterCount() != mtype.parameterCount())
+ continue;
+ else if (foundType == null)
+ foundType = mtype;
+ else if (foundType != mtype)
+ throw newIllegalArgumentException("more than one method named "+name+" in "+caller.getName());
+ // discard overrides
+ if (foundMethod == null)
+ foundMethod = method;
+ else if (foundMethod.getDeclaringClass().isAssignableFrom(method.getDeclaringClass()))
+ foundMethod = method;
+ }
+ if (foundMethod == null)
+ throw newIllegalArgumentException("no method named "+name+" in "+caller.getName());
+ MethodHandle entryPoint = MethodHandleImpl.findMethod(IMPL_TOKEN, foundMethod, true, caller);
+ if (type != null) {
+ MethodType epType = type.insertParameterTypes(0, entryPoint.type().parameterType(0));
+ entryPoint = MethodHandles.convertArguments(entryPoint, epType);
+ }
+ return entryPoint;
}
/** Make sure the given {@code argument} can be used as {@code argnum}-th
@@ -175,6 +222,24 @@
@Override
public String toString() {
- return "Bound[" + super.toString() + "]";
+ MethodHandle mh = this;
+ while (mh instanceof BoundMethodHandle) {
+ Object info = MethodHandleNatives.getTargetInfo(mh);
+ if (info instanceof MethodHandle) {
+ mh = (MethodHandle) info;
+ } else {
+ String name = null;
+ if (info instanceof MemberName)
+ name = ((MemberName)info).getName();
+ if (name != null)
+ return name;
+ else
+ return super.toString(); // <unknown>, probably
+ }
+ assert(mh != this);
+ if (mh instanceof JavaMethodHandle)
+ break; // access JMH.toString(), not BMH.toString()
+ }
+ return mh.toString();
}
}
--- a/jdk/src/share/classes/sun/dyn/CallSiteImpl.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/CallSiteImpl.java Wed Jul 05 17:04:56 2017 +0200
@@ -26,34 +26,51 @@
package sun.dyn;
import java.dyn.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
- * The CallSite privately created by the JVM at every invokedynamic instruction.
+ * Parts of CallSite known to the JVM.
+ * FIXME: Merge all this into CallSite proper.
* @author jrose
*/
-class CallSiteImpl extends CallSite {
- // Fields used only by the JVM. Do not use or change.
+public class CallSiteImpl {
+ // Field used only by the JVM. Do not use or change.
private Object vmmethod;
// Values supplied by the JVM:
- int callerMID, callerBCI;
+ protected int callerMID, callerBCI;
+
+ private MethodHandle target;
+ protected final Object caller; // usually a class
+ protected final String name;
+ protected final MethodType type;
- private CallSiteImpl(Class<?> caller, String name, MethodType type) {
- super(caller, name, type);
+ /** called only directly from CallSite() */
+ protected CallSiteImpl(Access token, Object caller, String name, MethodType type) {
+ Access.check(token);
+ this.caller = caller;
+ this.name = name;
+ this.type = type;
}
- @Override
- public void setTarget(MethodHandle mh) {
- checkTarget(mh);
- if (MethodHandleNatives.JVM_SUPPORT)
- MethodHandleNatives.linkCallSite(this, (MethodHandle) mh);
- else
- super.setTarget(mh);
+ /** native version of setTarget */
+ protected void setTarget(MethodHandle mh) {
+ //System.out.println("setTarget "+this+" := "+mh);
+ // XXX I don't know how to fix this properly.
+// if (false && MethodHandleNatives.JVM_SUPPORT) // FIXME: enable this
+// MethodHandleNatives.linkCallSite(this, mh);
+// else
+ this.target = mh;
+ }
+
+ protected MethodHandle getTarget() {
+ return target;
}
private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
MethodHandleImpl.IMPL_LOOKUP.findStatic(CallSite.class, "privateInitializeCallSite",
- MethodType.make(void.class, CallSite.class, int.class, int.class));
+ MethodType.methodType(void.class, CallSite.class, int.class, int.class));
// this is the up-call from the JVM:
static CallSite makeSite(Class<?> caller, String name, MethodType type,
@@ -61,10 +78,25 @@
MethodHandle bsm = Linkage.getBootstrapMethod(caller);
if (bsm == null)
throw new InvokeDynamicBootstrapError("class has no bootstrap method: "+caller);
- CallSite site = bsm.<CallSite>invoke(caller, name, type);
+ CallSite site;
+ try {
+ site = bsm.<CallSite>invoke(caller, name, type);
+ } catch (Throwable ex) {
+ throw new InvokeDynamicBootstrapError("exception thrown while linking", ex);
+ }
if (site == null)
throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
- PRIVATE_INITIALIZE_CALL_SITE.<void>invoke(site, callerMID, callerBCI);
+ if (site.type() != type)
+ throw new InvokeDynamicBootstrapError("call site type not initialized correctly: "+site);
+ if (site.callerClass() != caller)
+ throw new InvokeDynamicBootstrapError("call site caller not initialized correctly: "+site);
+ if ((Object)site.name() != name)
+ throw new InvokeDynamicBootstrapError("call site name not initialized correctly: "+site);
+ try {
+ PRIVATE_INITIALIZE_CALL_SITE.<void>invoke(site, callerMID, callerBCI);
+ } catch (Throwable ex) {
+ throw new InvokeDynamicBootstrapError("call site initialization exception", ex);
+ }
return site;
}
}
--- a/jdk/src/share/classes/sun/dyn/FilterGeneric.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/FilterGeneric.java Wed Jul 05 17:04:56 2017 +0200
@@ -31,174 +31,159 @@
import java.dyn.NoAccessException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import static sun.dyn.MemberName.newIllegalArgumentException;
/**
- * "Flyby adapters" which apply arbitrary conversions to arguments
+ * These adapters apply arbitrary conversions to arguments
* on the way to a ultimate target.
* For simplicity, these are all generically typed.
* @author jrose
*/
class FilterGeneric {
- // type for the outgoing call (will be generic)
- private final MethodType targetType;
- // position of (first) argument to participate in filtering
- private final short argumentPosition;
- // number of arguments to participate in filtering
- private final short argumentCount;
- // how the result interacts with the filtered arguments: Prepend, Append, Replace, Discard
- private final char replaceMode;
- // prototype adapter (clone and customize for each new target & conversion!)
- private final Adapter adapter;
- // entry point for adapter (Adapter mh, a...) => ...
- private final MethodHandle entryPoint;
- // more of them (loosely cached)
- private FilterGeneric variations;
+ // type for the incoming call (will be generic)
+ private final MethodType entryType;
+ // prototype adapters (clone and customize for each new target & conversion!)
+ private final Adapter[] adapters;
- /** Compute and cache information common to all unboxing adapters
- * that can call out to targets of the erasure-family of the given erased type.
+ /** Compute and cache information common to all filtering adapters
+ * with the given generic type
*/
- // TO DO: Make this private.
- FilterGeneric(MethodType targetType, short argumentPosition, short argumentCount, char replaceMode) {
- if (argumentCount == 0) {
- if (replaceMode == 'P' || replaceMode == 'A') replaceMode = 'R';
- if (replaceMode == 'I') argumentPosition = 0;
- }
- this.targetType = targetType;
- this.argumentPosition = argumentPosition;
- this.argumentCount = argumentCount;
- this.replaceMode = replaceMode;
- validate(targetType, argumentPosition, argumentCount, replaceMode);
- Adapter ad = findAdapter(targetType, argumentPosition, argumentCount, replaceMode, filterType());
- if (ad == null)
- ad = buildAdapterFromBytecodes(targetType, argumentPosition, argumentCount, replaceMode, filterType());
- this.adapter = ad;
- this.entryPoint = ad.prototypeEntryPoint();
+ FilterGeneric(MethodType entryType) {
+ this.entryType = entryType;
+ int tableSize = Kind.LIMIT.invokerIndex(1 + entryType.parameterCount());
+ this.adapters = new Adapter[tableSize];
}
- Adapter makeInstance(MethodHandle filter, MethodHandle target) {
- return adapter.makeInstance(entryPoint, filter, target);
+ Adapter getAdapter(Kind kind, int pos) {
+ int index = kind.invokerIndex(pos);
+ Adapter ad = adapters[index];
+ if (ad != null) return ad;
+ ad = findAdapter(entryType, kind, pos);
+ if (ad == null)
+ ad = buildAdapterFromBytecodes(entryType, kind, pos);
+ adapters[index] = ad;
+ return ad;
+ }
+
+ Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
+ Adapter ad = getAdapter(kind, pos);
+ return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes filter
+ * on the selected incoming argument before passing it to the target.
+ * @param pos the argument to filter
+ * @param filter the function to call on the argument
+ * @param target the target to call with the modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeArgumentFilter(int pos, MethodHandle filter, MethodHandle target) {
+ return make(Kind.value, pos, filter, target);
}
- /** Build an adapter of the given generic type, which invokes typedTarget
- * on the incoming arguments, after unboxing as necessary.
- * The return value is boxed if necessary.
- * @param genericType the required type of the result
- * @param typedTarget the target
+ /** Build an adapter of the given generic type, which invokes a combiner
+ * on a selected group of leading arguments.
+ * The result of the combiner is prepended before all those arguments.
+ * @param combiner the function to call on the selected leading arguments
+ * @param target the target to call with the modified argument list
* @return an adapter method handle
*/
- public static MethodHandle make(MethodHandle target, int pos, MethodHandle filter) {
- return FilterGeneric.of(target.type(), (short)pos, (short)1, 'R').makeInstance(filter, target);
+ public static MethodHandle makeArgumentFolder(MethodHandle combiner, MethodHandle target) {
+ int num = combiner.type().parameterCount();
+ return make(Kind.fold, num, combiner, target);
}
- /** Return the adapter information for this type's erasure. */
- static FilterGeneric of(MethodType type, short ap, short ac, char mode) {
- if (type.generic() != type)
- throw new IllegalArgumentException("must be generic: "+type);
- validate(type, ap, ac, mode);
- MethodTypeImpl form = MethodTypeImpl.of(type);
- FilterGeneric filterGen = form.filterGeneric;
- if (filterGen == null)
- form.filterGeneric = filterGen = new FilterGeneric(type, (short)0, (short)1, 'R');
- return find(filterGen, ap, ac, mode);
+ /** Build an adapter of the given generic type, which invokes a filter
+ * on the incoming arguments, reified as a group.
+ * The argument may be modified (by side effects in the filter).
+ * The arguments, possibly modified, are passed on to the target.
+ * @param filter the function to call on the arguments
+ * @param target the target to call with the possibly-modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeFlyby(MethodHandle filter, MethodHandle target) {
+ return make(Kind.flyby, 0, filter, target);
}
- static FilterGeneric find(FilterGeneric gen, short ap, short ac, char mode) {
- for (;;) {
- if (gen.argumentPosition == ap &&
- gen.argumentCount == ac &&
- gen.replaceMode == mode) {
- return gen;
- }
- FilterGeneric gen2 = gen.variations;
- if (gen2 == null) break;
- gen = gen2;
- }
- FilterGeneric gen2 = new FilterGeneric(gen.targetType, ap, ac, mode);
- gen.variations = gen2; // OK if this smashes another cached chain
- return gen2;
+ /** Build an adapter of the given generic type, which invokes a collector
+ * on the selected incoming argument and all following arguments.
+ * The result of the collector replaces all those arguments.
+ * @param collector the function to call on the selected trailing arguments
+ * @param target the target to call with the modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeArgumentCollector(MethodHandle collector, MethodHandle target) {
+ int pos = target.type().parameterCount() - 1;
+ return make(Kind.collect, pos, collector, target);
}
- private static void validate(MethodType type, short ap, short ac, char mode) {
- int endpos = ap + ac;
- switch (mode) {
- case 'P': case 'A': case 'R': case 'D':
- if (ap >= 0 && ac >= 0 &&
- endpos >= 0 && endpos <= type.parameterCount())
- return;
- default:
- throw new InternalError("configuration "+patternName(ap, ac, mode));
- }
+ static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
+ FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
+ return fgen.makeInstance(kind, pos, filter, target);
+ }
+
+ /** Return the adapter information for this target and filter type. */
+ static FilterGeneric of(Kind kind, int pos, MethodType filterType, MethodType targetType) {
+ MethodType entryType = entryType(kind, pos, filterType, targetType);
+ if (entryType.generic() != entryType)
+ throw newIllegalArgumentException("must be generic: "+entryType);
+ MethodTypeImpl form = MethodTypeImpl.of(entryType);
+ FilterGeneric filterGen = form.filterGeneric;
+ if (filterGen == null)
+ form.filterGeneric = filterGen = new FilterGeneric(entryType);
+ return filterGen;
}
public String toString() {
- return "FilterGeneric/"+patternName()+targetType;
- }
-
- String patternName() {
- return patternName(argumentPosition, argumentCount, replaceMode);
- }
-
- static String patternName(short ap, short ac, char mode) {
- return ""+mode+ap+(ac>1?"_"+ac:"");
- }
-
- Class<?> filterType() {
- return Object.class; // result of filter operation; an uninteresting type
+ return "FilterGeneric/"+entryType;
}
- static MethodType targetType(MethodType entryType, short ap, short ac, char mode,
- Class<?> arg) {
+ static MethodType targetType(MethodType entryType, Kind kind, int pos, MethodType filterType) {
MethodType type = entryType;
- int pos = ap;
- switch (mode) {
- case 'A':
- pos += ac;
- case 'P':
- type = type.insertParameterType(pos, arg);
+ switch (kind) {
+ case value:
+ case flyby:
+ break; // no change
+ case fold:
+ type = type.insertParameterTypes(0, filterType.returnType());
break;
- case 'I':
- for (int i = 1; i < ac; i++)
- type = type.dropParameterType(pos);
- assert(type.parameterType(pos) == arg);
+ case collect:
+ type = type.dropParameterTypes(pos, type.parameterCount());
+ type = type.insertParameterTypes(pos, filterType.returnType());
break;
- case 'D':
- break;
+ default:
+ throw new InternalError();
}
return type;
}
- static MethodType entryType(MethodType targetType, short ap, short ac, char mode,
- Class<?> arg) {
+ static MethodType entryType(Kind kind, int pos, MethodType filterType, MethodType targetType) {
MethodType type = targetType;
- int pos = ap;
- switch (mode) {
- case 'A':
- pos += ac;
- case 'P':
- type = type.dropParameterType(pos);
+ switch (kind) {
+ case value:
+ case flyby:
+ break; // no change
+ case fold:
+ type = type.dropParameterTypes(0, 1);
break;
- case 'I':
- for (int i = 1; i < ac; i++)
- type = type.insertParameterType(pos, arg);
- assert(type.parameterType(pos) == arg);
+ case collect:
+ type = type.dropParameterTypes(pos, pos+1);
+ type = type.insertParameterTypes(pos, filterType.parameterList());
break;
- case 'D':
- break;
+ default:
+ throw new InternalError();
}
return type;
}
/* Create an adapter that handles spreading calls for the given type. */
- static Adapter findAdapter(MethodType targetType, short ap, short ac, char mode, Class<?> arg) {
- MethodType entryType = entryType(targetType, ap, ac, mode, arg);
- int argc = targetType.parameterCount();
- String pname = patternName(ap, ac, mode);
+ static Adapter findAdapter(MethodType entryType, Kind kind, int pos) {
+ int argc = entryType.parameterCount();
String cname0 = "F"+argc;
- String cname1 = "F"+argc+mode;
- String cname2 = "F"+argc+pname;
- String[] cnames = { cname0, cname1, cname1+"X", cname2 };
- String iname = "invoke_"+pname;
- // e.g., F5R; invoke_R3
+ String cname1 = "F"+argc+kind.key;
+ String[] cnames = { cname0, cname1 };
+ String iname = kind.invokerName(pos);
+ // e.g., F5; invoke_C3
for (String cname : cnames) {
Class<? extends Adapter> acls = Adapter.findSubClass(cname);
if (acls == null) continue;
@@ -220,7 +205,10 @@
// Produce an instance configured as a prototype.
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
- } catch (InvocationTargetException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
@@ -228,7 +216,7 @@
return null;
}
- static Adapter buildAdapterFromBytecodes(MethodType targetType, short ap, short ac, char mode, Class<?> arg) {
+ static Adapter buildAdapterFromBytecodes(MethodType entryType, Kind kind, int pos) {
throw new UnsupportedOperationException("NYI");
}
@@ -242,8 +230,13 @@
* generated once per type erasure family, and reused across adapters.
*/
static abstract class Adapter extends JavaMethodHandle {
- protected final MethodHandle filter;
- protected final MethodHandle target;
+ protected final MethodHandle filter; // transforms one or more arguments
+ protected final MethodHandle target; // ultimate target
+
+ @Override
+ public String toString() {
+ return target.toString();
+ }
protected boolean isPrototype() { return target == null; }
protected Adapter(MethodHandle entryPoint) {
@@ -287,52 +280,4221 @@
}
}
- //* generated classes follow this pattern:
- static class F1RX extends Adapter {
- protected F1RX(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F1RX(MethodHandle e, MethodHandle f, MethodHandle t)
- { super(e, f, t); }
- protected F1RX makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
- { return new F1RX(e, f, t); }
- protected Object filter(Object a0) { return filter.<Object>invoke(a0); }
- protected Object target(Object a0) { return target.<Object>invoke(a0); }
- protected Object invoke_R0(Object a0) { return target(filter(a0)); }
- }
- static class F2RX extends Adapter {
- protected F2RX(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F2RX(MethodHandle e, MethodHandle f, MethodHandle t)
- { super(e, f, t); }
- protected F2RX makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
- { return new F2RX(e, f, t); }
- protected Object filter(Object a0) { return filter.<Object>invoke(a0); }
- protected Object target(Object a0, Object a1) { return target.<Object>invoke(a0, a1); }
- protected Object invoke_R0(Object a0, Object a1) { return target(filter(a0), a1); }
- protected Object invoke_R1(Object a0, Object a1) { return target(a0, filter(a1)); }
+ static enum Kind {
+ value('V'), // filter and replace Nth argument value
+ fold('F'), // fold first N arguments, prepend result
+ collect('C'), // collect last N arguments, replace with result
+ flyby('Y'), // reify entire argument list, filter, pass to target
+ LIMIT('?');
+ static final int COUNT = LIMIT.ordinal();
+
+ final char key;
+ Kind(char key) { this.key = key; }
+ String invokerName(int pos) { return "invoke_"+key+""+pos; }
+ int invokerIndex(int pos) { return pos * COUNT + ordinal(); }
}
- static class F3RX extends Adapter {
- protected F3RX(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F3RX(MethodHandle e, MethodHandle f, MethodHandle t)
+
+ /* generated classes follow this pattern:
+ static class F1X extends Adapter {
+ protected F1X(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F1X(MethodHandle e, MethodHandle f, MethodHandle t)
{ super(e, f, t); }
- protected F3RX makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
- { return new F3RX(e, f, t); }
- protected Object filter(Object a0) { return filter.<Object>invoke(a0); }
- protected Object target(Object a0, Object a1, Object a2) { return target.<Object>invoke(a0, a1, a2); }
- protected Object invoke_R0(Object a0, Object a1, Object a2) { return target(filter(a0), a1, a2); }
- protected Object invoke_R1(Object a0, Object a1, Object a2) { return target(a0, filter(a1), a2); }
- protected Object invoke_R2(Object a0, Object a1, Object a2) { return target(a0, a1, filter(a2)); }
+ protected F1X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
+ { return new F1X(e, f, t); }
+ protected Object invoke_V0(Object a0) { return target.invoke(filter.invoke(a0)); }
+ protected Object invoke_F0(Object a0) { return target.invoke(filter.invoke(), a0); }
+ protected Object invoke_F1(Object a0) { return target.invoke(filter.invoke(a0), a0); }
+ protected Object invoke_C0(Object a0) { return target.invoke(filter.invoke(a0)); }
+ protected Object invoke_C1(Object a0) { return target.invoke(a0, filter.invoke()); }
+ protected Object invoke_Y0(Object a0) { Object[] av = { a0 };
+ filter.<void>invoke(av); return target.invoke(av[0]); }
}
- static class F4RX extends Adapter {
- protected F4RX(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F4RX(MethodHandle e, MethodHandle f, MethodHandle t)
+ static class F2X extends Adapter {
+ protected F2X(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F2X(MethodHandle e, MethodHandle f, MethodHandle t)
{ super(e, f, t); }
- protected F4RX makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
- { return new F4RX(e, f, t); }
- protected Object filter(Object a0) { return filter.<Object>invoke(a0); }
- protected Object target(Object a0, Object a1, Object a2, Object a3) { return target.<Object>invoke(a0, a1, a2, a3); }
- protected Object invoke_R0(Object a0, Object a1, Object a2, Object a3) { return target(filter(a0), a1, a2, a3); }
- protected Object invoke_R1(Object a0, Object a1, Object a2, Object a3) { return target(a0, filter(a1), a2, a3); }
- protected Object invoke_R2(Object a0, Object a1, Object a2, Object a3) { return target(a0, a1, filter(a2), a3); }
- protected Object invoke_R3(Object a0, Object a1, Object a2, Object a3) { return target(a0, a1, a2, filter(a3)); }
+ protected F2X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
+ { return new F2X(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1) { return target.invoke(filter.invoke(a0), a1); }
+ protected Object invoke_V1(Object a0, Object a1) { return target.invoke(a0, filter.invoke(a1)); }
+ protected Object invoke_F0(Object a0, Object a1) { return target.invoke(filter.invoke(), a0, a1); }
+ protected Object invoke_F1(Object a0, Object a1) { return target.invoke(filter.invoke(a0), a0, a1); }
+ protected Object invoke_F2(Object a0, Object a1) { return target.invoke(filter.invoke(a0, a1), a0, a1); }
+ protected Object invoke_C0(Object a0, Object a1) { return target.invoke(filter.invoke(a0, a1)); }
+ protected Object invoke_C1(Object a0, Object a1) { return target.invoke(a0, filter.invoke(a1)); }
+ protected Object invoke_C2(Object a0, Object a1) { return target.invoke(a0, a1, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1) { Object[] av = { a0, a1 };
+ filter.<void>invoke(av); return target.invoke(av[0], av[1]); }
}
// */
+
+ // This one is written by hand:
+ static class F0 extends Adapter {
+ protected F0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F0(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F0 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F0(e, f, t); }
+ protected Object invoke_F0() throws Throwable {
+ return target.invoke(filter.invoke()); }
+ protected Object invoke_C0() throws Throwable {
+ return target.invoke(filter.invoke()); }
+ static final Object[] NO_ARGS = { };
+ protected Object invoke_Y0() throws Throwable {
+ filter.<void>invoke(NO_ARGS); // make the flyby
+ return target.invoke(); }
+ }
+
+/*
+ : SHELL; n=FilterGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -ea -cp . genclasses | sed 's| *[/]/ *$||') >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
+//{{{
+import java.util.*;
+class genclasses {
+ static String[][] TEMPLATES = { {
+ "@for@ N=1..20",
+ " //@each-cat@",
+ " static class @cat@ extends Adapter {",
+ " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
+ " protected @cat@(MethodHandle e, MethodHandle f, MethodHandle t) {",
+ " super(e, f, t); }",
+ " protected @cat@ makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {",
+ " return new @cat@(e, f, t); }",
+ " //@each-P@",
+ " protected Object invoke_V@P@(@Tvav@) throws Throwable {",
+ " return target.invoke(@a0_@@Psp@filter.invoke(a@P@)@_aN@); }",
+ " //@end-P@",
+ " //@each-P@",
+ " protected Object invoke_F@P@(@Tvav@) throws Throwable {",
+ " return target.invoke(filter.invoke(@a0@),",
+ " @av@); }",
+ " //@end-P@",
+ " protected Object invoke_F@N@(@Tvav@) throws Throwable {",
+ " return target.invoke(filter.invoke(@av@),",
+ " @av@); }",
+ " //@each-P@",
+ " protected Object invoke_C@P@(@Tvav@) throws Throwable {",
+ " return target.invoke(@a0_@filter.invoke(a@P@@_aN@)); }",
+ " //@end-P@",
+ " protected Object invoke_C@N@(@Tvav@) throws Throwable {",
+ " return target.invoke(@av@, filter.invoke()); }",
+ " protected Object invoke_Y0(@Tvav@) throws Throwable {",
+ " Object[] av = { @av@ };",
+ " filter.<void>invoke(av); // make the flyby",
+ " return target.invoke(@av[i]@); }",
+ " }",
+ } };
+ static final String NEWLINE_INDENT = " //\n ";
+ enum VAR {
+ cat, N, P, Tvav, av, a0, a0_, _aN, Psp, av_i_;
+ public final String pattern = "@"+toString().replace('_','.')+"@";
+ public String binding = toString();
+ static void makeBindings(boolean topLevel, int inargs, int pos) {
+ assert(-1 <= pos && pos < inargs);
+ VAR.cat.binding = "F"+inargs;
+ VAR.N.binding = String.valueOf(inargs); // incoming arg count
+ VAR.P.binding = String.valueOf(pos); // selected arg position
+ String[] av = new String[inargs];
+ String[] Tvav = new String[inargs];
+ String[] av_i_ = new String[inargs];
+ for (int i = 0; i < inargs; i++) {
+ av[i] = arg(i);
+ av_i_[i] = "av["+i+"]";
+ String spc = "";
+ if (i > 0 && i % 4 == 0) spc = NEWLINE_INDENT+(pos>9?" ":"")+" ";
+ Tvav[i] = spc+param("Object", av[i]);
+ }
+ VAR.av.binding = comma(av);
+ VAR.av_i_.binding = comma(av_i_);
+ VAR.Tvav.binding = comma(Tvav);
+ if (pos >= 0) {
+ VAR.Psp.binding = (pos > 0 && pos % 10 == 0) ? NEWLINE_INDENT : "";
+ String[] a0 = new String[pos];
+ String[] aN = new String[inargs - (pos+1)];
+ for (int i = 0; i < pos; i++) {
+ String spc = "";
+ if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
+ a0[i] = spc+av[i];
+ }
+ VAR.a0.binding = comma(a0);
+ VAR.a0_.binding = comma(a0, ", ");
+ for (int i = pos+1; i < inargs; i++) {
+ String spc = "";
+ if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
+ aN[i - (pos+1)] = spc+av[i];
+ }
+ VAR._aN.binding = comma(", ", aN);
+ }
+ }
+ static String arg(int i) { return "a"+i; }
+ static String param(String t, String a) { return t+" "+a; }
+ static String comma(String[] v) { return comma(v, ""); }
+ static String comma(String[] v, String sep) { return comma("", v, sep); }
+ static String comma(String sep, String[] v) { return comma(sep, v, ""); }
+ static String comma(String sep1, String[] v, String sep2) {
+ if (v.length == 0) return "";
+ String res = v[0];
+ for (int i = 1; i < v.length; i++) res += ", "+v[i];
+ return sep1 + res + sep2;
+ }
+ static String transform(String string) {
+ for (VAR var : values())
+ string = string.replaceAll(var.pattern, var.binding);
+ return string;
+ }
+ }
+ static String[] stringsIn(String[] strings, int beg, int end) {
+ return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
+ }
+ static String[] stringsBefore(String[] strings, int pos) {
+ return stringsIn(strings, 0, pos);
+ }
+ static String[] stringsAfter(String[] strings, int pos) {
+ return stringsIn(strings, pos, strings.length);
+ }
+ static int indexAfter(String[] strings, int pos, String tag) {
+ return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
+ }
+ static int indexBefore(String[] strings, int pos, String tag) {
+ for (int i = pos, end = strings.length; ; i++) {
+ if (i == end || strings[i].endsWith(tag)) return i;
+ }
+ }
+ static int MIN_ARITY, MAX_ARITY;
+ public static void main(String... av) {
+ for (String[] template : TEMPLATES) {
+ int forLinesLimit = indexBefore(template, 0, "@each-cat@");
+ String[] forLines = stringsBefore(template, forLinesLimit);
+ template = stringsAfter(template, forLinesLimit);
+ for (String forLine : forLines)
+ expandTemplate(forLine, template);
+ }
+ }
+ static void expandTemplate(String forLine, String[] template) {
+ String[] params = forLine.split("[^0-9]+");
+ if (params[0].length() == 0) params = stringsAfter(params, 1);
+ System.out.println("//params="+Arrays.asList(params));
+ int pcur = 0;
+ MIN_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_ARITY = Integer.valueOf(params[pcur++]);
+ if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
+ for (int inargs = MIN_ARITY; inargs <= MAX_ARITY; inargs++) {
+ expandTemplate(template, true, inargs, -1);
+ }
+ }
+ static void expandTemplate(String[] template, boolean topLevel, int inargs, int pos) {
+ VAR.makeBindings(topLevel, inargs, pos);
+ for (int i = 0; i < template.length; i++) {
+ String line = template[i];
+ if (line.endsWith("@each-cat@")) {
+ // ignore
+ } else if (line.endsWith("@each-P@")) {
+ int blockEnd = indexAfter(template, i, "@end-P@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ for (int pos1 = Math.max(0,pos); pos1 < inargs; pos1++)
+ expandTemplate(block, false, inargs, pos1);
+ VAR.makeBindings(topLevel, inargs, pos);
+ i = blockEnd-1; continue;
+ } else {
+ System.out.println(VAR.transform(line));
+ }
+ }
+ }
}
+//}}} */
+//params=[1, 20]
+ static class F1 extends Adapter {
+ protected F1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F1(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F1 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F1(e, f, t); }
+ protected Object invoke_V0(Object a0) throws Throwable {
+ return target.invoke(filter.invoke(a0)); }
+ protected Object invoke_F0(Object a0) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0); }
+ protected Object invoke_F1(Object a0) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0); }
+ protected Object invoke_C0(Object a0) throws Throwable {
+ return target.invoke(filter.invoke(a0)); }
+ protected Object invoke_C1(Object a0) throws Throwable {
+ return target.invoke(a0, filter.invoke()); }
+ protected Object invoke_Y0(Object a0) throws Throwable {
+ Object[] av = { a0 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0]); }
+ }
+ static class F2 extends Adapter {
+ protected F2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F2(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F2 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F2(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1); }
+ protected Object invoke_V1(Object a0, Object a1) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1)); }
+ protected Object invoke_F0(Object a0, Object a1) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1); }
+ protected Object invoke_F1(Object a0, Object a1) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1); }
+ protected Object invoke_F2(Object a0, Object a1) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1); }
+ protected Object invoke_C0(Object a0, Object a1) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1)); }
+ protected Object invoke_C1(Object a0, Object a1) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1)); }
+ protected Object invoke_C2(Object a0, Object a1) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1) throws Throwable {
+ Object[] av = { a0, a1 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1]); }
+ }
+ static class F3 extends Adapter {
+ protected F3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F3(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F3 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F3(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2) throws Throwable {
+ Object[] av = { a0, a1, a2 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2]); }
+ }
+ static class F4 extends Adapter {
+ protected F4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F4(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F4 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F4(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ Object[] av = { a0, a1, a2, a3 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3]); }
+ }
+ static class F5 extends Adapter {
+ protected F5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F5(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F5 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F5(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4]); }
+ }
+ static class F6 extends Adapter {
+ protected F6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F6(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F6 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F6(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5]); }
+ }
+ static class F7 extends Adapter {
+ protected F7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F7(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F7 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F7(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6]); }
+ }
+ static class F8 extends Adapter {
+ protected F8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F8(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F8 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F8(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7]); }
+ }
+ static class F9 extends Adapter {
+ protected F9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F9(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F9 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F9(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8]); }
+ }
+ static class F10 extends Adapter {
+ protected F10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F10(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F10 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F10(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9]); }
+ }
+ static class F11 extends Adapter {
+ protected F11(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F11(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F11 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F11(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10]); }
+ }
+ static class F12 extends Adapter {
+ protected F12(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F12(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F12 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F12(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11]); }
+ }
+ static class F13 extends Adapter {
+ protected F13(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F13(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F13 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F13(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12]); }
+ }
+ static class F14 extends Adapter {
+ protected F14(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F14(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F14 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F14(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13]); }
+ }
+ static class F15 extends Adapter {
+ protected F15(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F15(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F15 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F15(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13, a14); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13, a14); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13, a14); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13), a14); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13, a14)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13, a14)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13, a14)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13, a14)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14]); }
+ }
+ static class F16 extends Adapter {
+ protected F16(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F16(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F16 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F16(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13, a14, a15); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13, a14, a15); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13, a14, a15); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13), a14, a15); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14), a15); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13, a14, a15)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13, a14, a15)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13, a14, a15)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14, a15)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15]); }
+ }
+ static class F17 extends Adapter {
+ protected F17(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F17(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F17 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F17(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13, a14, a15, a16); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13, a14, a15, a16); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13), a14, a15, a16); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14), a15, a16); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15), a16); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13, a14, a15, a16)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13, a14, a15, a16)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14, a15, a16)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15, a16)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16]); }
+ }
+ static class F18 extends Adapter {
+ protected F18(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F18(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F18 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F18(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13, a14, a15, a16, a17); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13), a14, a15, a16, a17); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14), a15, a16, a17); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15), a16, a17); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16), a17); }
+ protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invoke(a17)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13, a14, a15, a16, a17)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14, a15, a16, a17)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15, a16, a17)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16, a17)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invoke(a17)); }
+ protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17]); }
+ }
+ static class F19 extends Adapter {
+ protected F19(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F19(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F19 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F19(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13), a14, a15, a16, a17, a18); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14), a15, a16, a17, a18); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15), a16, a17, a18); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16), a17, a18); }
+ protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invoke(a17), a18); }
+ protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invoke(a18)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14, a15, a16, a17, a18)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15, a16, a17, a18)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16, a17, a18)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invoke(a17, a18)); }
+ protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invoke(a18)); }
+ protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18]); }
+ }
+ static class F20 extends Adapter {
+ protected F20(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F20(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F20 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F20(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9),
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invoke(a10), a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11), a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12), a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13), a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14), a15, a16, a17, a18, a19); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15), a16, a17, a18, a19); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16), a17, a18, a19); }
+ protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invoke(a17), a18, a19); }
+ protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invoke(a18), a19); }
+ protected Object invoke_V19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invoke(a19)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F20(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(filter.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, filter.invoke(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, filter.invoke(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, filter.invoke(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, filter.invoke(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, filter.invoke(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, filter.invoke(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, filter.invoke(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, filter.invoke(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invoke(a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invoke(a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invoke(a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invoke(a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invoke(a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invoke(a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invoke(a15, a16, a17, a18, a19)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invoke(a16, a17, a18, a19)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invoke(a17, a18, a19)); }
+ protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invoke(a18, a19)); }
+ protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invoke(a19)); }
+ protected Object invoke_C20(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, filter.invoke()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19 };
+ filter.<void>invoke(av); // make the flyby
+ return target.invoke(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18], av[19]); }
+ }
+}
--- a/jdk/src/share/classes/sun/dyn/FilterOneArgument.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/FilterOneArgument.java Wed Jul 05 17:04:56 2017 +0200
@@ -27,7 +27,6 @@
import java.dyn.JavaMethodHandle;
import java.dyn.MethodHandle;
-import java.dyn.MethodHandles;
import java.dyn.MethodType;
/**
@@ -42,16 +41,21 @@
protected final MethodHandle filter; // Object -> Object
protected final MethodHandle target; // Object -> Object
- protected Object entryPoint(Object argument) {
- Object filteredArgument = filter.<Object>invoke(argument);
- return target.<Object>invoke(filteredArgument);
+ @Override
+ public String toString() {
+ return target.toString();
}
- private static final MethodHandle entryPoint =
- MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "entryPoint", MethodType.makeGeneric(1));
+ protected Object invoke(Object argument) throws Throwable {
+ Object filteredArgument = filter.invoke(argument);
+ return target.invoke(filteredArgument);
+ }
+
+ private static final MethodHandle INVOKE =
+ MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke", MethodType.genericMethodType(1));
protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
- super(entryPoint);
+ super(INVOKE);
this.filter = filter;
this.target = target;
}
@@ -62,10 +66,6 @@
return new FilterOneArgument(filter, target);
}
- public String toString() {
- return filter + "|>" + target;
- }
-
// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
// MethodHandle filter = make(filter1, filter2);
// return make(filter, target);
--- a/jdk/src/share/classes/sun/dyn/FromGeneric.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/FromGeneric.java Wed Jul 05 17:04:56 2017 +0200
@@ -36,8 +36,8 @@
import sun.dyn.util.Wrapper;
/**
- * Adapters which mediate between incoming calls which are not generic
- * and outgoing calls which are. Any call can be represented generically
+ * Adapters which mediate between incoming calls which are generic
+ * and outgoing calls which are not. Any call can be represented generically
* boxing up its arguments, and (on return) unboxing the return value.
* <p>
* A call is "generic" (in MethodHandle terms) if its MethodType features
@@ -50,9 +50,6 @@
* either binds internally or else takes as a leading argument).
* (To stretch the term, adapter-like method handles may have multiple
* targets or be polymorphic across multiple call types.)
- * <p>
- * This adapter can sometimes be more directly implemented
- * by the JVM's built-in OP_SPREAD_ARGS adapter.
* @author jrose
*/
class FromGeneric {
@@ -99,7 +96,7 @@
}
this.internalType = internalType0;
this.adapter = ad;
- MethodType tepType = targetType.insertParameterType(0, adapter.getClass());
+ MethodType tepType = targetType.insertParameterTypes(0, adapter.getClass());
this.entryPoint = ad.prototypeEntryPoint();
this.returnConversion = computeReturnConversion(targetType, internalType0);
this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
@@ -146,7 +143,7 @@
if (fixArgs == null)
throw new InternalError("bad fixArgs");
// reinterpret the calling sequence as raw:
- MethodHandle retyper = AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN,
+ MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN,
Invokers.invokerType(internalType), fixArgs);
if (retyper == null)
throw new InternalError("bad retyper");
@@ -226,7 +223,10 @@
// Produce an instance configured as a prototype.
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
- } catch (InvocationTargetException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
@@ -260,6 +260,11 @@
protected final MethodHandle convert; // raw(R) => Object
protected final MethodHandle target; // (any**N) => R
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+
protected boolean isPrototype() { return target == null; }
protected Adapter(MethodHandle entryPoint) {
this(entryPoint, null, entryPoint, null);
@@ -284,11 +289,11 @@
// { return new ThisType(entryPoint, convert, target); }
/// Conversions on the value returned from the target.
- protected Object convert_L(Object result) { return convert.<Object>invoke(result); }
- protected Object convert_I(int result) { return convert.<Object>invoke(result); }
- protected Object convert_J(long result) { return convert.<Object>invoke(result); }
- protected Object convert_F(float result) { return convert.<Object>invoke(result); }
- protected Object convert_D(double result) { return convert.<Object>invoke(result); }
+ protected Object convert_L(Object result) throws Throwable { return convert.<Object>invoke(result); }
+ protected Object convert_I(int result) throws Throwable { return convert.<Object>invoke(result); }
+ protected Object convert_J(long result) throws Throwable { return convert.<Object>invoke(result); }
+ protected Object convert_F(float result) throws Throwable { return convert.<Object>invoke(result); }
+ protected Object convert_D(double result) throws Throwable { return convert.<Object>invoke(result); }
static private final String CLASS_PREFIX; // "sun.dyn.FromGeneric$"
static {
@@ -317,11 +322,11 @@
{ super(e, i, c, t); }
protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new xA2(e, i, c, t); }
- protected Object invoke_L2(Object a0, Object a1) { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
- protected Object invoke_I2(Object a0, Object a1) { return convert_I(invoker.<int >invoke(target, a0, a1)); }
- protected Object invoke_J2(Object a0, Object a1) { return convert_J(invoker.<long >invoke(target, a0, a1)); }
- protected Object invoke_F2(Object a0, Object a1) { return convert_F(invoker.<float >invoke(target, a0, a1)); }
- protected Object invoke_D2(Object a0, Object a1) { return convert_D(invoker.<double>invoke(target, a0, a1)); }
+ protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
+ protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1)); }
+ protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1)); }
+ protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1)); }
+ protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1)); }
}
// */
@@ -342,7 +347,7 @@
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
" { return new @cat@(e, i, c, t); }",
" //@each-R@",
- " protected Object invoke_@catN@(@Tvav@) { return convert_@Rc@(invoker.<@R@>invoke(target@av@)); }",
+ " protected Object invoke_@catN@(@Tvav@) throws Throwable { return convert_@Rc@(invoker.<@R@>invoke(target@av@)); }",
" //@end-R@",
" }",
} };
@@ -498,11 +503,11 @@
{ super(e, i, c, t); }
protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A0(e, i, c, t); }
- protected Object invoke_L0() { return convert_L(invoker.<Object>invoke(target)); }
- protected Object invoke_I0() { return convert_I(invoker.<int >invoke(target)); }
- protected Object invoke_J0() { return convert_J(invoker.<long >invoke(target)); }
- protected Object invoke_F0() { return convert_F(invoker.<float >invoke(target)); }
- protected Object invoke_D0() { return convert_D(invoker.<double>invoke(target)); }
+ protected Object invoke_L0() throws Throwable { return convert_L(invoker.<Object>invoke(target)); }
+ protected Object invoke_I0() throws Throwable { return convert_I(invoker.<int >invoke(target)); }
+ protected Object invoke_J0() throws Throwable { return convert_J(invoker.<long >invoke(target)); }
+ protected Object invoke_F0() throws Throwable { return convert_F(invoker.<float >invoke(target)); }
+ protected Object invoke_D0() throws Throwable { return convert_D(invoker.<double>invoke(target)); }
}
static class A1 extends Adapter {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -510,11 +515,11 @@
{ super(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A1(e, i, c, t); }
- protected Object invoke_L1(Object a0) { return convert_L(invoker.<Object>invoke(target, a0)); }
- protected Object invoke_I1(Object a0) { return convert_I(invoker.<int >invoke(target, a0)); }
- protected Object invoke_J1(Object a0) { return convert_J(invoker.<long >invoke(target, a0)); }
- protected Object invoke_F1(Object a0) { return convert_F(invoker.<float >invoke(target, a0)); }
- protected Object invoke_D1(Object a0) { return convert_D(invoker.<double>invoke(target, a0)); }
+ protected Object invoke_L1(Object a0) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0)); }
+ protected Object invoke_I1(Object a0) throws Throwable { return convert_I(invoker.<int >invoke(target, a0)); }
+ protected Object invoke_J1(Object a0) throws Throwable { return convert_J(invoker.<long >invoke(target, a0)); }
+ protected Object invoke_F1(Object a0) throws Throwable { return convert_F(invoker.<float >invoke(target, a0)); }
+ protected Object invoke_D1(Object a0) throws Throwable { return convert_D(invoker.<double>invoke(target, a0)); }
}
static class A2 extends Adapter {
protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -522,11 +527,11 @@
{ super(e, i, c, t); }
protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A2(e, i, c, t); }
- protected Object invoke_L2(Object a0, Object a1) { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
- protected Object invoke_I2(Object a0, Object a1) { return convert_I(invoker.<int >invoke(target, a0, a1)); }
- protected Object invoke_J2(Object a0, Object a1) { return convert_J(invoker.<long >invoke(target, a0, a1)); }
- protected Object invoke_F2(Object a0, Object a1) { return convert_F(invoker.<float >invoke(target, a0, a1)); }
- protected Object invoke_D2(Object a0, Object a1) { return convert_D(invoker.<double>invoke(target, a0, a1)); }
+ protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
+ protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1)); }
+ protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1)); }
+ protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1)); }
+ protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1)); }
}
static class A3 extends Adapter {
protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -534,11 +539,11 @@
{ super(e, i, c, t); }
protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A3(e, i, c, t); }
- protected Object invoke_L3(Object a0, Object a1, Object a2) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2)); }
- protected Object invoke_I3(Object a0, Object a1, Object a2) { return convert_I(invoker.<int >invoke(target, a0, a1, a2)); }
- protected Object invoke_J3(Object a0, Object a1, Object a2) { return convert_J(invoker.<long >invoke(target, a0, a1, a2)); }
- protected Object invoke_F3(Object a0, Object a1, Object a2) { return convert_F(invoker.<float >invoke(target, a0, a1, a2)); }
- protected Object invoke_D3(Object a0, Object a1, Object a2) { return convert_D(invoker.<double>invoke(target, a0, a1, a2)); }
+ protected Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2)); }
+ protected Object invoke_I3(Object a0, Object a1, Object a2) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2)); }
+ protected Object invoke_J3(Object a0, Object a1, Object a2) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2)); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2)); }
+ protected Object invoke_D3(Object a0, Object a1, Object a2) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2)); }
}
static class A4 extends Adapter {
protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -546,11 +551,11 @@
{ super(e, i, c, t); }
protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A4(e, i, c, t); }
- protected Object invoke_L4(Object a0, Object a1, Object a2, Object a3) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3)); }
- protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3)); }
- protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3)); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3)); }
- protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3)); }
+ protected Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3)); }
+ protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3)); }
+ protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3)); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3)); }
+ protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3)); }
}
static class A5 extends Adapter {
protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -558,11 +563,11 @@
{ super(e, i, c, t); }
protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A5(e, i, c, t); }
- protected Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_I5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_J5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_D5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_I5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_J5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_D5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4)); }
}
static class A6 extends Adapter {
protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -570,11 +575,11 @@
{ super(e, i, c, t); }
protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A6(e, i, c, t); }
- protected Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_I6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_J6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_D6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_I6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_J6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_D6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5)); }
}
static class A7 extends Adapter {
protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -582,11 +587,11 @@
{ super(e, i, c, t); }
protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A7(e, i, c, t); }
- protected Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_I7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_J7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_D7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_I7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_J7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_D7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
}
static class A8 extends Adapter {
protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -594,11 +599,11 @@
{ super(e, i, c, t); }
protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A8(e, i, c, t); }
- protected Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_I8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_J8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_D8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_I8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_J8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_D8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
}
static class A9 extends Adapter {
protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -606,11 +611,11 @@
{ super(e, i, c, t); }
protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A9(e, i, c, t); }
- protected Object invoke_L9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_I9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_J9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_D9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_I9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_J9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_D9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
}
static class A10 extends Adapter {
protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
@@ -618,10 +623,10 @@
{ super(e, i, c, t); }
protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new A10(e, i, c, t); }
- protected Object invoke_L10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_I10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_J10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_D10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_I10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_J10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_D10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
}
}
--- a/jdk/src/share/classes/sun/dyn/Invokers.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/Invokers.java Wed Jul 05 17:04:56 2017 +0200
@@ -44,16 +44,20 @@
// generic (untyped) invoker for the outgoing call
private /*lazy*/ MethodHandle genericInvoker;
+ // generic (untyped) invoker for the outgoing call; accepts a single Object[]
+ private final /*lazy*/ MethodHandle[] varargsInvokers;
+
/** Compute and cache information common to all collecting adapters
* that implement members of the erasure-family of the given erased type.
*/
public Invokers(Access token, MethodType targetType) {
Access.check(token);
this.targetType = targetType;
+ this.varargsInvokers = new MethodHandle[targetType.parameterCount()+1];
}
public static MethodType invokerType(MethodType targetType) {
- return targetType.insertParameterType(0, MethodHandle.class);
+ return targetType.insertParameterTypes(0, MethodHandle.class);
}
public MethodHandle exactInvoker() {
@@ -76,8 +80,14 @@
return invoker;
}
- public MethodHandle varargsInvoker() {
- throw new UnsupportedOperationException("NYI");
+ public MethodHandle varargsInvoker(int objectArgCount) {
+ MethodHandle vaInvoker = varargsInvokers[objectArgCount];
+ if (vaInvoker != null) return vaInvoker;
+ MethodHandle gInvoker = genericInvoker();
+ MethodType vaType = MethodType.genericMethodType(objectArgCount, true);
+ vaInvoker = MethodHandles.spreadArguments(gInvoker, invokerType(vaType));
+ varargsInvokers[objectArgCount] = vaInvoker;
+ return vaInvoker;
}
public String toString() {
--- a/jdk/src/share/classes/sun/dyn/MemberName.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/MemberName.java Wed Jul 05 17:04:56 2017 +0200
@@ -25,7 +25,7 @@
package sun.dyn;
-import sun.dyn.util.BytecodeSignature;
+import sun.dyn.util.BytecodeDescriptor;
import java.dyn.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -33,6 +33,7 @@
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -93,7 +94,7 @@
}
if (type instanceof String) {
String sig = (String) type;
- MethodType res = MethodType.fromBytecodeString(sig, getClassLoader());
+ MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
this.type = res;
return res;
}
@@ -101,7 +102,7 @@
Object[] typeInfo = (Object[]) type;
Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
Class<?> rtype = (Class<?>) typeInfo[0];
- MethodType res = MethodType.make(rtype, ptypes);
+ MethodType res = MethodType.methodType(rtype, ptypes);
this.type = res;
return res;
}
@@ -111,7 +112,7 @@
public MethodType getInvocationType() {
MethodType itype = getMethodType();
if (!isStatic())
- itype = itype.insertParameterType(0, clazz);
+ itype = itype.insertParameterTypes(0, clazz);
return itype;
}
@@ -135,7 +136,7 @@
}
if (type instanceof String) {
String sig = (String) type;
- MethodType mtype = MethodType.fromBytecodeString("()"+sig, getClassLoader());
+ MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
Class<?> res = mtype.returnType();
this.type = res;
return res;
@@ -155,9 +156,9 @@
if (type instanceof String)
return (String) type;
if (isInvocable())
- return BytecodeSignature.unparse(getMethodType());
+ return BytecodeDescriptor.unparse(getMethodType());
else
- return BytecodeSignature.unparse(getFieldType());
+ return BytecodeDescriptor.unparse(getFieldType());
}
public int getModifiers() {
@@ -353,6 +354,8 @@
return type.toString(); // class java.lang.String
// else it is a field, method, or constructor
StringBuilder buf = new StringBuilder();
+ if (!isResolved())
+ buf.append("*.");
if (getDeclaringClass() != null) {
buf.append(getName(clazz));
buf.append('.');
@@ -381,7 +384,7 @@
private static String getName(Object obj) {
if (obj instanceof Class<?>)
return ((Class<?>)obj).getName();
- return obj.toString();
+ return String.valueOf(obj);
}
// Queries to the JVM:
@@ -408,6 +411,9 @@
public static NoAccessException newNoAccessException(MemberName name, Class<?> lookupClass) {
return newNoAccessException("cannot access", name, lookupClass);
}
+ public static NoAccessException newNoAccessException(MemberName name, MethodHandles.Lookup lookup) {
+ return newNoAccessException(name, lookup.lookupClass());
+ }
public static NoAccessException newNoAccessException(String message,
MemberName name, Class<?> lookupClass) {
message += ": " + name;
@@ -436,7 +442,7 @@
matchFlags &= ALLOWED_FLAGS;
String matchSig = null;
if (matchType != null) {
- matchSig = BytecodeSignature.unparse(matchType);
+ matchSig = BytecodeDescriptor.unparse(matchType);
if (matchSig.startsWith("("))
matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
else
@@ -447,17 +453,18 @@
MemberName[] buf = newMemberBuffer(len1);
int totalCount = 0;
ArrayList<MemberName[]> bufs = null;
+ int bufCount = 0;
for (;;) {
- int bufCount = MethodHandleNatives.getMembers(defc,
+ bufCount = MethodHandleNatives.getMembers(defc,
matchName, matchSig, matchFlags,
lookupClass,
totalCount, buf);
if (bufCount <= buf.length) {
- if (bufCount >= 0)
- totalCount += bufCount;
+ if (bufCount < 0) bufCount = 0;
+ totalCount += bufCount;
break;
}
- // JVM returned tp us with an intentional overflow!
+ // JVM returned to us with an intentional overflow!
totalCount += buf.length;
int excess = bufCount - buf.length;
if (bufs == null) bufs = new ArrayList<MemberName[]>(1);
@@ -473,7 +480,7 @@
Collections.addAll(result, buf0);
}
}
- Collections.addAll(result, buf);
+ result.addAll(Arrays.asList(buf).subList(0, bufCount));
// Signature matching is not the same as type matching, since
// one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results.
--- a/jdk/src/share/classes/sun/dyn/MethodHandleImpl.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/MethodHandleImpl.java Wed Jul 05 17:04:56 2017 +0200
@@ -25,12 +25,25 @@
package sun.dyn;
+import java.dyn.JavaMethodHandle;
import java.dyn.MethodHandle;
import java.dyn.MethodHandles;
import java.dyn.MethodHandles.Lookup;
import java.dyn.MethodType;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import sun.dyn.util.VerifyType;
import java.dyn.NoAccessException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import sun.dyn.empty.Empty;
+import sun.dyn.util.ValueConversions;
+import sun.dyn.util.Wrapper;
+import sun.misc.Unsafe;
import static sun.dyn.MemberName.newIllegalArgumentException;
import static sun.dyn.MemberName.newNoAccessException;
@@ -57,6 +70,25 @@
static final int INT_FIELD = 0;
static final long LONG_FIELD = 0;
+ /** Access methods for the internals of MethodHandle, supplied to
+ * MethodHandleImpl as a trusted agent.
+ */
+ static public interface MethodHandleFriend {
+ void initType(MethodHandle mh, MethodType type);
+ }
+ public static void setMethodHandleFriend(Access token, MethodHandleFriend am) {
+ Access.check(token);
+ if (METHOD_HANDLE_FRIEND != null)
+ throw new InternalError(); // just once
+ METHOD_HANDLE_FRIEND = am;
+ }
+ static private MethodHandleFriend METHOD_HANDLE_FRIEND;
+
+ // NOT public
+ static void initType(MethodHandle mh, MethodType type) {
+ METHOD_HANDLE_FRIEND.initType(mh, type);
+ }
+
// type is defined in java.dyn.MethodHandle, which is platform-independent
// vmentry (a void* field) is used *only* by by the JVM.
@@ -106,8 +138,8 @@
}
static {
- // Force initialization:
- Lookup.PUBLIC_LOOKUP.lookupClass();
+ // Force initialization of Lookup, so it calls us back as initLookup:
+ MethodHandles.publicLookup();
if (IMPL_LOOKUP_INIT == null)
throw new InternalError();
}
@@ -151,7 +183,7 @@
// adjust the advertised receiver type to be exactly the one requested
// (in the case of invokespecial, this will be the calling class)
Class<?> recvType = method.getDeclaringClass();
- mtype = mtype.insertParameterType(0, recvType);
+ mtype = mtype.insertParameterTypes(0, recvType);
if (method.isConstructor())
doDispatch = true;
// FIXME: JVM has trouble building MH.invoke sites for
@@ -170,21 +202,223 @@
public static
MethodHandle accessField(Access token,
- MemberName member, boolean isSetter,
- Class<?> lookupClass) {
+ MemberName member, boolean isSetter,
+ Class<?> lookupClass) {
Access.check(token);
- // FIXME: Use sun.misc.Unsafe to dig up the dirt on the field.
- throw new UnsupportedOperationException("Not yet implemented");
+ // Use sun. misc.Unsafe to dig up the dirt on the field.
+ MethodHandle mh = new FieldAccessor(token, member, isSetter);
+ return mh;
}
public static
MethodHandle accessArrayElement(Access token,
- Class<?> arrayClass, boolean isSetter) {
+ Class<?> arrayClass, boolean isSetter) {
Access.check(token);
if (!arrayClass.isArray())
throw newIllegalArgumentException("not an array: "+arrayClass);
- // FIXME: Use sun.misc.Unsafe to dig up the dirt on the array.
- throw new UnsupportedOperationException("Not yet implemented");
+ Class<?> elemClass = arrayClass.getComponentType();
+ MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass);
+ if (mhs == null) {
+ if (!FieldAccessor.doCache(elemClass))
+ return FieldAccessor.ahandle(arrayClass, isSetter);
+ mhs = new MethodHandle[] {
+ FieldAccessor.ahandle(arrayClass, false),
+ FieldAccessor.ahandle(arrayClass, true)
+ };
+ if (mhs[0].type().parameterType(0) == Class.class) {
+ mhs[0] = MethodHandles.insertArguments(mhs[0], 0, elemClass);
+ mhs[1] = MethodHandles.insertArguments(mhs[1], 0, elemClass);
+ }
+ synchronized (FieldAccessor.ARRAY_CACHE) {} // memory barrier
+ FieldAccessor.ARRAY_CACHE.put(elemClass, mhs);
+ }
+ return mhs[isSetter ? 1 : 0];
+ }
+
+ static final class FieldAccessor<C,V> extends JavaMethodHandle {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ final Object base; // for static refs only
+ final long offset;
+ final String name;
+
+ public FieldAccessor(Access token, MemberName field, boolean isSetter) {
+ super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic()));
+ this.offset = (long) field.getVMIndex(token);
+ this.name = field.getName();
+ this.base = staticBase(field);
+ }
+ public String toString() { return name; }
+
+ int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
+ void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
+ long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
+ void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
+ float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
+ void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
+ double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
+ void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
+ boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
+ void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
+ byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
+ void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
+ short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
+ void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
+ char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
+ void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
+ @SuppressWarnings("unchecked")
+ V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
+ @SuppressWarnings("unchecked")
+ void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
+ // cast (V) is OK here, since we wrap convertArguments around the MH.
+
+ static Object staticBase(MemberName field) {
+ if (!field.isStatic()) return null;
+ Class c = field.getDeclaringClass();
+ java.lang.reflect.Field f;
+ try {
+ // FIXME: Should not have to create 'f' to get this value.
+ f = c.getDeclaredField(field.getName());
+ return unsafe.staticFieldBase(f);
+ } catch (Exception ee) {
+ Error e = new InternalError();
+ e.initCause(ee);
+ throw e;
+ }
+ }
+
+ int getStaticI() { return unsafe.getInt(base, offset); }
+ void setStaticI(int x) { unsafe.putInt(base, offset, x); }
+ long getStaticJ() { return unsafe.getLong(base, offset); }
+ void setStaticJ(long x) { unsafe.putLong(base, offset, x); }
+ float getStaticF() { return unsafe.getFloat(base, offset); }
+ void setStaticF(float x) { unsafe.putFloat(base, offset, x); }
+ double getStaticD() { return unsafe.getDouble(base, offset); }
+ void setStaticD(double x) { unsafe.putDouble(base, offset, x); }
+ boolean getStaticZ() { return unsafe.getBoolean(base, offset); }
+ void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); }
+ byte getStaticB() { return unsafe.getByte(base, offset); }
+ void setStaticB(byte x) { unsafe.putByte(base, offset, x); }
+ short getStaticS() { return unsafe.getShort(base, offset); }
+ void setStaticS(short x) { unsafe.putShort(base, offset, x); }
+ char getStaticC() { return unsafe.getChar(base, offset); }
+ void setStaticC(char x) { unsafe.putChar(base, offset, x); }
+ V getStaticL() { return (V) unsafe.getObject(base, offset); }
+ void setStaticL(V x) { unsafe.putObject(base, offset, x); }
+
+ static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) {
+ String stem;
+ if (!isStatic)
+ stem = (!isSetter ? "getField" : "setField");
+ else
+ stem = (!isSetter ? "getStatic" : "setStatic");
+ return stem + Wrapper.basicTypeChar(vclass);
+ }
+ static MethodType ftype(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) {
+ MethodType type;
+ if (!isStatic) {
+ if (!isSetter)
+ return MethodType.methodType(vclass, cclass);
+ else
+ return MethodType.methodType(void.class, cclass, vclass);
+ } else {
+ if (!isSetter)
+ return MethodType.methodType(vclass);
+ else
+ return MethodType.methodType(void.class, vclass);
+ }
+ }
+ static MethodHandle fhandle(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) {
+ String name = FieldAccessor.fname(vclass, isSetter, isStatic);
+ if (cclass.isPrimitive()) throw newIllegalArgumentException("primitive "+cclass);
+ Class<?> ecclass = Object.class; //erase this type
+ Class<?> evclass = vclass;
+ if (!evclass.isPrimitive()) evclass = Object.class;
+ MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic);
+ MethodHandle mh;
+ try {
+ mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
+ } catch (NoAccessException ee) {
+ Error e = new InternalError("name,type="+name+type);
+ e.initCause(ee);
+ throw e;
+ }
+ if (evclass != vclass || (!isStatic && ecclass != cclass)) {
+ MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
+ strongType = strongType.insertParameterTypes(0, FieldAccessor.class);
+ mh = MethodHandles.convertArguments(mh, strongType);
+ }
+ return mh;
+ }
+
+ /// Support for array element access
+ static final HashMap<Class<?>, MethodHandle[]> ARRAY_CACHE =
+ new HashMap<Class<?>, MethodHandle[]>();
+ // FIXME: Cache on the classes themselves, not here.
+ static boolean doCache(Class<?> elemClass) {
+ if (elemClass.isPrimitive()) return true;
+ ClassLoader cl = elemClass.getClassLoader();
+ return cl == null || cl == ClassLoader.getSystemClassLoader();
+ }
+ static int getElementI(int[] a, int i) { return a[i]; }
+ static void setElementI(int[] a, int i, int x) { a[i] = x; }
+ static long getElementJ(long[] a, int i) { return a[i]; }
+ static void setElementJ(long[] a, int i, long x) { a[i] = x; }
+ static float getElementF(float[] a, int i) { return a[i]; }
+ static void setElementF(float[] a, int i, float x) { a[i] = x; }
+ static double getElementD(double[] a, int i) { return a[i]; }
+ static void setElementD(double[] a, int i, double x) { a[i] = x; }
+ static boolean getElementZ(boolean[] a, int i) { return a[i]; }
+ static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; }
+ static byte getElementB(byte[] a, int i) { return a[i]; }
+ static void setElementB(byte[] a, int i, byte x) { a[i] = x; }
+ static short getElementS(short[] a, int i) { return a[i]; }
+ static void setElementS(short[] a, int i, short x) { a[i] = x; }
+ static char getElementC(char[] a, int i) { return a[i]; }
+ static void setElementC(char[] a, int i, char x) { a[i] = x; }
+ static Object getElementL(Object[] a, int i) { return a[i]; }
+ static void setElementL(Object[] a, int i, Object x) { a[i] = x; }
+ static <V> V getElementL(Class<V[]> aclass, V[] a, int i) { return aclass.cast(a)[i]; }
+ static <V> void setElementL(Class<V[]> aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; }
+
+ static String aname(Class<?> aclass, boolean isSetter) {
+ Class<?> vclass = aclass.getComponentType();
+ if (vclass == null) throw new IllegalArgumentException();
+ return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass);
+ }
+ static MethodType atype(Class<?> aclass, boolean isSetter) {
+ Class<?> vclass = aclass.getComponentType();
+ if (!isSetter)
+ return MethodType.methodType(vclass, aclass, int.class);
+ else
+ return MethodType.methodType(void.class, aclass, int.class, vclass);
+ }
+ static MethodHandle ahandle(Class<?> aclass, boolean isSetter) {
+ Class<?> vclass = aclass.getComponentType();
+ String name = FieldAccessor.aname(aclass, isSetter);
+ Class<?> caclass = null;
+ if (!vclass.isPrimitive() && vclass != Object.class) {
+ caclass = aclass;
+ aclass = Object[].class;
+ vclass = Object.class;
+ }
+ MethodType type = FieldAccessor.atype(aclass, isSetter);
+ if (caclass != null)
+ type = type.insertParameterTypes(0, Class.class);
+ MethodHandle mh;
+ try {
+ mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
+ } catch (NoAccessException ee) {
+ Error e = new InternalError("name,type="+name+type);
+ e.initCause(ee);
+ throw e;
+ }
+ if (caclass != null) {
+ MethodType strongType = FieldAccessor.atype(caclass, isSetter);
+ mh = MethodHandles.insertArguments(mh, 0, caclass);
+ mh = MethodHandles.convertArguments(mh, strongType);
+ }
+ return mh;
+ }
}
/** Bind a predetermined first argument to the given direct method handle.
@@ -203,8 +437,11 @@
if (info instanceof DirectMethodHandle) {
DirectMethodHandle dmh = (DirectMethodHandle) info;
if (receiver == null ||
- dmh.type().parameterType(0).isAssignableFrom(receiver.getClass()))
- target = dmh;
+ dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) {
+ MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0);
+ MethodType newType = target.type().dropParameterTypes(0, 1);
+ return convertArguments(token, bmh, newType, bmh.type(), null);
+ }
}
}
if (target instanceof DirectMethodHandle)
@@ -223,7 +460,7 @@
MethodHandle bindArgument(Access token,
MethodHandle target, int argnum, Object receiver) {
Access.check(token);
- throw new UnsupportedOperationException("NYI");
+ return new BoundMethodHandle(target, receiver, argnum);
}
public static MethodHandle convertArguments(Access token,
@@ -232,6 +469,189 @@
MethodType oldType,
int[] permutationOrNull) {
Access.check(token);
+ if (permutationOrNull != null) {
+ int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
+ if (permutationOrNull.length != outargs)
+ throw newIllegalArgumentException("wrong number of arguments in permutation");
+ // Make the individual outgoing argument types match up first.
+ Class<?>[] callTypeArgs = new Class<?>[outargs];
+ for (int i = 0; i < outargs; i++)
+ callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
+ MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
+ target = convertArguments(token, target, callType, oldType, null);
+ assert(target != null);
+ oldType = target.type();
+ List<Integer> goal = new ArrayList<Integer>(); // i*TOKEN
+ List<Integer> state = new ArrayList<Integer>(); // i*TOKEN
+ List<Integer> drops = new ArrayList<Integer>(); // not tokens
+ List<Integer> dups = new ArrayList<Integer>(); // not tokens
+ final int TOKEN = 10; // to mark items which are symbolic only
+ // state represents the argument values coming into target
+ for (int i = 0; i < outargs; i++) {
+ state.add(permutationOrNull[i] * TOKEN);
+ }
+ // goal represents the desired state
+ for (int i = 0; i < inargs; i++) {
+ if (state.contains(i * TOKEN)) {
+ goal.add(i * TOKEN);
+ } else {
+ // adapter must initially drop all unused arguments
+ drops.add(i);
+ }
+ }
+ // detect duplications
+ while (state.size() > goal.size()) {
+ for (int i2 = 0; i2 < state.size(); i2++) {
+ int arg1 = state.get(i2);
+ int i1 = state.indexOf(arg1);
+ if (i1 != i2) {
+ // found duplicate occurrence at i2
+ int arg2 = (inargs++) * TOKEN;
+ state.set(i2, arg2);
+ dups.add(goal.indexOf(arg1));
+ goal.add(arg2);
+ }
+ }
+ }
+ assert(state.size() == goal.size());
+ int size = goal.size();
+ while (!state.equals(goal)) {
+ // Look for a maximal sequence of adjacent misplaced arguments,
+ // and try to rotate them into place.
+ int bestRotArg = -10 * TOKEN, bestRotLen = 0;
+ int thisRotArg = -10 * TOKEN, thisRotLen = 0;
+ for (int i = 0; i < size; i++) {
+ int arg = state.get(i);
+ // Does this argument match the current run?
+ if (arg == thisRotArg + TOKEN) {
+ thisRotArg = arg;
+ thisRotLen += 1;
+ if (bestRotLen < thisRotLen) {
+ bestRotLen = thisRotLen;
+ bestRotArg = thisRotArg;
+ }
+ } else {
+ // The old sequence (if any) stops here.
+ thisRotLen = 0;
+ thisRotArg = -10 * TOKEN;
+ // But maybe a new one starts here also.
+ int wantArg = goal.get(i);
+ final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION;
+ if (arg != wantArg &&
+ arg >= wantArg - TOKEN * MAX_ARG_ROTATION &&
+ arg <= wantArg + TOKEN * MAX_ARG_ROTATION) {
+ thisRotArg = arg;
+ thisRotLen = 1;
+ }
+ }
+ }
+ if (bestRotLen >= 2) {
+ // Do a rotation if it can improve argument positioning
+ // by at least 2 arguments. This is not always optimal,
+ // but it seems to catch common cases.
+ int dstEnd = state.indexOf(bestRotArg);
+ int srcEnd = goal.indexOf(bestRotArg);
+ int rotBy = dstEnd - srcEnd;
+ int dstBeg = dstEnd - (bestRotLen - 1);
+ int srcBeg = srcEnd - (bestRotLen - 1);
+ assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs
+ // Make a span which covers both source and destination.
+ int rotBeg = Math.min(dstBeg, srcBeg);
+ int rotEnd = Math.max(dstEnd, srcEnd);
+ int score = 0;
+ for (int i = rotBeg; i <= rotEnd; i++) {
+ if ((int)state.get(i) != (int)goal.get(i))
+ score += 1;
+ }
+ List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1);
+ Collections.rotate(rotSpan, -rotBy); // reverse direction
+ for (int i = rotBeg; i <= rotEnd; i++) {
+ if ((int)state.get(i) != (int)goal.get(i))
+ score -= 1;
+ }
+ if (score >= 2) {
+ // Improved at least two argument positions. Do it.
+ List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
+ Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
+ MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
+ MethodHandle nextTarget
+ = AdapterMethodHandle.makeRotateArguments(token, rotType, target,
+ rotBeg, rotSpan.size(), rotBy);
+ if (nextTarget != null) {
+ //System.out.println("Rot: "+rotSpan+" by "+rotBy);
+ target = nextTarget;
+ oldType = rotType;
+ continue;
+ }
+ }
+ // Else de-rotate, and drop through to the swap-fest.
+ Collections.rotate(rotSpan, rotBy);
+ }
+
+ // Now swap like the wind!
+ List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
+ for (int i = 0; i < size; i++) {
+ // What argument do I want here?
+ int arg = goal.get(i);
+ if (arg != state.get(i)) {
+ // Where is it now?
+ int j = state.indexOf(arg);
+ Collections.swap(ptypes, i, j);
+ MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes);
+ target = AdapterMethodHandle.makeSwapArguments(token, swapType, target, i, j);
+ if (target == null) throw newIllegalArgumentException("cannot swap");
+ assert(target.type() == swapType);
+ oldType = swapType;
+ Collections.swap(state, i, j);
+ }
+ }
+ // One pass of swapping must finish the job.
+ assert(state.equals(goal));
+ }
+ while (!dups.isEmpty()) {
+ // Grab a contiguous trailing sequence of dups.
+ int grab = dups.size() - 1;
+ int dupArgPos = dups.get(grab), dupArgCount = 1;
+ while (grab - 1 >= 0) {
+ int dup0 = dups.get(grab - 1);
+ if (dup0 != dupArgPos - 1) break;
+ dupArgPos -= 1;
+ dupArgCount += 1;
+ grab -= 1;
+ }
+ //if (dupArgCount > 1) System.out.println("Dup: "+dups.subList(grab, dups.size()));
+ dups.subList(grab, dups.size()).clear();
+ // In the new target type drop that many args from the tail:
+ List<Class<?>> ptypes = oldType.parameterList();
+ ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
+ MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
+ target = AdapterMethodHandle.makeDupArguments(token, dupType, target, dupArgPos, dupArgCount);
+ if (target == null)
+ throw newIllegalArgumentException("cannot dup");
+ oldType = target.type();
+ }
+ while (!drops.isEmpty()) {
+ // Grab a contiguous initial sequence of drops.
+ int dropArgPos = drops.get(0), dropArgCount = 1;
+ while (dropArgCount < drops.size()) {
+ int drop1 = drops.get(dropArgCount);
+ if (drop1 != dropArgPos + dropArgCount) break;
+ dropArgCount += 1;
+ }
+ //if (dropArgCount > 1) System.out.println("Drop: "+drops.subList(0, dropArgCount));
+ drops.subList(0, dropArgCount).clear();
+ List<Class<?>> dropTypes = newType.parameterList()
+ .subList(dropArgPos, dropArgPos + dropArgCount);
+ MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
+ target = AdapterMethodHandle.makeDropArguments(token, dropType, target, dropArgPos, dropArgCount);
+ if (target == null) throw newIllegalArgumentException("cannot drop");
+ oldType = target.type();
+ }
+ }
+ if (newType == oldType)
+ return target;
+ if (oldType.parameterCount() != newType.parameterCount())
+ throw newIllegalArgumentException("mismatched parameter count");
MethodHandle res = AdapterMethodHandle.makePairwiseConvert(token, newType, target);
if (res != null)
return res;
@@ -241,7 +661,7 @@
// Use a heavier method: Convert all the arguments to Object,
// then back to the desired types. We might have to use Java-based
// method handles to do this.
- MethodType objType = MethodType.makeGeneric(argc);
+ MethodType objType = MethodType.genericMethodType(argc);
MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(token, objType, target);
if (objTarget == null)
objTarget = FromGeneric.make(target);
@@ -272,83 +692,386 @@
Class<?>[] ptypes = oldType.parameterArray();
for (int i = 0; i < spreadCount; i++)
ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i);
- MethodType midType = MethodType.make(newType.returnType(), ptypes);
+ MethodType midType = MethodType.methodType(newType.returnType(), ptypes);
// after spreading, some arguments may need further conversion
- target = convertArguments(token, target, midType, oldType, null);
- if (target == null)
+ MethodHandle target2 = convertArguments(token, target, midType, oldType, null);
+ if (target2 == null)
throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType);
- res = AdapterMethodHandle.makeSpreadArguments(token, newType, target, spreadArgType, spreadArg, spreadCount);
+ res = AdapterMethodHandle.makeSpreadArguments(token, newType, target2, spreadArgType, spreadArg, spreadCount);
+ if (res != null)
+ return res;
+ res = SpreadGeneric.make(target2, spreadCount);
+ if (res != null)
+ res = convertArguments(token, res, newType, res.type(), null);
return res;
}
public static MethodHandle collectArguments(Access token,
MethodHandle target,
MethodType newType,
- int collectArg) {
- if (collectArg > 0)
- throw new UnsupportedOperationException("NYI");
- throw new UnsupportedOperationException("NYI");
+ int collectArg,
+ MethodHandle collector) {
+ MethodType oldType = target.type(); // (a...,c)=>r
+ if (collector == null) {
+ int numCollect = newType.parameterCount() - oldType.parameterCount() + 1;
+ collector = ValueConversions.varargsArray(numCollect);
+ }
+ // newType // (a..., b...)=>r
+ MethodType colType = collector.type(); // (b...)=>c
+ // oldType // (a..., b...)=>r
+ assert(newType.parameterCount() == collectArg + colType.parameterCount());
+ assert(oldType.parameterCount() == collectArg + 1);
+ MethodHandle gtarget = convertArguments(token, target, oldType.generic(), oldType, null);
+ MethodHandle gcollector = convertArguments(token, collector, colType.generic(), colType, null);
+ if (gtarget == null || gcollector == null) return null;
+ MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
+ MethodHandle result = convertArguments(token, gresult, newType, gresult.type(), null);
+ return result;
}
+
+ public static MethodHandle filterArgument(Access token,
+ MethodHandle target,
+ int pos,
+ MethodHandle filter) {
+ Access.check(token);
+ MethodType ttype = target.type(), gttype = ttype.generic();
+ if (ttype != gttype) {
+ target = convertArguments(token, target, gttype, ttype, null);
+ ttype = gttype;
+ }
+ MethodType ftype = filter.type(), gftype = ftype.generic();
+ if (ftype.parameterCount() != 1)
+ throw new InternalError();
+ if (ftype != gftype) {
+ filter = convertArguments(token, filter, gftype, ftype, null);
+ ftype = gftype;
+ }
+ if (ftype == ttype) {
+ // simple unary case
+ return FilterOneArgument.make(filter, target);
+ }
+ return FilterGeneric.makeArgumentFilter(pos, filter, target);
+ }
+
+ public static MethodHandle foldArguments(Access token,
+ MethodHandle target,
+ MethodType newType,
+ MethodHandle combiner) {
+ Access.check(token);
+ MethodType oldType = target.type();
+ MethodType ctype = combiner.type();
+ MethodHandle gtarget = convertArguments(token, target, oldType.generic(), oldType, null);
+ MethodHandle gcombiner = convertArguments(token, combiner, ctype.generic(), ctype, null);
+ if (gtarget == null || gcombiner == null) return null;
+ MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget);
+ MethodHandle result = convertArguments(token, gresult, newType, gresult.type(), null);
+ return result;
+ }
+
public static
MethodHandle dropArguments(Access token, MethodHandle target,
MethodType newType, int argnum) {
Access.check(token);
+ int drops = newType.parameterCount() - target.type().parameterCount();
+ MethodHandle res = AdapterMethodHandle.makeDropArguments(token, newType, target, argnum, drops);
+ if (res != null)
+ return res;
throw new UnsupportedOperationException("NYI");
}
+ private static class GuardWithTest extends JavaMethodHandle {
+ private final MethodHandle test, target, fallback;
+ public GuardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback) {
+ this(INVOKES[target.type().parameterCount()], test, target, fallback);
+ }
+ public GuardWithTest(MethodHandle invoker,
+ MethodHandle test, MethodHandle target, MethodHandle fallback) {
+ super(invoker);
+ this.test = test;
+ this.target = target;
+ this.fallback = fallback;
+ }
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+ private Object invoke_V(Object... av) throws Throwable {
+ if (test.<boolean>invoke(av))
+ return target.<Object>invoke(av);
+ return fallback.<Object>invoke(av);
+ }
+ private Object invoke_L0() throws Throwable {
+ if (test.<boolean>invoke())
+ return target.<Object>invoke();
+ return fallback.<Object>invoke();
+ }
+ private Object invoke_L1(Object a0) throws Throwable {
+ if (test.<boolean>invoke(a0))
+ return target.<Object>invoke(a0);
+ return fallback.<Object>invoke(a0);
+ }
+ private Object invoke_L2(Object a0, Object a1) throws Throwable {
+ if (test.<boolean>invoke(a0, a1))
+ return target.<Object>invoke(a0, a1);
+ return fallback.<Object>invoke(a0, a1);
+ }
+ private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
+ if (test.<boolean>invoke(a0, a1, a2))
+ return target.<Object>invoke(a0, a1, a2);
+ return fallback.<Object>invoke(a0, a1, a2);
+ }
+ private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ if (test.<boolean>invoke(a0, a1, a2, a3))
+ return target.<Object>invoke(a0, a1, a2, a3);
+ return fallback.<Object>invoke(a0, a1, a2, a3);
+ }
+ private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
+ if (test.<boolean>invoke(a0, a1, a2, a3, a4))
+ return target.<Object>invoke(a0, a1, a2, a3, a4);
+ return fallback.<Object>invoke(a0, a1, a2, a3, a4);
+ }
+ private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
+ if (test.<boolean>invoke(a0, a1, a2, a3, a4, a5))
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5);
+ return fallback.<Object>invoke(a0, a1, a2, a3, a4, a5);
+ }
+ private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
+ if (test.<boolean>invoke(a0, a1, a2, a3, a4, a5, a6))
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6);
+ return fallback.<Object>invoke(a0, a1, a2, a3, a4, a5, a6);
+ }
+ private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ if (test.<boolean>invoke(a0, a1, a2, a3, a4, a5, a6, a7))
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7);
+ return fallback.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+ static MethodHandle[] makeInvokes() {
+ ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = invokes.size();
+ String name = "invoke_L"+nargs;
+ MethodHandle invoke = null;
+ try {
+ invoke = lookup.findVirtual(GuardWithTest.class, name, MethodType.genericMethodType(nargs));
+ } catch (NoAccessException ex) {
+ }
+ if (invoke == null) break;
+ invokes.add(invoke);
+ }
+ assert(invokes.size() == 9); // current number of methods
+ return invokes.toArray(new MethodHandle[0]);
+ };
+ static final MethodHandle[] INVOKES = makeInvokes();
+ // For testing use this:
+ //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
+ static final MethodHandle VARARGS_INVOKE;
+ static {
+ try {
+ VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
+ } catch (NoAccessException ex) {
+ throw new InternalError("");
+ }
+ }
+ }
+
public static
MethodHandle makeGuardWithTest(Access token,
- final MethodHandle test,
- final MethodHandle target,
- final MethodHandle fallback) {
+ MethodHandle test,
+ MethodHandle target,
+ MethodHandle fallback) {
Access.check(token);
- // %%% This is just a sketch. It needs to be de-boxed.
- // Adjust the handles to accept varargs lists.
MethodType type = target.type();
- Class<?> rtype = type.returnType();
- if (type.parameterCount() != 1 || type.parameterType(0).isPrimitive()) {
- MethodType vatestType = MethodType.make(boolean.class, Object[].class);
- MethodType vatargetType = MethodType.make(rtype, Object[].class);
- MethodHandle vaguard = makeGuardWithTest(token,
- MethodHandles.spreadArguments(test, vatestType),
- MethodHandles.spreadArguments(target, vatargetType),
- MethodHandles.spreadArguments(fallback, vatargetType));
- return MethodHandles.collectArguments(vaguard, type);
+ int nargs = type.parameterCount();
+ if (nargs < GuardWithTest.INVOKES.length) {
+ MethodType gtype = type.generic();
+ MethodHandle gtest = convertArguments(token, test, gtype.changeReturnType(boolean.class), test.type(), null);
+ MethodHandle gtarget = convertArguments(token, target, gtype, type, null);
+ MethodHandle gfallback = convertArguments(token, fallback, gtype, type, null);
+ if (gtest == null || gtarget == null || gfallback == null) return null;
+ MethodHandle gguard = new GuardWithTest(gtest, gtarget, gfallback);
+ return convertArguments(token, gguard, type, gtype, null);
+ } else {
+ MethodType gtype = MethodType.genericMethodType(0, true);
+ MethodHandle gtest = spreadArguments(token, test, gtype.changeReturnType(boolean.class), 0);
+ MethodHandle gtarget = spreadArguments(token, target, gtype, 0);
+ MethodHandle gfallback = spreadArguments(token, fallback, gtype, 0);
+ MethodHandle gguard = new GuardWithTest(GuardWithTest.VARARGS_INVOKE, gtest, gtarget, gfallback);
+ if (gtest == null || gtarget == null || gfallback == null) return null;
+ return collectArguments(token, gguard, type, 0, null);
+ }
+ }
+
+ private static class GuardWithCatch extends JavaMethodHandle {
+ private final MethodHandle target;
+ private final Class<? extends Throwable> exType;
+ private final MethodHandle catcher;
+ public GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
+ this(INVOKES[target.type().parameterCount()], target, exType, catcher);
+ }
+ public GuardWithCatch(MethodHandle invoker,
+ MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
+ super(invoker);
+ this.target = target;
+ this.exType = exType;
+ this.catcher = catcher;
}
- if (rtype.isPrimitive()) {
- MethodType boxtype = type.changeReturnType(Object.class);
- MethodHandle boxguard = makeGuardWithTest(token,
- test,
- MethodHandles.convertArguments(target, boxtype),
- MethodHandles.convertArguments(fallback, boxtype));
- return MethodHandles.convertArguments(boxguard, type);
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+ private Object invoke_V(Object... av) throws Throwable {
+ try {
+ return target.<Object>invoke(av);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, av);
+ }
+ }
+ private Object invoke_L0() throws Throwable {
+ try {
+ return target.<Object>invoke();
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t);
+ }
}
- // Got here? Reduced calling sequence to Object(Object).
- class Guarder {
- Object invoke(Object x) {
- // If javac supports MethodHandle.invoke directly:
- //z = vatest.invoke<boolean>(arguments);
- // If javac does not support direct MH.invoke calls:
- boolean z = (Boolean) MethodHandles.invoke_1(test, x);
- MethodHandle mh = (z ? target : fallback);
- return MethodHandles.invoke_1(mh, x);
+ private Object invoke_L1(Object a0) throws Throwable {
+ try {
+ return target.<Object>invoke(a0);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0);
}
- MethodHandle handle() {
- MethodType invokeType = MethodType.makeGeneric(0, true);
- MethodHandle vh = IMPL_LOOKUP.bind(this, "invoke", invokeType);
- return MethodHandles.collectArguments(vh, target.type());
+ }
+ private Object invoke_L2(Object a0, Object a1) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1);
+ }
+ }
+ private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1, a2);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1, a2);
}
}
- return new Guarder().handle();
+ private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1, a2, a3);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1, a2, a3);
+ }
+ }
+ private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1, a2, a3, a4);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1, a2, a3, a4);
+ }
+ }
+ private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1, a2, a3, a4, a5);
+ }
+ }
+ private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1, a2, a3, a4, a5, a6);
+ }
+ }
+ private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ try {
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.<Object>invoke(t, a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+ }
+ static MethodHandle[] makeInvokes() {
+ ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = invokes.size();
+ String name = "invoke_L"+nargs;
+ MethodHandle invoke = null;
+ try {
+ invoke = lookup.findVirtual(GuardWithCatch.class, name, MethodType.genericMethodType(nargs));
+ } catch (NoAccessException ex) {
+ }
+ if (invoke == null) break;
+ invokes.add(invoke);
+ }
+ assert(invokes.size() == 9); // current number of methods
+ return invokes.toArray(new MethodHandle[0]);
+ };
+ static final MethodHandle[] INVOKES = makeInvokes();
+ // For testing use this:
+ //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
+ static final MethodHandle VARARGS_INVOKE;
+ static {
+ try {
+ VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
+ } catch (NoAccessException ex) {
+ throw new InternalError("");
+ }
+ }
+ }
+
+
+ public static
+ MethodHandle makeGuardWithCatch(Access token,
+ MethodHandle target,
+ Class<? extends Throwable> exType,
+ MethodHandle catcher) {
+ Access.check(token);
+ MethodType type = target.type();
+ MethodType ctype = catcher.type();
+ int nargs = type.parameterCount();
+ if (nargs < GuardWithCatch.INVOKES.length) {
+ MethodType gtype = type.generic();
+ MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
+ MethodHandle gtarget = convertArguments(token, target, gtype, type, null);
+ MethodHandle gcatcher = convertArguments(token, catcher, gcatchType, ctype, null);
+ MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
+ if (gtarget == null || gcatcher == null || gguard == null) return null;
+ return convertArguments(token, gguard, type, gtype, null);
+ } else {
+ MethodType gtype = MethodType.genericMethodType(0, true);
+ MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
+ MethodHandle gtarget = spreadArguments(token, target, gtype, 0);
+ MethodHandle gcatcher = spreadArguments(token, catcher, gcatchType, 1);
+ MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher);
+ if (gtarget == null || gcatcher == null || gguard == null) return null;
+ return collectArguments(token, gguard, type, 0, null);
+ }
}
public static
- MethodHandle combineArguments(Access token, MethodHandle target, MethodHandle checker, int pos) {
+ MethodHandle throwException(Access token, MethodType type) {
Access.check(token);
- throw new UnsupportedOperationException("Not yet implemented");
+ return AdapterMethodHandle.makeRetypeRaw(token, type, THROW_EXCEPTION);
}
- protected static String basicToString(MethodHandle target) {
+ static final MethodHandle THROW_EXCEPTION
+ = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
+ MethodType.methodType(Empty.class, Throwable.class));
+ static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
+
+ public static String getNameString(Access token, MethodHandle target) {
+ Access.check(token);
MemberName name = null;
if (target != null)
name = MethodHandleNatives.getMethodName(target);
@@ -357,17 +1080,30 @@
return name.getName();
}
- protected static String addTypeString(MethodHandle target, String name) {
- if (target == null) return name;
- return name+target.type();
+ public static String addTypeString(MethodHandle target) {
+ if (target == null) return "null";
+ return target.toString() + target.type();
}
- static RuntimeException newIllegalArgumentException(String string) {
- return new IllegalArgumentException(string);
+
+ public static void checkSpreadArgument(Object av, int n) {
+ if (av == null ? n != 0 : ((Object[])av).length != n)
+ throw newIllegalArgumentException("Array is not of length "+n);
}
- @Override
- public String toString() {
- MethodHandle self = (MethodHandle) this;
- return addTypeString(self, basicToString(self));
+ public static void raiseException(int code, Object actual, Object required) {
+ String message;
+ // disregard the identity of the actual object, if it is not a class:
+ if (!(actual instanceof Class) && !(actual instanceof MethodType))
+ actual = actual.getClass();
+ if (actual != null)
+ message = "required "+required+" but encountered "+actual;
+ else
+ message = "required "+required;
+ switch (code) {
+ case 192: // checkcast
+ throw new ClassCastException(message);
+ default:
+ throw new InternalError("unexpected code "+code+": "+message);
+ }
}
}
--- a/jdk/src/share/classes/sun/dyn/MethodHandleNatives.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/MethodHandleNatives.java Wed Jul 05 17:04:56 2017 +0200
@@ -25,6 +25,7 @@
package sun.dyn;
+import java.dyn.CallSite;
import java.dyn.MethodHandle;
import java.dyn.MethodType;
import java.lang.reflect.AccessibleObject;
@@ -60,7 +61,7 @@
static native void init(MethodType self);
/** Tell the JVM that we need to change the target of an invokedynamic. */
- static native void linkCallSite(CallSiteImpl site, MethodHandle target);
+ static native void linkCallSite(CallSite site, MethodHandle target);
/** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references.
@@ -84,8 +85,7 @@
}
/** Fetch the target of this method handle.
- * If it directly targets a method, return a tuple of method info.
- * The info is of the form new Object[]{defclass, name, sig, refclass}.
+ * If it directly targets a method, return a MemberName for the method.
* If it is chained to another method handle, return that handle.
*/
static Object getTargetInfo(MethodHandle self) {
@@ -123,7 +123,7 @@
registerNatives();
JVM_SUPPORT_ = true;
JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
- JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_LIMIT);
+ JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
} catch (UnsatisfiedLinkError ee) {
// ignore; if we use init() methods later we'll see linkage errors
@@ -149,7 +149,7 @@
// MethodHandleImpl
static final int // for getConstant
GC_JVM_PUSH_LIMIT = 0,
- GC_JVM_STACK_MOVE_LIMIT = 1;
+ GC_JVM_STACK_MOVE_UNIT = 1;
static final int
ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
@@ -178,19 +178,20 @@
*/
static final int
OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
- OP_CHECK_CAST = 0x1, // ref-to-ref conversion; requires a Class argument
- OP_PRIM_TO_PRIM = 0x2, // converts from one primitive to another
- OP_REF_TO_PRIM = 0x3, // unboxes a wrapper to produce a primitive
- OP_PRIM_TO_REF = 0x4, // boxes a primitive into a wrapper (NYI)
- OP_SWAP_ARGS = 0x5, // swap arguments (vminfo is 2nd arg)
- OP_ROT_ARGS = 0x6, // rotate arguments (vminfo is displaced arg)
- OP_DUP_ARGS = 0x7, // duplicates one or more arguments (at TOS)
- OP_DROP_ARGS = 0x8, // remove one or more argument slots
- OP_COLLECT_ARGS = 0x9, // combine one or more arguments into a varargs (NYI)
- OP_SPREAD_ARGS = 0xA, // expand in place a varargs array (of known size)
- OP_FLYBY = 0xB, // operate first on reified argument list (NYI)
- OP_RICOCHET = 0xC, // run an adapter chain on the return value (NYI)
- CONV_OP_LIMIT = 0xD; // limit of CONV_OP enumeration
+ OP_RETYPE_RAW = 0x1, // no argument changes; straight retype
+ OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument
+ OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another
+ OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive
+ OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper (NYI)
+ OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg)
+ OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg)
+ OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS)
+ OP_DROP_ARGS = 0x9, // remove one or more argument slots
+ OP_COLLECT_ARGS = 0xA, // combine one or more arguments into a varargs (NYI)
+ OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size)
+ OP_FLYBY = 0xC, // operate first on reified argument list (NYI)
+ OP_RICOCHET = 0xD, // run an adapter chain on the return value (NYI)
+ CONV_OP_LIMIT = 0xE; // limit of CONV_OP enumeration
/** Shift and mask values for decoding the AMH.conversion field.
* These numbers are shared with the JVM for creating AMHs.
*/
@@ -209,6 +210,7 @@
// TODO: The following expression should be replaced by
// a JVM query.
((1<<OP_RETYPE_ONLY)
+ |(1<<OP_RETYPE_RAW)
|(1<<OP_CHECK_CAST)
|(1<<OP_PRIM_TO_PRIM)
|(1<<OP_REF_TO_PRIM)
@@ -216,6 +218,7 @@
|(1<<OP_ROT_ARGS)
|(1<<OP_DUP_ARGS)
|(1<<OP_DROP_ARGS)
+ //|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code.
);
/**
--- a/jdk/src/share/classes/sun/dyn/MethodTypeImpl.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/MethodTypeImpl.java Wed Jul 05 17:04:56 2017 +0200
@@ -27,6 +27,7 @@
import java.dyn.*;
import sun.dyn.util.Wrapper;
+import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* Shared information for a group of method types, which differ
@@ -56,8 +57,8 @@
// Cached adapter information:
/*lazy*/ ToGeneric toGeneric; // convert cs. with prims to w/o
/*lazy*/ FromGeneric fromGeneric; // convert cs. w/o prims to with
+ /*lazy*/ SpreadGeneric[] spreadGeneric; // expand one argument to many
/*lazy*/ FilterGeneric filterGeneric; // convert argument(s) on the fly
- ///*lazy*/ Invokers invokers; // cache of handy higher-order adapters
public MethodType erasedType() {
return erasedType;
@@ -68,7 +69,7 @@
}
/** Access methods for the internals of MethodType, supplied to
- * MethodTypeForm as a trusted agent.
+ * MethodTypeImpl as a trusted agent.
*/
static public interface MethodTypeFriend {
Class<?>[] ptypes(MethodType mt);
@@ -150,7 +151,7 @@
this.argToSlotTable = argToSlotTab;
this.slotToArgTable = slotToArgTab;
- if (pslotCount >= 256) throw new IllegalArgumentException("too many arguments");
+ if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
// send a few bits down to the JVM:
this.vmslots = parameterSlotCount();
@@ -378,10 +379,10 @@
static MethodTypeImpl findForm(MethodType mt) {
MethodType erased = canonicalize(mt, ERASE, ERASE);
if (erased == null) {
- // It is already erased. Make a new MethodTypeForm.
+ // It is already erased. Make a new MethodTypeImpl.
return METHOD_TYPE_FRIEND.newMethodTypeForm(mt);
} else {
- // Share the MethodTypeForm with the erased version.
+ // Share the MethodTypeImpl with the erased version.
return METHOD_TYPE_FRIEND.form(erased);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/dyn/SpreadGeneric.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,682 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.dyn;
+
+import java.dyn.JavaMethodHandle;
+import java.dyn.MethodHandle;
+import java.dyn.MethodHandles;
+import java.dyn.MethodType;
+import java.dyn.NoAccessException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import sun.dyn.util.ValueConversions;
+import static sun.dyn.MemberName.newIllegalArgumentException;
+
+/**
+ * Generic spread adapter.
+ * Expands a final argument into multiple (zero or more) arguments, keeping the others the same.
+ * @author jrose
+ */
+class SpreadGeneric {
+ // type for the outgoing call
+ private final MethodType targetType;
+ // number of arguments to spread
+ private final int spreadCount;
+ // prototype adapter (clone and customize for each new target!)
+ private final Adapter adapter;
+ // entry point for adapter (Adapter mh, a...) => ...
+ private final MethodHandle entryPoint;
+
+ /** Compute and cache information common to all spreading adapters
+ * that accept calls of the given (generic) type.
+ */
+ private SpreadGeneric(MethodType targetType, int spreadCount) {
+ assert(targetType == targetType.generic());
+ this.targetType = targetType;
+ this.spreadCount = spreadCount;
+ // the target invoker will generally need casts on reference arguments
+ MethodHandle[] ep = { null };
+ Adapter ad = findAdapter(this, ep);
+ if (ad != null) {
+ this.adapter = ad;
+ this.entryPoint = ep[0];
+ return;
+ }
+ this.adapter = buildAdapterFromBytecodes(targetType, spreadCount, ep);
+ this.entryPoint = ep[0];
+ }
+
+ /** From targetType remove the last spreadCount arguments, and instead
+ * append a simple Object argument.
+ */
+ static MethodType preSpreadType(MethodType targetType, int spreadCount) {
+ @SuppressWarnings("unchecked")
+ ArrayList<Class<?>> params = new ArrayList(targetType.parameterList());
+ int outargs = params.size();
+ params.subList(outargs - spreadCount, outargs).clear();
+ params.add(Object.class);
+ return MethodType.methodType(targetType.returnType(), params);
+ }
+
+ MethodHandle makeInstance(MethodHandle target) {
+ MethodType type = target.type();
+ if (type != targetType) {
+ throw new UnsupportedOperationException("NYI type="+type);
+ }
+ return adapter.makeInstance(this, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes typedTarget
+ * on the incoming arguments, after unboxing as necessary.
+ * The return value is boxed if necessary.
+ * @param genericType the required type of the result
+ * @param typedTarget the target
+ * @return an adapter method handle
+ */
+ public static MethodHandle make(MethodHandle target, int spreadCount) {
+ MethodType type = target.type();
+ MethodType gtype = type.generic();
+ if (type == gtype) {
+ return SpreadGeneric.of(type, spreadCount).makeInstance(target);
+ } else {
+ MethodHandle gtarget = FromGeneric.make(target);
+ assert(gtarget.type() == gtype);
+ MethodHandle gspread = SpreadGeneric.of(gtype, spreadCount).makeInstance(gtarget);
+ return ToGeneric.make(preSpreadType(type, spreadCount), gspread);
+ }
+ }
+
+ /** Return the adapter information for this type's erasure. */
+ static SpreadGeneric of(MethodType targetType, int spreadCount) {
+ if (targetType != targetType.generic())
+ throw new UnsupportedOperationException("NYI type="+targetType);
+ MethodTypeImpl form = MethodTypeImpl.of(targetType);
+ int outcount = form.parameterCount();
+ assert(spreadCount <= outcount);
+ SpreadGeneric[] spreadGens = form.spreadGeneric;
+ if (spreadGens == null)
+ form.spreadGeneric = spreadGens = new SpreadGeneric[outcount+1];
+ SpreadGeneric spreadGen = spreadGens[spreadCount];
+ if (spreadGen == null)
+ spreadGens[spreadCount] = spreadGen = new SpreadGeneric(form.erasedType(), spreadCount);
+ return spreadGen;
+ }
+
+ public String toString() {
+ return getClass().getSimpleName()+targetType+"["+spreadCount+"]";
+ }
+
+ // This mini-api is called from an Adapter to manage the spread.
+ /** A check/coercion that happens once before any selections. */
+ protected Object check(Object av, int n) {
+ MethodHandleImpl.checkSpreadArgument(av, n);
+ return av;
+ }
+
+ /** The selection operator for spreading; note that it takes Object not Object[]. */
+ protected Object select(Object av, int n) {
+ return ((Object[])av)[n];
+ }
+ /*
+ protected int select_I(Object av, int n) {
+ // maybe return ((int[])select)[n]
+ throw new UnsupportedOperationException("subclass resp.");
+ }
+ protected int select_J(Object av, int n) {
+ // maybe return ((long[])select)[n]
+ throw new UnsupportedOperationException("subclass resp.");
+ }
+ // */
+
+ /* Create an adapter that handles spreading calls for the given type. */
+ static Adapter findAdapter(SpreadGeneric outer, MethodHandle[] ep) {
+ MethodType targetType = outer.targetType;
+ int spreadCount = outer.spreadCount;
+ int outargs = targetType.parameterCount();
+ int inargs = outargs - spreadCount;
+ if (inargs < 0) return null;
+ MethodType entryType = MethodType.genericMethodType(inargs + 1); // 1 for av
+ String cname1 = "S" + outargs;
+ String[] cnames = { cname1 };
+ String iname = "invoke_S"+spreadCount;
+ // e.g., D5I2, D5, L5I2, L5; invoke_D5
+ for (String cname : cnames) {
+ Class<? extends Adapter> acls = Adapter.findSubClass(cname);
+ if (acls == null) continue;
+ // see if it has the required invoke method
+ MethodHandle entryPoint = null;
+ try {
+ entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
+ } catch (NoAccessException ex) {
+ }
+ if (entryPoint == null) continue;
+ Constructor<? extends Adapter> ctor = null;
+ try {
+ ctor = acls.getDeclaredConstructor(SpreadGeneric.class);
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) {
+ }
+ if (ctor == null) continue;
+ try {
+ // Produce an instance configured as a prototype.
+ Adapter ad = ctor.newInstance(outer);
+ ep[0] = entryPoint;
+ return ad;
+ } catch (IllegalArgumentException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ }
+ }
+ return null;
+ }
+
+ static Adapter buildAdapterFromBytecodes(MethodType targetType,
+ int spreadCount, MethodHandle[] ep) {
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ /**
+ * This adapter takes some untyped arguments, and returns an untyped result.
+ * Internally, it applies the invoker to the target, which causes the
+ * objects to be unboxed; the result is a raw type in L/I/J/F/D.
+ * This result is passed to convert, which is responsible for
+ * converting the raw result into a boxed object.
+ * The invoker is kept separate from the target because it can be
+ * generated once per type erasure family, and reused across adapters.
+ */
+ static abstract class Adapter extends JavaMethodHandle {
+ /*
+ * class X<<R,int M,int N>> extends Adapter {
+ * (Object**N)=>R target;
+ * static int S = N-M;
+ * Object invoke(Object**M a, Object v) = target(a..., v[0]...v[S-1]);
+ * }
+ */
+ protected final SpreadGeneric outer;
+ protected final MethodHandle target; // (any**N) => R
+
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+
+ static final MethodHandle NO_ENTRY = ValueConversions.identity();
+
+ protected boolean isPrototype() { return target == null; }
+ protected Adapter(SpreadGeneric outer) {
+ super(NO_ENTRY);
+ this.outer = outer;
+ this.target = null;
+ assert(isPrototype());
+ }
+
+ protected Adapter(SpreadGeneric outer, MethodHandle target) {
+ super(outer.entryPoint);
+ this.outer = outer;
+ this.target = target;
+ }
+
+ /** Make a copy of self, with new fields. */
+ protected abstract Adapter makeInstance(SpreadGeneric outer, MethodHandle target);
+ // { return new ThisType(outer, target); }
+
+ protected Object check(Object av, int n) {
+ return outer.check(av, n);
+ }
+ protected Object select(Object av, int n) {
+ return outer.select(av, n);
+ }
+
+ static private final String CLASS_PREFIX; // "sun.dyn.SpreadGeneric$"
+ static {
+ String aname = Adapter.class.getName();
+ String sname = Adapter.class.getSimpleName();
+ if (!aname.endsWith(sname)) throw new InternalError();
+ CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
+ }
+ /** Find a sibing class of Adapter. */
+ static Class<? extends Adapter> findSubClass(String name) {
+ String cname = Adapter.CLASS_PREFIX + name;
+ try {
+ return Class.forName(cname).asSubclass(Adapter.class);
+ } catch (ClassNotFoundException ex) {
+ return null;
+ } catch (ClassCastException ex) {
+ return null;
+ }
+ }
+ }
+
+ /* generated classes follow this pattern:
+ static class xS2 extends Adapter {
+ protected xS2(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected xS2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected xS2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new xS2(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av,0);
+ return target.<Object>invoke(a0, a1)); }
+ protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av,1);
+ return target.<Object>invoke(a0,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av,1);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1)); }
+ }
+ // */
+
+/*
+: SHELL; n=SpreadGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
+//{{{
+import java.util.*;
+class genclasses {
+ static String[][] TEMPLATES = { {
+ "@for@ N=0..10",
+ " //@each-cat@",
+ " static class @cat@ extends Adapter {",
+ " protected @cat@(SpreadGeneric outer) { super(outer); } // to build prototype",
+ " protected @cat@(SpreadGeneric outer, MethodHandle t) { super(outer, t); }",
+ " protected @cat@ makeInstance(SpreadGeneric outer, MethodHandle t) { return new @cat@(outer, t); }",
+ " protected Object invoke_S0(@Tvav,@Object av) throws Throwable { av = super.check(av, 0);",
+ " return target.<Object>invoke(@av@); }",
+ " //@each-S@",
+ " protected Object invoke_S@S@(@Tvav,@Object av) throws Throwable { av = super.check(av, @S@);",
+ " return target.<Object>invoke(@av,@@sv@); }",
+ " //@end-S@",
+ " }",
+ } };
+ static final String NEWLINE_INDENT = "\n ";
+ enum VAR {
+ cat, N, S, av, av_, Tvav_, sv;
+ public final String pattern = "@"+toString().replace('_','.')+"@";
+ public String binding = toString();
+ static void makeBindings(boolean topLevel, int outargs, int spread) {
+ int inargs = outargs - spread;
+ VAR.cat.binding = "S"+outargs;
+ VAR.N.binding = String.valueOf(outargs); // outgoing arg count
+ VAR.S.binding = String.valueOf(spread); // spread count
+ String[] av = new String[inargs];
+ String[] Tvav = new String[inargs];
+ for (int i = 0; i < inargs; i++) {
+ av[i] = arg(i);
+ Tvav[i] = param("Object", av[i]);
+ }
+ VAR.av.binding = comma(av);
+ VAR.av_.binding = comma(av, ", ");
+ VAR.Tvav_.binding = comma(Tvav, ", ");
+ String[] sv = new String[spread];
+ for (int i = 0; i < spread; i++) {
+ String spc = "";
+ if (i % 4 == 0) spc = NEWLINE_INDENT;
+ sv[i] = spc+"super.select(av,"+i+")";
+ }
+ VAR.sv.binding = comma(sv);
+ }
+ static String arg(int i) { return "a"+i; }
+ static String param(String t, String a) { return t+" "+a; }
+ static String comma(String[] v) { return comma(v, ""); }
+ static String comma(String[] v, String sep) {
+ if (v.length == 0) return "";
+ String res = v[0];
+ for (int i = 1; i < v.length; i++) res += ", "+v[i];
+ return res + sep;
+ }
+ static String transform(String string) {
+ for (VAR var : values())
+ string = string.replaceAll(var.pattern, var.binding);
+ return string;
+ }
+ }
+ static String[] stringsIn(String[] strings, int beg, int end) {
+ return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
+ }
+ static String[] stringsBefore(String[] strings, int pos) {
+ return stringsIn(strings, 0, pos);
+ }
+ static String[] stringsAfter(String[] strings, int pos) {
+ return stringsIn(strings, pos, strings.length);
+ }
+ static int indexAfter(String[] strings, int pos, String tag) {
+ return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
+ }
+ static int indexBefore(String[] strings, int pos, String tag) {
+ for (int i = pos, end = strings.length; ; i++) {
+ if (i == end || strings[i].endsWith(tag)) return i;
+ }
+ }
+ static int MIN_ARITY, MAX_ARITY;
+ public static void main(String... av) {
+ for (String[] template : TEMPLATES) {
+ int forLinesLimit = indexBefore(template, 0, "@each-cat@");
+ String[] forLines = stringsBefore(template, forLinesLimit);
+ template = stringsAfter(template, forLinesLimit);
+ for (String forLine : forLines)
+ expandTemplate(forLine, template);
+ }
+ }
+ static void expandTemplate(String forLine, String[] template) {
+ String[] params = forLine.split("[^0-9]+");
+ if (params[0].length() == 0) params = stringsAfter(params, 1);
+ System.out.println("//params="+Arrays.asList(params));
+ int pcur = 0;
+ MIN_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_ARITY = Integer.valueOf(params[pcur++]);
+ if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
+ for (int outargs = MIN_ARITY; outargs <= MAX_ARITY; outargs++) {
+ expandTemplate(template, true, outargs, 0);
+ }
+ }
+ static void expandTemplate(String[] template, boolean topLevel, int outargs, int spread) {
+ VAR.makeBindings(topLevel, outargs, spread);
+ for (int i = 0; i < template.length; i++) {
+ String line = template[i];
+ if (line.endsWith("@each-cat@")) {
+ // ignore
+ } else if (line.endsWith("@each-S@")) {
+ int blockEnd = indexAfter(template, i, "@end-S@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ for (int spread1 = spread+1; spread1 <= outargs; spread1++)
+ expandTemplate(block, false, outargs, spread1);
+ VAR.makeBindings(topLevel, outargs, spread);
+ i = blockEnd-1; continue;
+ } else {
+ System.out.println(VAR.transform(line));
+ }
+ }
+ }
+}
+//}}} */
+//params=[0, 10]
+ static class S0 extends Adapter {
+ protected S0(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S0(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S0 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S0(outer, t); }
+ protected Object invoke_S0(Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(); }
+ }
+ static class S1 extends Adapter {
+ protected S1(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S1(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S1 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S1(outer, t); }
+ protected Object invoke_S0(Object a0, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0); }
+ protected Object invoke_S1(Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(
+ super.select(av,0)); }
+ }
+ static class S2 extends Adapter {
+ protected S2(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S2(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1); }
+ protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1)); }
+ }
+ static class S3 extends Adapter {
+ protected S3(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S3(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S3 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S3(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2); }
+ protected Object invoke_S1(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ }
+ static class S4 extends Adapter {
+ protected S4(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S4(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S4 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S4(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ }
+ static class S5 extends Adapter {
+ protected S5(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S5(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S5 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S5(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3, a4); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2, a3,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object av) throws Throwable { av = super.check(av, 5);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ }
+ static class S6 extends Adapter {
+ protected S6(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S6(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S6 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S6(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2, a3, a4,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object av) throws Throwable { av = super.check(av, 5);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object av) throws Throwable { av = super.check(av, 6);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ }
+ static class S7 extends Adapter {
+ protected S7(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S7(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S7 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S7(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 5);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object av) throws Throwable { av = super.check(av, 6);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object av) throws Throwable { av = super.check(av, 7);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ }
+ static class S8 extends Adapter {
+ protected S8(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S8(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S8 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S8(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 5);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 6);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object a0, Object av) throws Throwable { av = super.check(av, 7);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ protected Object invoke_S8(Object av) throws Throwable { av = super.check(av, 8);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
+ }
+ static class S9 extends Adapter {
+ protected S9(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S9(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S9 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S9(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 5);
+ return target.<Object>invoke(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 6);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 7);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ protected Object invoke_S8(Object a0, Object av) throws Throwable { av = super.check(av, 8);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
+ protected Object invoke_S9(Object av) throws Throwable { av = super.check(av, 9);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
+ super.select(av,8)); }
+ }
+ static class S10 extends Adapter {
+ protected S10(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S10(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S10 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S10(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9, Object av) throws Throwable { av = super.check(av, 0);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 1);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 2);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 3);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 4);
+ return target.<Object>invoke(a0, a1, a2, a3, a4, a5,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 5);
+ return target.<Object>invoke(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 6);
+ return target.<Object>invoke(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 7);
+ return target.<Object>invoke(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ protected Object invoke_S8(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 8);
+ return target.<Object>invoke(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
+ protected Object invoke_S9(Object a0, Object av) throws Throwable { av = super.check(av, 9);
+ return target.<Object>invoke(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
+ super.select(av,8)); }
+ protected Object invoke_S10(Object av) throws Throwable { av = super.check(av, 10);
+ return target.<Object>invoke(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
+ super.select(av,8), super.select(av,9)); }
+ }
+}
--- a/jdk/src/share/classes/sun/dyn/ToGeneric.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/ToGeneric.java Wed Jul 05 17:04:56 2017 +0200
@@ -34,6 +34,7 @@
import java.lang.reflect.InvocationTargetException;
import sun.dyn.util.ValueConversions;
import sun.dyn.util.Wrapper;
+import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* Adapters which mediate between incoming calls which are not generic
@@ -68,7 +69,7 @@
// conversion which unboxes a primitive return value
private final MethodHandle returnConversion;
- /** Compute and cache information common to all collecting adapters
+ /** Compute and cache information common to all generifying (boxing) adapters
* that implement members of the erasure-family of the given erased type.
*/
private ToGeneric(MethodType entryType) {
@@ -111,30 +112,48 @@
// primitive arguments according to their "raw" types int/long
MethodType intsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsInts();
ad = findAdapter(rawEntryTypeInit = intsAtEnd);
- if (ad == null) {
+ MethodHandle rawEntryPoint;
+ if (ad != null) {
+ rawEntryPoint = ad.prototypeEntryPoint();
+ } else {
// Perhaps the adapter is available only for longs.
// If so, we can use it, but there will have to be a little
// more stack motion on each call.
MethodType longsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsLongs();
ad = findAdapter(rawEntryTypeInit = longsAtEnd);
- if (ad == null) {
+ if (ad != null) {
+ MethodType eptWithLongs = longsAtEnd.insertParameterTypes(0, ad.getClass());
+ MethodType eptWithInts = intsAtEnd.insertParameterTypes(0, ad.getClass());
+ rawEntryPoint = ad.prototypeEntryPoint();
+ MethodType midType = eptWithLongs; // will change longs to ints
+ for (int i = 0, nargs = midType.parameterCount(); i < nargs; i++) {
+ if (midType.parameterType(i) != eptWithInts.parameterType(i)) {
+ assert(midType.parameterType(i) == long.class);
+ assert(eptWithInts.parameterType(i) == int.class);
+ MethodType nextType = midType.changeParameterType(i, int.class);
+ rawEntryPoint = MethodHandle.convertArguments(Access.TOKEN,
+ rawEntryPoint, nextType, midType, null);
+ midType = nextType;
+ }
+ }
+ assert(midType == eptWithInts);
+ } else {
// If there is no statically compiled adapter,
// build one by means of dynamic bytecode generation.
ad = buildAdapterFromBytecodes(rawEntryTypeInit = intsAtEnd);
+ rawEntryPoint = ad.prototypeEntryPoint();
}
}
- MethodHandle rawEntryPoint = ad.prototypeEntryPoint();
- MethodType tepType = entryType.insertParameterType(0, ad.getClass());
+ MethodType tepType = entryType.insertParameterTypes(0, ad.getClass());
this.entryPoint =
- AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, rawEntryPoint);
+ AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, rawEntryPoint);
if (this.entryPoint == null)
throw new UnsupportedOperationException("cannot retype to "+entryType
- +" from "+rawEntryPoint.type().dropParameterType(0));
+ +" from "+rawEntryPoint.type().dropParameterTypes(0, 1));
this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
this.rawEntryType = rawEntryTypeInit;
this.adapter = ad;
- this.invoker = makeRawArgumentFilter(invoker0,
- rawEntryPoint.type().dropParameterType(0), entryType);
+ this.invoker = makeRawArgumentFilter(invoker0, rawEntryTypeInit, entryType);
}
/** A generic argument list will be created by a call of type 'raw'.
@@ -157,8 +176,8 @@
if (filteredInvoker == null) throw new UnsupportedOperationException("NYI");
}
MethodHandle reboxer = ValueConversions.rebox(dst, false);
- FilterGeneric gen = new FilterGeneric(filteredInvoker.type(), (short)(1+i), (short)1, 'R');
- filteredInvoker = gen.makeInstance(reboxer, filteredInvoker);
+ filteredInvoker = FilterGeneric.makeArgumentFilter(1+i, reboxer, filteredInvoker);
+ if (filteredInvoker == null) throw new InternalError();
}
if (filteredInvoker == null) return invoker;
return AdapterMethodHandle.makeRetypeOnly(Access.TOKEN, invoker.type(), filteredInvoker);
@@ -209,9 +228,9 @@
if (convert == null)
convert = computeReturnConversion(type, rawEntryType, true);
// retype erased reference arguments (the cast makes it safe to do this)
- MethodType tepType = type.insertParameterType(0, adapter.getClass());
+ MethodType tepType = type.insertParameterTypes(0, adapter.getClass());
MethodHandle typedEntryPoint =
- AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, entryPoint);
+ AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, entryPoint);
return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
}
@@ -225,7 +244,7 @@
public static MethodHandle make(MethodType type, MethodHandle genericTarget) {
MethodType gtype = genericTarget.type();
if (type.generic() != gtype)
- throw new IllegalArgumentException();
+ throw newIllegalArgumentException("type must be generic");
if (type == gtype) return genericTarget;
return ToGeneric.of(type).makeInstance(type, genericTarget);
}
@@ -283,7 +302,10 @@
try {
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
- } catch (InvocationTargetException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
@@ -317,6 +339,11 @@
protected final MethodHandle target; // Object... -> Object
protected final MethodHandle convert; // Object -> R
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+
protected boolean isPrototype() { return target == null; }
/* Prototype constructor. */
protected Adapter(MethodHandle entryPoint) {
@@ -344,33 +371,33 @@
// { return new ThisType(entryPoint, convert, target); }
// Code to run when the arguments (<= 4) have all been boxed.
- protected Object target() { return invoker.<Object>invoke(target); }
- protected Object target(Object a0) { return invoker.<Object>invoke(target, a0); }
+ protected Object target() throws Throwable { return invoker.<Object>invoke(target); }
+ protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); }
protected Object target(Object a0, Object a1)
- { return invoker.<Object>invoke(target, a0, a1); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, a1); }
protected Object target(Object a0, Object a1, Object a2)
- { return invoker.<Object>invoke(target, a0, a1, a2); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2); }
protected Object target(Object a0, Object a1, Object a2, Object a3)
- { return invoker.<Object>invoke(target, a0, a1, a2, a3); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3); }
/*
- protected Object target_0(Object... av) { return invoker.<Object>invoke(target, av); }
+ protected Object target_0(Object... av) throws Throwable { return invoker.<Object>invoke(target, av); }
protected Object target_1(Object a0, Object... av)
- { return invoker.<Object>invoke(target, a0, (Object)av); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, (Object)av); }
protected Object target_2(Object a0, Object a1, Object... av)
- { return invoker.<Object>invoke(target, a0, a1, (Object)av); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, a1, (Object)av); }
protected Object target_3(Object a0, Object a1, Object a2, Object... av)
- { return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); }
protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
- { return invoker.<Object>invoke(target, a0, a1, a2, a3, (Object)av); }
+ throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, (Object)av); }
// */
// (For more than 4 arguments, generate the code in the adapter itself.)
// Code to run when the generic target has finished and produced a value.
- protected Object return_L(Object res) { return convert.<Object>invoke(res); }
- protected int return_I(Object res) { return convert.<int >invoke(res); }
- protected long return_J(Object res) { return convert.<long >invoke(res); }
- protected float return_F(Object res) { return convert.<float >invoke(res); }
- protected double return_D(Object res) { return convert.<double>invoke(res); }
+ protected Object return_L(Object res) throws Throwable { return convert.<Object>invoke(res); }
+ protected int return_I(Object res) throws Throwable { return convert.<int >invoke(res); }
+ protected long return_J(Object res) throws Throwable { return convert.<long >invoke(res); }
+ protected float return_F(Object res) throws Throwable { return convert.<float >invoke(res); }
+ protected double return_D(Object res) throws Throwable { return convert.<double>invoke(res); }
static private final String CLASS_PREFIX; // "sun.dyn.ToGeneric$"
static {
@@ -397,25 +424,25 @@
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
- protected Object target(Object a0) { return invoker.<Object>invoke(target, a0); }
- protected Object targetA1(Object a0) { return target(a0); }
- protected Object targetA1(int a0) { return target(a0); }
- protected Object targetA1(long a0) { return target(a0); }
- protected Object invoke_L(Object a0) { return return_L(targetA1(a0)); }
- protected int invoke_I(Object a0) { return return_I(targetA1(a0)); }
- protected long invoke_J(Object a0) { return return_J(targetA1(a0)); }
- protected float invoke_F(Object a0) { return return_F(targetA1(a0)); }
- protected double invoke_D(Object a0) { return return_D(targetA1(a0)); }
- protected Object invoke_L(int a0) { return return_L(targetA1(a0)); }
- protected int invoke_I(int a0) { return return_I(targetA1(a0)); }
- protected long invoke_J(int a0) { return return_J(targetA1(a0)); }
- protected float invoke_F(int a0) { return return_F(targetA1(a0)); }
- protected double invoke_D(int a0) { return return_D(targetA1(a0)); }
- protected Object invoke_L(long a0) { return return_L(targetA1(a0)); }
- protected int invoke_I(long a0) { return return_I(targetA1(a0)); }
- protected long invoke_J(long a0) { return return_J(targetA1(a0)); }
- protected float invoke_F(long a0) { return return_F(targetA1(a0)); }
- protected double invoke_D(long a0) { return return_D(targetA1(a0)); }
+ protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); }
+ protected Object targetA1(Object a0) throws Throwable { return target(a0); }
+ protected Object targetA1(int a0) throws Throwable { return target(a0); }
+ protected Object targetA1(long a0) throws Throwable { return target(a0); }
+ protected Object invoke_L(Object a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(Object a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(Object a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(Object a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(Object a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(int a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(int a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(int a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(int a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(int a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(long a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(long a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(long a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(long a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(long a0) throws Throwable { return return_D(targetA1(a0)); }
}
// */
@@ -435,13 +462,13 @@
" protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
" protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
- " protected Object target(@Ovav@) { return invoker.<Object>invoke(target, @av@); }",
+ " protected Object target(@Ovav@) throws Throwable { return invoker.<Object>invoke(target, @av@); }",
" //@each-Tv@",
- " protected Object target@cat@(@Tvav@) { return target(@av@); }",
+ " protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }",
" //@end-Tv@",
" //@each-Tv@",
" //@each-R@",
- " protected @R@ invoke_@Rc@(@Tvav@) { return return_@Rc@(target@cat@(@av@)); }",
+ " protected @R@ invoke_@Rc@(@Tvav@) throws Throwable { return return_@Rc@(target@cat@(@av@)); }",
" //@end-R@",
" //@end-Tv@",
" }",
@@ -595,424 +622,424 @@
protected A0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A0(e, i, c, t); }
- protected Object target() { return invoker.<Object>invoke(target); }
- protected Object targetA0() { return target(); }
- protected Object invoke_L() { return return_L(targetA0()); }
- protected int invoke_I() { return return_I(targetA0()); }
- protected long invoke_J() { return return_J(targetA0()); }
- protected float invoke_F() { return return_F(targetA0()); }
- protected double invoke_D() { return return_D(targetA0()); }
+ protected Object target() throws Throwable { return invoker.<Object>invoke(target); }
+ protected Object targetA0() throws Throwable { return target(); }
+ protected Object invoke_L() throws Throwable { return return_L(targetA0()); }
+ protected int invoke_I() throws Throwable { return return_I(targetA0()); }
+ protected long invoke_J() throws Throwable { return return_J(targetA0()); }
+ protected float invoke_F() throws Throwable { return return_F(targetA0()); }
+ protected double invoke_D() throws Throwable { return return_D(targetA0()); }
}
static class A1 extends Adapter {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
- protected Object target(Object a0) { return invoker.<Object>invoke(target, a0); }
- protected Object targetA1(Object a0) { return target(a0); }
- protected Object targetA1(int a0) { return target(a0); }
- protected Object targetA1(long a0) { return target(a0); }
- protected Object invoke_L(Object a0) { return return_L(targetA1(a0)); }
- protected int invoke_I(Object a0) { return return_I(targetA1(a0)); }
- protected long invoke_J(Object a0) { return return_J(targetA1(a0)); }
- protected float invoke_F(Object a0) { return return_F(targetA1(a0)); }
- protected double invoke_D(Object a0) { return return_D(targetA1(a0)); }
- protected Object invoke_L(int a0) { return return_L(targetA1(a0)); }
- protected int invoke_I(int a0) { return return_I(targetA1(a0)); }
- protected long invoke_J(int a0) { return return_J(targetA1(a0)); }
- protected float invoke_F(int a0) { return return_F(targetA1(a0)); }
- protected double invoke_D(int a0) { return return_D(targetA1(a0)); }
- protected Object invoke_L(long a0) { return return_L(targetA1(a0)); }
- protected int invoke_I(long a0) { return return_I(targetA1(a0)); }
- protected long invoke_J(long a0) { return return_J(targetA1(a0)); }
- protected float invoke_F(long a0) { return return_F(targetA1(a0)); }
- protected double invoke_D(long a0) { return return_D(targetA1(a0)); }
+ protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); }
+ protected Object targetA1(Object a0) throws Throwable { return target(a0); }
+ protected Object targetA1(int a0) throws Throwable { return target(a0); }
+ protected Object targetA1(long a0) throws Throwable { return target(a0); }
+ protected Object invoke_L(Object a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(Object a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(Object a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(Object a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(Object a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(int a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(int a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(int a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(int a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(int a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(long a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(long a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(long a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(long a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(long a0) throws Throwable { return return_D(targetA1(a0)); }
}
static class A2 extends Adapter {
protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A2(e, i, c, t); }
- protected Object target(Object a0, Object a1) { return invoker.<Object>invoke(target, a0, a1); }
- protected Object targetA2(Object a0, Object a1) { return target(a0, a1); }
- protected Object targetA2(Object a0, int a1) { return target(a0, a1); }
- protected Object targetA2(int a0, int a1) { return target(a0, a1); }
- protected Object targetA2(Object a0, long a1) { return target(a0, a1); }
- protected Object targetA2(long a0, long a1) { return target(a0, a1); }
- protected Object invoke_L(Object a0, Object a1) { return return_L(targetA2(a0, a1)); }
- protected int invoke_I(Object a0, Object a1) { return return_I(targetA2(a0, a1)); }
- protected long invoke_J(Object a0, Object a1) { return return_J(targetA2(a0, a1)); }
- protected float invoke_F(Object a0, Object a1) { return return_F(targetA2(a0, a1)); }
- protected double invoke_D(Object a0, Object a1) { return return_D(targetA2(a0, a1)); }
- protected Object invoke_L(Object a0, int a1) { return return_L(targetA2(a0, a1)); }
- protected int invoke_I(Object a0, int a1) { return return_I(targetA2(a0, a1)); }
- protected long invoke_J(Object a0, int a1) { return return_J(targetA2(a0, a1)); }
- protected float invoke_F(Object a0, int a1) { return return_F(targetA2(a0, a1)); }
- protected double invoke_D(Object a0, int a1) { return return_D(targetA2(a0, a1)); }
- protected Object invoke_L(int a0, int a1) { return return_L(targetA2(a0, a1)); }
- protected int invoke_I(int a0, int a1) { return return_I(targetA2(a0, a1)); }
- protected long invoke_J(int a0, int a1) { return return_J(targetA2(a0, a1)); }
- protected float invoke_F(int a0, int a1) { return return_F(targetA2(a0, a1)); }
- protected double invoke_D(int a0, int a1) { return return_D(targetA2(a0, a1)); }
- protected Object invoke_L(Object a0, long a1) { return return_L(targetA2(a0, a1)); }
- protected int invoke_I(Object a0, long a1) { return return_I(targetA2(a0, a1)); }
- protected long invoke_J(Object a0, long a1) { return return_J(targetA2(a0, a1)); }
- protected float invoke_F(Object a0, long a1) { return return_F(targetA2(a0, a1)); }
- protected double invoke_D(Object a0, long a1) { return return_D(targetA2(a0, a1)); }
- protected Object invoke_L(long a0, long a1) { return return_L(targetA2(a0, a1)); }
- protected int invoke_I(long a0, long a1) { return return_I(targetA2(a0, a1)); }
- protected long invoke_J(long a0, long a1) { return return_J(targetA2(a0, a1)); }
- protected float invoke_F(long a0, long a1) { return return_F(targetA2(a0, a1)); }
- protected double invoke_D(long a0, long a1) { return return_D(targetA2(a0, a1)); }
+ protected Object target(Object a0, Object a1) throws Throwable { return invoker.<Object>invoke(target, a0, a1); }
+ protected Object targetA2(Object a0, Object a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(Object a0, int a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(int a0, int a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(Object a0, long a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(long a0, long a1) throws Throwable { return target(a0, a1); }
+ protected Object invoke_L(Object a0, Object a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(Object a0, Object a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(Object a0, Object a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(Object a0, Object a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(Object a0, Object a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(Object a0, int a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(Object a0, int a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(Object a0, int a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(Object a0, int a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(Object a0, int a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(int a0, int a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(int a0, int a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(int a0, int a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(int a0, int a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(int a0, int a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(Object a0, long a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(Object a0, long a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(Object a0, long a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(Object a0, long a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(Object a0, long a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(long a0, long a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(long a0, long a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(long a0, long a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(long a0, long a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(long a0, long a1) throws Throwable { return return_D(targetA2(a0, a1)); }
}
static class A3 extends Adapter {
protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A3(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A3(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2) { return invoker.<Object>invoke(target, a0, a1, a2); }
- protected Object targetA3(Object a0, Object a1, Object a2) { return target(a0, a1, a2); }
- protected Object targetA3(Object a0, Object a1, int a2) { return target(a0, a1, a2); }
- protected Object targetA3(Object a0, int a1, int a2) { return target(a0, a1, a2); }
- protected Object targetA3(int a0, int a1, int a2) { return target(a0, a1, a2); }
- protected Object targetA3(Object a0, Object a1, long a2) { return target(a0, a1, a2); }
- protected Object targetA3(Object a0, long a1, long a2) { return target(a0, a1, a2); }
- protected Object targetA3(long a0, long a1, long a2) { return target(a0, a1, a2); }
- protected Object invoke_L(Object a0, Object a1, Object a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(Object a0, Object a1, Object a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(Object a0, Object a1, Object a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(Object a0, Object a1, Object a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(Object a0, Object a1, Object a2) { return return_D(targetA3(a0, a1, a2)); }
- protected Object invoke_L(Object a0, Object a1, int a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(Object a0, Object a1, int a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(Object a0, Object a1, int a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(Object a0, Object a1, int a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(Object a0, Object a1, int a2) { return return_D(targetA3(a0, a1, a2)); }
- protected Object invoke_L(Object a0, int a1, int a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(Object a0, int a1, int a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(Object a0, int a1, int a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(Object a0, int a1, int a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(Object a0, int a1, int a2) { return return_D(targetA3(a0, a1, a2)); }
- protected Object invoke_L(int a0, int a1, int a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(int a0, int a1, int a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(int a0, int a1, int a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(int a0, int a1, int a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(int a0, int a1, int a2) { return return_D(targetA3(a0, a1, a2)); }
- protected Object invoke_L(Object a0, Object a1, long a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(Object a0, Object a1, long a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(Object a0, Object a1, long a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(Object a0, Object a1, long a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(Object a0, Object a1, long a2) { return return_D(targetA3(a0, a1, a2)); }
- protected Object invoke_L(Object a0, long a1, long a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(Object a0, long a1, long a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(Object a0, long a1, long a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(Object a0, long a1, long a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(Object a0, long a1, long a2) { return return_D(targetA3(a0, a1, a2)); }
- protected Object invoke_L(long a0, long a1, long a2) { return return_L(targetA3(a0, a1, a2)); }
- protected int invoke_I(long a0, long a1, long a2) { return return_I(targetA3(a0, a1, a2)); }
- protected long invoke_J(long a0, long a1, long a2) { return return_J(targetA3(a0, a1, a2)); }
- protected float invoke_F(long a0, long a1, long a2) { return return_F(targetA3(a0, a1, a2)); }
- protected double invoke_D(long a0, long a1, long a2) { return return_D(targetA3(a0, a1, a2)); }
+ protected Object target(Object a0, Object a1, Object a2) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2); }
+ protected Object targetA3(Object a0, Object a1, Object a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, Object a1, int a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, int a1, int a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(int a0, int a1, int a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, Object a1, long a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, long a1, long a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(long a0, long a1, long a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object invoke_L(Object a0, Object a1, Object a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, Object a1, Object a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, Object a1, Object a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, Object a1, Object a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, Object a1, Object a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, Object a1, int a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, Object a1, int a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, Object a1, int a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, Object a1, int a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, Object a1, int a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, int a1, int a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, int a1, int a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, int a1, int a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, int a1, int a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, int a1, int a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(int a0, int a1, int a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(int a0, int a1, int a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(int a0, int a1, int a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(int a0, int a1, int a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(int a0, int a1, int a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, Object a1, long a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, Object a1, long a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, Object a1, long a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, Object a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, Object a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, long a1, long a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, long a1, long a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, long a1, long a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, long a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, long a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(long a0, long a1, long a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(long a0, long a1, long a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(long a0, long a1, long a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(long a0, long a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(long a0, long a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
}
//params=[4, 5, 2, 99, 99, 99]
static class A4 extends Adapter {
protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A4(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3) { return invoker.<Object>invoke(target, a0, a1, a2, a3); }
- protected Object targetA4(Object a0, Object a1, Object a2, Object a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(Object a0, Object a1, Object a2, int a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(Object a0, Object a1, int a2, int a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(Object a0, int a1, int a2, int a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(int a0, int a1, int a2, int a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(Object a0, Object a1, Object a2, long a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(Object a0, Object a1, long a2, long a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(Object a0, long a1, long a2, long a3) { return target(a0, a1, a2, a3); }
- protected Object targetA4(long a0, long a1, long a2, long a3) { return target(a0, a1, a2, a3); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, Object a1, Object a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, Object a1, Object a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(Object a0, Object a1, int a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, Object a1, int a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, Object a1, int a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(Object a0, int a1, int a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, int a1, int a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, int a1, int a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(int a0, int a1, int a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(int a0, int a1, int a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(int a0, int a1, int a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
- protected int invoke_I(long a0, long a1, long a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
- protected long invoke_J(long a0, long a1, long a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, Object a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, int a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(int a0, int a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, Object a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, long a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, long a1, long a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(long a0, long a1, long a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(int a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(int a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(int a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
}
static class A5 extends Adapter {
protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A5(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, Object a2, Object a3, Object a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, Object a2, Object a3, int a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, Object a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, int a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, int a1, int a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(int a0, int a1, int a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, Object a2, Object a3, long a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, Object a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, Object a1, long a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(Object a0, long a1, long a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
- protected Object targetA5(long a0, long a1, long a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, Object a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, Object a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, Object a1, int a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, int a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, int a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, int a1, int a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, int a1, int a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, int a1, int a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(int a0, int a1, int a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(int a0, int a1, int a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(int a0, int a1, int a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
- protected int invoke_I(long a0, long a1, long a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
- protected long invoke_J(long a0, long a1, long a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(int a0, int a1, int a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(long a0, long a1, long a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(int a0, int a1, int a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(int a0, int a1, int a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(int a0, int a1, int a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
}
//params=[6, 10, 2, 99, 0, 99]
static class A6 extends Adapter {
protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A6(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A6(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(Object a0, Object a1, Object a2, Object a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(Object a0, Object a1, Object a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(Object a0, Object a1, long a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(Object a0, long a1, long a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object targetA6(long a0, long a1, long a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5) { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5) { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
- protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
}
static class A7 extends Adapter {
protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A7(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A7(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object targetA7(long a0, long a1, long a2, long a3, long a4, long a5, long a6) { return target(a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6) { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6) { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
- protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
}
static class A8 extends Adapter {
protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A8(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A8(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object targetA8(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
}
static class A9 extends Adapter {
protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A9(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A9(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object targetA9(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
}
static class A10 extends Adapter {
protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A10(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A10(e, i, c, t); }
- protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object targetA10(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
}
}
--- a/jdk/src/share/classes/sun/dyn/empty/Empty.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/empty/Empty.java Wed Jul 05 17:04:56 2017 +0200
@@ -29,6 +29,10 @@
* An empty class in an empty package.
* Used as a proxy for unprivileged code, since making access checks
* against it will only succeed against public methods in public types.
+ * <p>
+ * This class also stands (internally to sun.dyn) for the type of a
+ * value that cannot be produced, because the expression of this type
+ * always returns abnormally. (Cf. Nothing in the closures proposal.)
* @author jrose
*/
public class Empty {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.dyn.util;
+
+import java.dyn.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility routines for dealing with bytecode-level signatures.
+ * @author jrose
+ */
+public class BytecodeDescriptor {
+
+ private BytecodeDescriptor() { } // cannot instantiate
+
+ public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {
+ return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);
+ }
+
+ static List<Class<?>> parseMethod(String bytecodeSignature,
+ int start, int end, ClassLoader loader) {
+ if (loader == null)
+ loader = ClassLoader.getSystemClassLoader();
+ String str = bytecodeSignature;
+ int[] i = {start};
+ ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>();
+ if (i[0] < end && str.charAt(i[0]) == '(') {
+ ++i[0]; // skip '('
+ while (i[0] < end && str.charAt(i[0]) != ')') {
+ Class<?> pt = parseSig(str, i, end, loader);
+ if (pt == null || pt == void.class)
+ parseError(str, "bad argument type");
+ ptypes.add(pt);
+ }
+ ++i[0]; // skip ')'
+ } else {
+ parseError(str, "not a method type");
+ }
+ Class<?> rtype = parseSig(str, i, end, loader);
+ if (rtype == null || i[0] != end)
+ parseError(str, "bad return type");
+ ptypes.add(rtype);
+ return ptypes;
+ }
+
+ static private void parseError(String str, String msg) {
+ throw new IllegalArgumentException("bad signature: "+str+": "+msg);
+ }
+
+ static private Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {
+ if (i[0] == end) return null;
+ char c = str.charAt(i[0]++);
+ if (c == 'L') {
+ int begc = i[0], endc = str.indexOf(';', begc);
+ if (endc < 0) return null;
+ i[0] = endc+1;
+ String name = str.substring(begc, endc).replace('/', '.');
+ try {
+ return loader.loadClass(name);
+ } catch (ClassNotFoundException ex) {
+ throw new TypeNotPresentException(name, ex);
+ }
+ } else if (c == '[') {
+ Class<?> t = parseSig(str, i, end, loader);
+ if (t != null)
+ t = java.lang.reflect.Array.newInstance(t, 0).getClass();
+ return t;
+ } else {
+ return Wrapper.forBasicType(c).primitiveType();
+ }
+ }
+
+ public static String unparse(Class<?> type) {
+ StringBuilder sb = new StringBuilder();
+ unparseSig(type, sb);
+ return sb.toString();
+ }
+
+ public static String unparse(MethodType type) {
+ return unparseMethod(type.returnType(), type.parameterList());
+ }
+
+ public static String unparse(Object type) {
+ if (type instanceof Class<?>)
+ return unparse((Class<?>) type);
+ if (type instanceof MethodType)
+ return unparse((MethodType) type);
+ return (String) type;
+ }
+
+ public static String unparseMethod(Class<?> rtype, List<Class<?>> ptypes) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('(');
+ for (Class<?> pt : ptypes)
+ unparseSig(pt, sb);
+ sb.append(')');
+ unparseSig(rtype, sb);
+ return sb.toString();
+ }
+
+ static private void unparseSig(Class<?> t, StringBuilder sb) {
+ char c = Wrapper.forBasicType(t).basicTypeChar();
+ if (c != 'L') {
+ sb.append(c);
+ } else {
+ boolean lsemi = (!t.isArray());
+ if (lsemi) sb.append('L');
+ sb.append(t.getName().replace('.', '/'));
+ if (lsemi) sb.append(';');
+ }
+ }
+
+}
--- a/jdk/src/share/classes/sun/dyn/util/BytecodeName.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/util/BytecodeName.java Wed Jul 05 17:04:56 2017 +0200
@@ -298,6 +298,8 @@
* The name {@code <init>} will be parsed into { '<', "init", '>'}}
* The name {@code foo/bar$:baz} will be parsed into
* {@code {"foo", '/', "bar", '$', ':', "baz"}}.
+ * The name {@code ::\=:foo:\=bar\!baz} will be parsed into
+ * {@code {':', ':', "", ':', "foo", ':', "bar:baz"}}.
*/
public static Object[] parseBytecodeName(String s) {
int slen = s.length();
@@ -315,7 +317,7 @@
if (lasti < i) {
// normal component
if (pass != 0)
- res[fillp] = s.substring(lasti, i);
+ res[fillp] = toSourceName(s.substring(lasti, i));
fillp++;
lasti = i+1;
}
@@ -323,13 +325,14 @@
if (pass != 0)
res[fillp] = DANGEROUS_CHARS_CA[whichDC];
fillp++;
+ lasti = i+1;
}
}
if (pass != 0) break;
// between passes, build the result array
- res = new String[fillp];
- if (fillp <= 1) {
- if (fillp != 0) res[0] = s;
+ res = new Object[fillp];
+ if (fillp <= 1 && lasti == 0) {
+ if (fillp != 0) res[0] = toSourceName(s);
break;
}
}
@@ -348,9 +351,19 @@
* @throws NullPointerException if any component is null
*/
public static String unparseBytecodeName(Object[] components) {
- for (Object c : components) {
- if (c instanceof String)
- checkSafeBytecodeName((String) c); // may fail
+ Object[] components0 = components;
+ for (int i = 0; i < components.length; i++) {
+ Object c = components[i];
+ if (c instanceof String) {
+ String mc = toBytecodeName((String) c);
+ if (i == 0 && components.length == 1)
+ return mc; // usual case
+ if ((Object)mc != c) {
+ if (components == components0)
+ components = components.clone();
+ components[i] = c = mc;
+ }
+ }
}
return appendAll(components);
}
@@ -381,6 +394,14 @@
* If the bytecode name contains dangerous characters,
* assume that they are being used as punctuation,
* and pass them through unchanged.
+ * Non-empty runs of non-dangerous characters are demangled
+ * if necessary, and the resulting names are quoted if
+ * they are not already valid Java identifiers, or if
+ * they contain a dangerous character (i.e., dollar sign "$").
+ * Single quotes are used when quoting.
+ * Within quoted names, embedded single quotes and backslashes
+ * are further escaped by prepended backslashes.
+ *
* @param s the original bytecode name (which may be qualified)
* @return a human-readable presentation
*/
@@ -389,10 +410,10 @@
for (int i = 0; i < components.length; i++) {
if (!(components[i] instanceof String))
continue;
- String c = (String) components[i];
- // pretty up the name by demangling it
- String sn = toSourceName(c);
- if ((Object)sn != c || !isJavaIdent(sn)) {
+ String sn = (String) components[i];
+ // note that the name is already demangled!
+ //sn = toSourceName(sn);
+ if (!isJavaIdent(sn) || sn.indexOf('$') >=0 ) {
components[i] = quoteDisplay(sn);
}
}
@@ -401,10 +422,10 @@
private static boolean isJavaIdent(String s) {
int slen = s.length();
if (slen == 0) return false;
- if (!Character.isUnicodeIdentifierStart(s.charAt(0)))
+ if (!Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < slen; i++) {
- if (!Character.isUnicodeIdentifierPart(s.charAt(0)))
+ if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
}
return true;
@@ -602,110 +623,5 @@
return -1;
}
- // test driver
- static void main(String[] av) {
- // If verbose is enabled, quietly check everything.
- // Otherwise, print the output for the user to check.
- boolean verbose = false;
- int maxlen = 0;
-
- while (av.length > 0 && av[0].startsWith("-")) {
- String flag = av[0].intern();
- av = java.util.Arrays.copyOfRange(av, 1, av.length); // Java 1.6 or later
- if (flag == "-" || flag == "--") break;
- else if (flag == "-q")
- verbose = false;
- else if (flag == "-v")
- verbose = true;
- else if (flag.startsWith("-l"))
- maxlen = Integer.valueOf(flag.substring(2));
- else
- throw new Error("Illegal flag argument: "+flag);
- }
-
- if (maxlen == 0)
- maxlen = (verbose ? 2 : 4);
- if (verbose) System.out.println("Note: maxlen = "+maxlen);
-
- switch (av.length) {
- case 0: av = new String[] {
- DANGEROUS_CHARS.substring(0) +
- REPLACEMENT_CHARS.substring(0, 1) +
- NULL_ESCAPE + "x"
- }; // and fall through:
- case 1:
- char[] cv = av[0].toCharArray();
- av = new String[cv.length];
- int avp = 0;
- for (char c : cv) {
- String s = String.valueOf(c);
- if (c == 'x') s = "foo"; // tradition...
- av[avp++] = s;
- }
- }
- if (verbose)
- System.out.println("Note: Verbose output mode enabled. Use '-q' to suppress.");
- Tester t = new Tester();
- t.maxlen = maxlen;
- t.verbose = verbose;
- t.tokens = av;
- t.test("", 0);
- }
-
- static class Tester {
- boolean verbose;
- int maxlen;
- java.util.Map<String,String> map = new java.util.HashMap<String,String>();
- String[] tokens;
-
- void test(String stringSoFar, int tokensSoFar) {
- test(stringSoFar);
- if (tokensSoFar <= maxlen) {
- for (String token : tokens) {
- if (token.length() == 0) continue; // skip empty tokens
- if (stringSoFar.indexOf(token) != stringSoFar.lastIndexOf(token))
- continue; // there are already two occs. of this token
- if (token.charAt(0) == ESCAPE_C && token.length() == 1 && maxlen < 4)
- test(stringSoFar+token, tokensSoFar); // want lots of \'s
- else if (tokensSoFar < maxlen)
- test(stringSoFar+token, tokensSoFar+1);
- }
- }
- }
-
- void test(String s) {
- // for small batches, do not test the null string
- if (s.length() == 0 && maxlen >=1 && maxlen <= 2) return;
- String bn = testSourceName(s);
- if (bn == null) return;
- if (bn == s) {
- //if (verbose) System.out.println(s+" == id");
- } else {
- if (verbose) System.out.println(s+" => "+bn+" "+toDisplayName(bn));
- String bnbn = testSourceName(bn);
- if (bnbn == null) return;
- if (verbose) System.out.println(bn+" => "+bnbn+" "+toDisplayName(bnbn));
- /*
- String bn3 = testSourceName(bnbn);
- if (bn3 == null) return;
- if (verbose) System.out.println(bnbn+" => "+bn3);
- */
- }
- }
-
- String testSourceName(String s) {
- if (map.containsKey(s)) return null;
- String bn = toBytecodeName(s);
- map.put(s, bn);
- String sn = toSourceName(bn);
- if (!sn.equals(s)) {
- String bad = (s+" => "+bn+" != "+sn);
- if (!verbose) throw new Error("Bad mangling: "+bad);
- System.out.println("*** "+bad);
- return null;
- }
- return bn;
- }
- }
}
--- a/jdk/src/share/classes/sun/dyn/util/BytecodeSignature.java Thu Dec 17 14:10:20 2009 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.dyn.util;
-
-import java.dyn.MethodType;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility routines for dealing with bytecode-level signatures.
- * @author jrose
- */
-public class BytecodeSignature {
-
- private BytecodeSignature() { } // cannot instantiate
-
- public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {
- return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);
- }
-
- static List<Class<?>> parseMethod(String bytecodeSignature,
- int start, int end, ClassLoader loader) {
- if (loader == null)
- loader = ClassLoader.getSystemClassLoader();
- String str = bytecodeSignature;
- int[] i = {start};
- ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>();
- if (i[0] < end && str.charAt(i[0]) == '(') {
- ++i[0]; // skip '('
- while (i[0] < end && str.charAt(i[0]) != ')') {
- Class<?> pt = parseSig(str, i, end, loader);
- if (pt == null || pt == void.class)
- parseError(str, "bad argument type");
- ptypes.add(pt);
- }
- ++i[0]; // skip ')'
- } else {
- parseError(str, "not a method type");
- }
- Class<?> rtype = parseSig(str, i, end, loader);
- if (rtype == null || i[0] != end)
- parseError(str, "bad return type");
- ptypes.add(rtype);
- return ptypes;
- }
-
- static private void parseError(String str, String msg) {
- throw new IllegalArgumentException("bad signature: "+str+": "+msg);
- }
-
- static private Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {
- if (i[0] == end) return null;
- char c = str.charAt(i[0]++);
- if (c == 'L') {
- int begc = i[0], endc = str.indexOf(';', begc);
- if (endc < 0) return null;
- i[0] = endc+1;
- String name = str.substring(begc, endc).replace('/', '.');
- try {
- return loader.loadClass(name);
- } catch (ClassNotFoundException ex) {
- throw new TypeNotPresentException(name, ex);
- }
- } else if (c == '[') {
- Class<?> t = parseSig(str, i, end, loader);
- if (t != null)
- t = java.lang.reflect.Array.newInstance(t, 0).getClass();
- return t;
- } else {
- return Wrapper.forBasicType(c).primitiveType();
- }
- }
-
- public static String unparse(Class<?> type) {
- StringBuilder sb = new StringBuilder();
- unparseSig(type, sb);
- return sb.toString();
- }
-
- public static String unparse(MethodType type) {
- return unparseMethod(type.returnType(), type.parameterList());
- }
-
- public static String unparse(Object type) {
- if (type instanceof Class<?>)
- return unparse((Class<?>) type);
- if (type instanceof MethodType)
- return unparse((MethodType) type);
- return (String) type;
- }
-
- public static String unparseMethod(Class<?> rtype, List<Class<?>> ptypes) {
- StringBuilder sb = new StringBuilder();
- sb.append('(');
- for (Class<?> pt : ptypes)
- unparseSig(pt, sb);
- sb.append(')');
- unparseSig(rtype, sb);
- return sb.toString();
- }
-
- static private void unparseSig(Class<?> t, StringBuilder sb) {
- char c = Wrapper.forBasicType(t).basicTypeChar();
- if (c != 'L') {
- sb.append(c);
- } else {
- boolean lsemi = (!t.isArray());
- if (lsemi) sb.append('L');
- sb.append(t.getName().replace('.', '/'));
- if (lsemi) sb.append(';');
- }
- }
-
-}
--- a/jdk/src/share/classes/sun/dyn/util/ValueConversions.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/util/ValueConversions.java Wed Jul 05 17:04:56 2017 +0200
@@ -27,7 +27,10 @@
import java.dyn.*;
import java.dyn.MethodHandles.Lookup;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.EnumMap;
+import java.util.List;
import sun.dyn.Access;
import sun.dyn.AdapterMethodHandle;
import sun.dyn.MethodHandleImpl;
@@ -37,6 +40,7 @@
private static final Lookup IMPL_LOOKUP = MethodHandleImpl.getLookup(IMPL_TOKEN);
private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
+ @SuppressWarnings("unchecked")
EnumMap<Wrapper, MethodHandle>[] caches
= (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n]; // unchecked warning expected here
for (int i = 0; i < n; i++)
@@ -114,7 +118,7 @@
}
private static MethodType unboxType(Wrapper wrap, boolean raw) {
- return MethodType.make(rawWrapper(wrap, raw).primitiveType(), wrap.wrapperType());
+ return MethodType.methodType(rawWrapper(wrap, raw).primitiveType(), wrap.wrapperType());
}
private static final EnumMap<Wrapper, MethodHandle>[]
@@ -240,7 +244,7 @@
private static MethodType boxType(Wrapper wrap, boolean raw) {
// be exact, since return casts are hard to compose
Class<?> boxType = wrap.wrapperType();
- return MethodType.make(boxType, rawWrapper(wrap, raw).primitiveType());
+ return MethodType.methodType(boxType, rawWrapper(wrap, raw).primitiveType());
}
private static Wrapper rawWrapper(Wrapper wrap, boolean raw) {
@@ -305,29 +309,47 @@
/// Kludges for when raw values get accidentally boxed.
+ static int unboxRawInteger(Object x) {
+ if (x instanceof Integer)
+ return unboxInteger(x);
+ else
+ return (int) unboxLong(x);
+ }
+
+ static Integer reboxRawInteger(Object x) {
+ if (x instanceof Integer)
+ return (Integer) x;
+ else
+ return (int) unboxLong(x);
+ }
+
static Byte reboxRawByte(Object x) {
if (x instanceof Byte) return (Byte) x;
- return boxByteRaw(unboxInteger(x));
+ return boxByteRaw(unboxRawInteger(x));
}
static Short reboxRawShort(Object x) {
if (x instanceof Short) return (Short) x;
- return boxShortRaw(unboxInteger(x));
+ return boxShortRaw(unboxRawInteger(x));
}
static Boolean reboxRawBoolean(Object x) {
if (x instanceof Boolean) return (Boolean) x;
- return boxBooleanRaw(unboxInteger(x));
+ return boxBooleanRaw(unboxRawInteger(x));
}
static Character reboxRawCharacter(Object x) {
if (x instanceof Character) return (Character) x;
- return boxCharacterRaw(unboxInteger(x));
+ return boxCharacterRaw(unboxRawInteger(x));
}
static Float reboxRawFloat(Object x) {
if (x instanceof Float) return (Float) x;
- return boxFloatRaw(unboxInteger(x));
+ return boxFloatRaw(unboxRawInteger(x));
+ }
+
+ static Long reboxRawLong(Object x) {
+ return (Long) x; //never a rebox
}
static Double reboxRawDouble(Object x) {
@@ -337,12 +359,21 @@
private static MethodType reboxType(Wrapper wrap) {
Class<?> boxType = wrap.wrapperType();
- return MethodType.make(boxType, Object.class);
+ return MethodType.methodType(boxType, Object.class);
}
private static final EnumMap<Wrapper, MethodHandle>[]
REBOX_CONVERSIONS = newWrapperCaches(2);
+ /**
+ * Becase we normalize primitive types to reduce the number of signatures,
+ * primitives are sometimes manipulated under an "erased" type,
+ * either int (for types other than long/double) or long (for all types).
+ * When the erased primitive value is then boxed into an Integer or Long,
+ * the final boxed primitive is sometimes required. This transformation
+ * is called a "rebox". It takes an Integer or Long and produces some
+ * other boxed value.
+ */
public static MethodHandle rebox(Wrapper wrap, boolean exact) {
EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[exact?1:0];
MethodHandle mh = cache.get(wrap);
@@ -355,9 +386,6 @@
mh = IDENTITY; break;
case VOID:
throw new IllegalArgumentException("cannot rebox a void");
- case INT: case LONG:
- mh = cast(wrap.wrapperType(), exact);
- break;
}
if (mh != null) {
cache.put(wrap, mh);
@@ -384,13 +412,21 @@
/// Width-changing conversions between int and long.
static long widenInt(int x) {
- return x;
+ return (long) x;
+ }
+
+ static Long widenBoxedInt(Integer x) {
+ return (long)(int)x;
}
static int narrowLong(long x) {
return (int) x;
}
+ static Integer narrowBoxedLong(Long x) {
+ return (int)(long) x;
+ }
+
/// Constant functions
static void ignore(Object x) {
@@ -432,7 +468,7 @@
return mh;
}
// slow path
- MethodType type = MethodType.make(wrap.primitiveType());
+ MethodType type = MethodType.methodType(wrap.primitiveType());
switch (wrap) {
case VOID:
mh = EMPTY;
@@ -500,11 +536,11 @@
private static final MethodHandle IDENTITY, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY;
static {
try {
- MethodType idType = MethodType.makeGeneric(1);
- MethodType castType = idType.insertParameterType(0, Class.class);
+ MethodType idType = MethodType.genericMethodType(1);
+ MethodType castType = idType.insertParameterTypes(0, Class.class);
MethodType alwaysZeroType = idType.changeReturnType(int.class);
MethodType ignoreType = idType.changeReturnType(void.class);
- MethodType zeroObjectType = MethodType.makeGeneric(0);
+ MethodType zeroObjectType = MethodType.genericMethodType(0);
IDENTITY = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", idType);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
CAST_REFERENCE = IMPL_LOOKUP.findStatic(ValueConversions.class, "castReference", castType);
@@ -512,7 +548,7 @@
ALWAYS_ZERO = IMPL_LOOKUP.findStatic(ValueConversions.class, "alwaysZero", alwaysZeroType);
ZERO_OBJECT = IMPL_LOOKUP.findStatic(ValueConversions.class, "zeroObject", zeroObjectType);
IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType);
- EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterType(0));
+ EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1));
} catch (RuntimeException ex) {
throw ex;
}
@@ -543,10 +579,10 @@
else if (VerifyType.isNullType(type))
mh = ALWAYS_NULL;
else
- mh = MethodHandles.insertArgument(CAST_REFERENCE, 0, type);
+ mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
if (exact) {
- MethodType xmt = MethodType.make(type, Object.class);
- mh = AdapterMethodHandle.makeRawRetypeOnly(IMPL_TOKEN, xmt, mh);
+ MethodType xmt = MethodType.methodType(type, Object.class);
+ mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
}
if (cache != null)
cache.put(wrap, mh);
@@ -560,4 +596,127 @@
private static MethodHandle retype(MethodType type, MethodHandle mh) {
return AdapterMethodHandle.makeRetypeOnly(IMPL_TOKEN, type, mh);
}
+
+ private static final Object[] NO_ARGS_ARRAY = {};
+ private static Object[] makeArray(Object... args) { return args; }
+ private static Object[] array() { return NO_ARGS_ARRAY; }
+ private static Object[] array(Object a0)
+ { return makeArray(a0); }
+ private static Object[] array(Object a0, Object a1)
+ { return makeArray(a0, a1); }
+ private static Object[] array(Object a0, Object a1, Object a2)
+ { return makeArray(a0, a1, a2); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3)
+ { return makeArray(a0, a1, a2, a3); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4)
+ { return makeArray(a0, a1, a2, a3, a4); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5)
+ { return makeArray(a0, a1, a2, a3, a4, a5); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ static MethodHandle[] makeArrays() {
+ ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = arrays.size();
+ MethodType type = MethodType.genericMethodType(nargs).changeReturnType(Object[].class);
+ String name = "array";
+ MethodHandle array = null;
+ try {
+ array = lookup.findStatic(ValueConversions.class, name, type);
+ } catch (NoAccessException ex) {
+ }
+ if (array == null) break;
+ arrays.add(array);
+ }
+ assert(arrays.size() == 11); // current number of methods
+ return arrays.toArray(new MethodHandle[0]);
+ }
+ static final MethodHandle[] ARRAYS = makeArrays();
+
+ /** Return a method handle that takes the indicated number of Object
+ * arguments and returns an Object array of them, as if for varargs.
+ */
+ public static MethodHandle varargsArray(int nargs) {
+ if (nargs < ARRAYS.length)
+ return ARRAYS[nargs];
+ // else need to spin bytecode or do something else fancy
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
+ private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
+ private static List<Object> list() { return NO_ARGS_LIST; }
+ private static List<Object> list(Object a0)
+ { return makeList(a0); }
+ private static List<Object> list(Object a0, Object a1)
+ { return makeList(a0, a1); }
+ private static List<Object> list(Object a0, Object a1, Object a2)
+ { return makeList(a0, a1, a2); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
+ { return makeList(a0, a1, a2, a3); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4)
+ { return makeList(a0, a1, a2, a3, a4); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5)
+ { return makeList(a0, a1, a2, a3, a4, a5); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ static MethodHandle[] makeLists() {
+ ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = arrays.size();
+ MethodType type = MethodType.genericMethodType(nargs).changeReturnType(List.class);
+ String name = "list";
+ MethodHandle array = null;
+ try {
+ array = lookup.findStatic(ValueConversions.class, name, type);
+ } catch (NoAccessException ex) {
+ }
+ if (array == null) break;
+ arrays.add(array);
+ }
+ assert(arrays.size() == 11); // current number of methods
+ return arrays.toArray(new MethodHandle[0]);
+ }
+ static final MethodHandle[] LISTS = makeLists();
+
+ /** Return a method handle that takes the indicated number of Object
+ * arguments and returns List.
+ */
+ public static MethodHandle varargsList(int nargs) {
+ if (nargs < LISTS.length)
+ return LISTS[nargs];
+ // else need to spin bytecode or do something else fancy
+ throw new UnsupportedOperationException("NYI");
+ }
}
+
--- a/jdk/src/share/classes/sun/dyn/util/VerifyAccess.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/util/VerifyAccess.java Wed Jul 05 17:04:56 2017 +0200
@@ -26,8 +26,12 @@
package sun.dyn.util;
import java.dyn.LinkagePermission;
+import java.dyn.MethodHandles.Lookup;
+import java.dyn.NoAccessException;
import java.lang.reflect.Modifier;
-import sun.dyn.Access;
+import sun.dyn.MemberName;
+import sun.dyn.MethodHandleImpl;
+import sun.dyn.empty.Empty;
/**
* This class centralizes information about the JVM's linkage access control.
@@ -45,21 +49,21 @@
* <p>
* Some circumstances require an additional check on the
* leading parameter (the receiver) of the method, if it is non-static.
- * In the case of {@code invokespecial} ({@code doDispatch} is false),
+ * In the case of {@code invokespecial} ({@code isSpecialInvoke} is true),
* the leading parameter must be the accessing class or a subclass.
* In the case of a call to a {@code protected} method outside the same
* package, the same constraint applies.
* @param m the proposed callee
- * @param doDispatch if false, a non-static m will be invoked as if by {@code invokespecial}
+ * @param isSpecialInvoke if true, a non-static method m is checked as if for {@code invokespecial}
* @param lookupClass the class for which the access check is being made
* @return null if the method is not accessible, else a receiver type constraint, else {@code Object.class}
*/
public static Class<?> isAccessible(Class<?> defc, int mods,
- boolean doDispatch, Class<?> lookupClass) {
+ Class<?> lookupClass, boolean isSpecialInvoke) {
if (!isAccessible(defc, lookupClass))
return null;
Class<?> constraint = Object.class;
- if (!doDispatch && !Modifier.isStatic(mods)) {
+ if (isSpecialInvoke && !Modifier.isStatic(mods)) {
constraint = lookupClass;
}
if (Modifier.isPublic(mods))
@@ -166,4 +170,38 @@
if (isSamePackage(requestingClass, subjectClass)) return;
security.checkPermission(new LinkagePermission(permissionName, requestingClass));
}
+
+ private static RuntimeException checkNameFailed(MemberName self, Lookup lookup, String comment) {
+ return new NoAccessException("cannot access from "+lookup+": "+self.toString()+": "+comment);
+ }
+ public static void checkName(MemberName self, Lookup lookup) {
+ Class<?> lc = lookup.lookupClass();
+ if (lc == null) return; // lookup is privileged
+ Class<?> dc = self.getDeclaringClass();
+ int samepkg = 0;
+ // First check the containing class. Must be public or local.
+ if (!Modifier.isPublic(dc.getModifiers())) {
+ if (lc != Empty.class)
+ samepkg = (isSamePackage(dc, lc) ? 1 : -1);
+ if (samepkg <= 0)
+ throw checkNameFailed(self, lookup, "class is not public");
+ }
+ // At this point dc is known to be accessible.
+ if (self.isPublic()) {
+ return;
+ } else if (lc == Empty.class) {
+ throw checkNameFailed(self, lookup, "member is not public");
+ } else if (self.isProtected()) {
+ if (dc.isAssignableFrom(lc)) return;
+ } else if (self.isPrivate()) {
+ if (isSamePackageMember(dc, lc)) return;
+ throw checkNameFailed(self, lookup, "member is private");
+ }
+ // Fall-through handles the package-private and protected cases.
+ if (samepkg == 0)
+ samepkg = (isSamePackage(dc, lc) ? 1 : -1);
+ if (samepkg > 0) return;
+ throw checkNameFailed(self, lookup,
+ self.isProtected() ? "member is protected" : "member is private to package");
+ }
}
--- a/jdk/src/share/classes/sun/dyn/util/VerifyType.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/util/VerifyType.java Wed Jul 05 17:04:56 2017 +0200
@@ -26,6 +26,7 @@
package sun.dyn.util;
import java.dyn.MethodType;
+import sun.dyn.empty.Empty;
/**
* This class centralizes information about the JVM verifier
@@ -73,29 +74,28 @@
}
/**
- * Is the given type either java.lang.Void or java.lang.Null?
- * These types serve as markers for bare nulls and therefore
- * may be promoted to any type. This is secure, since
+ * Is the given type java.lang.Null or an equivalent null-only type?
*/
public static boolean isNullType(Class<?> type) {
if (type == null) return false;
- return type == NULL_CLASS_1 || type == NULL_CLASS_2;
+ return type == NULL_CLASS
+ // This one may also be used as a null type.
+ // TO DO: Decide if we really want to legitimize it here.
+ // Probably we do, unless java.lang.Null really makes it into Java 7
+ //|| type == Void.class
+ // Locally known null-only class:
+ || type == Empty.class
+ ;
}
- private static final Class<?> NULL_CLASS_1, NULL_CLASS_2;
+ private static final Class<?> NULL_CLASS;
static {
- Class<?> nullClass1 = null, nullClass2 = null;
+ Class<?> nullClass = null;
try {
- nullClass1 = Class.forName("java.lang.Null");
+ nullClass = Class.forName("java.lang.Null");
} catch (ClassNotFoundException ex) {
// OK, we'll cope
}
- NULL_CLASS_1 = nullClass1;
-
- // This one may also be used as a null type.
- // TO DO: Decide if we really want to legitimize it here.
- // Probably we do, unless java.lang.Null really makes it into Java 7
- nullClass2 = Void.class;
- NULL_CLASS_2 = nullClass2;
+ NULL_CLASS = nullClass;
}
/**
@@ -191,6 +191,11 @@
// to be captured as a garbage int.
// Caller promises that the actual value will be disregarded.
return dst == int.class ? 1 : 0;
+ if (isNullType(src))
+ // Special permission for raw conversions: allow a null
+ // to be reinterpreted as anything. For objects, it is safe,
+ // and for primitives you get a garbage value (probably zero).
+ return 1;
if (!src.isPrimitive())
return 0;
Wrapper sw = Wrapper.forPrimitiveType(src);
--- a/jdk/src/share/classes/sun/dyn/util/Wrapper.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/dyn/util/Wrapper.java Wed Jul 05 17:04:56 2017 +0200
@@ -141,13 +141,19 @@
* @throws IllegalArgumentException for unexpected types
*/
public static Wrapper forPrimitiveType(Class<?> type) {
+ Wrapper w = findPrimitiveType(type);
+ if (w != null) return w;
+ if (type.isPrimitive())
+ throw new InternalError(); // redo hash function
+ throw newIllegalArgumentException("not primitive: "+type);
+ }
+
+ static Wrapper findPrimitiveType(Class<?> type) {
Wrapper w = FROM_PRIM[hashPrim(type)];
if (w != null && w.primitiveType == type) {
return w;
}
- if (type.isPrimitive())
- throw new InternalError(); // redo hash function
- throw newIllegalArgumentException("not primitive: "+type);
+ return null;
}
/** Return the wrapper that wraps values into the given wrapper type.
@@ -160,7 +166,7 @@
Wrapper w = findWrapperType(type);
if (w != null) return w;
for (Wrapper x : values())
- if (w.wrapperType == type)
+ if (x.wrapperType == type)
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not wrapper: "+type);
}
@@ -244,8 +250,10 @@
public Class<?> wrapperType() { return wrapperType; }
/** What is the wrapper type for this wrapper?
- * The example type must be the wrapper type,
+ * Otherwise, the example type must be the wrapper type,
* or the corresponding primitive type.
+ * (For {@code OBJECT}, the example type can be any non-primitive,
+ * and is normalized to {@code Object.class}.)
* The resulting class type has the same type parameter.
*/
public <T> Class<T> wrapperType(Class<T> exampleType) {
@@ -290,6 +298,16 @@
return type.isPrimitive();
}
+ /** What is the bytecode signature character for this type?
+ * All non-primitives, including array types, report as 'L', the signature character for references.
+ */
+ public static char basicTypeChar(Class<?> type) {
+ if (!type.isPrimitive())
+ return 'L';
+ else
+ return forPrimitiveType(type).basicTypeChar();
+ }
+
/** What is the bytecode signature character for this wrapper's
* primitive type?
*/
@@ -309,7 +327,7 @@
/** Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
* Performs standard primitive conversions, including truncation and float conversions.
* The given type must be compatible with this wrapper. That is, it must either
- * be the wrapper type (or a subtype, in the case of {@code OBJECT} or else
+ * be the wrapper type (or a subtype, in the case of {@code OBJECT}) or else
* it must be the wrapper's primitive type.
* @throws ClassCastException if the given type is not compatible with this wrapper
*/
@@ -326,9 +344,17 @@
* If the target type is a primitive, change it to a wrapper.
*/
static <T> Class<T> forceType(Class<?> type, Class<T> exampleType) {
+ boolean z = (type == exampleType ||
+ type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
+ exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
+ type == Object.class && !exampleType.isPrimitive());
+ if (!z)
+ System.out.println(type+" <= "+exampleType);
assert(type == exampleType ||
- type == asWrapperType(exampleType) ||
- type == Object.class && exampleType.isInterface());
+ type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
+ exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
+ type == Object.class && !exampleType.isPrimitive());
+ @SuppressWarnings("unchecked")
Class<T> result = (Class<T>) type; // unchecked warning is expected here
return result;
}
--- a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -89,6 +89,11 @@
Oid[] retVal = new Oid[mechs.length];
int pos = 0;
+ // Compatibility with RFC 2853 old NT_HOSTBASED_SERVICE value.
+ if (nameType.equals(GSSNameImpl.oldHostbasedServiceName)) {
+ nameType = GSSName.NT_HOSTBASED_SERVICE;
+ }
+
// Iterate thru all mechs in GSS
for (int i = 0; i < mechs.length; i++) {
// what nametypes does this mech support?
--- a/jdk/src/share/classes/sun/security/jgss/GSSNameImpl.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/GSSNameImpl.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -81,6 +81,29 @@
public class GSSNameImpl implements GSSName {
+ /**
+ * The old Oid used in RFC 2853. Now supported as
+ * input parameters in:
+ *
+ * 1. The four overloaded GSSManager.createName(*) methods
+ * 2. GSSManager.getMechsForName(Oid)
+ *
+ * Note that even if a GSSName is created with this old Oid,
+ * its internal name type and getStringNameType() output are
+ * always the new value.
+ */
+ final static Oid oldHostbasedServiceName;
+
+ static {
+ Oid tmp = null;
+ try {
+ tmp = new Oid("1.3.6.1.5.6.2");
+ } catch (Exception e) {
+ // should never happen
+ }
+ oldHostbasedServiceName = tmp;
+ }
+
private GSSManagerImpl gssManager = null;
/*
@@ -134,6 +157,9 @@
Oid mech)
throws GSSException {
+ if (oldHostbasedServiceName.equals(appNameType)) {
+ appNameType = GSSName.NT_HOSTBASED_SERVICE;
+ }
if (appName == null)
throw new GSSExceptionImpl(GSSException.BAD_NAME,
"Cannot import null name");
--- a/jdk/src/share/classes/sun/security/jgss/GSSUtil.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/GSSUtil.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,9 +66,6 @@
public static final Oid NT_GSS_KRB5_PRINCIPAL =
GSSUtil.createOid("1.2.840.113554.1.2.2.1");
- public static final Oid NT_HOSTBASED_SERVICE2 =
- GSSUtil.createOid("1.2.840.113554.1.2.1.4");
-
private static final String DEFAULT_HANDLER =
"auth.login.defaultCallbackHandler";
--- a/jdk/src/share/classes/sun/security/jgss/wrapper/GSSNameElement.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/wrapper/GSSNameElement.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Sun Microsystems, Inc. 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 @@
static final GSSNameElement DEF_ACCEPTOR = new GSSNameElement();
private static Oid getNativeNameType(Oid nameType, GSSLibStub stub) {
- if (GSSUtil.NT_GSS_KRB5_PRINCIPAL.equals(nameType) ||
- GSSName.NT_HOSTBASED_SERVICE.equals(nameType)) {
+ if (GSSUtil.NT_GSS_KRB5_PRINCIPAL.equals(nameType)) {
Oid[] supportedNTs = null;
try {
supportedNTs = stub.inquireNamesForMech();
@@ -83,15 +82,9 @@
if (supportedNTs[i].equals(nameType)) return nameType;
}
// Special handling the specified name type
- if (GSSUtil.NT_GSS_KRB5_PRINCIPAL.equals(nameType)) {
- SunNativeProvider.debug("Override " + nameType +
- " with mechanism default(null)");
- return null; // Use mechanism specific default
- } else {
- SunNativeProvider.debug("Override " + nameType +
- " with " + GSSUtil.NT_HOSTBASED_SERVICE2);
- return GSSUtil.NT_HOSTBASED_SERVICE2;
- }
+ SunNativeProvider.debug("Override " + nameType +
+ " with mechanism default(null)");
+ return null; // Use mechanism specific default
}
}
return nameType;
--- a/jdk/src/share/classes/sun/security/krb5/Config.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java Wed Jul 05 17:04:56 2017 +0200
@@ -109,6 +109,7 @@
public static synchronized void refresh() throws KrbException {
singleton = new Config();
KeyTab.refresh();
+ KrbKdcReq.KdcAccessibility.reset();
}
--- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Wed Jul 05 17:04:56 2017 +0200
@@ -512,6 +512,23 @@
}
/**
+ * Determines if a kvno matches another kvno. Used in the method
+ * findKey(type, kvno, keys). Always returns true if either input
+ * is null or zero, in case any side does not have kvno info available.
+ *
+ * Note: zero is included because N/A is not a legal value for kvno
+ * in javax.security.auth.kerberos.KerberosKey. Therefore, the info
+ * that the kvno is N/A might be lost when converting between this
+ * class and KerberosKey.
+ */
+ private static boolean versionMatches(Integer v1, Integer v2) {
+ if (v1 == null || v1 == 0 || v2 == null || v2 == 0) {
+ return true;
+ }
+ return v1.equals(v2);
+ }
+
+ /**
* Find a key with given etype and kvno
* @param kvno if null, return any (first?) key
*/
@@ -525,15 +542,20 @@
}
int ktype;
+ boolean etypeFound = false;
for (int i = 0; i < keys.length; i++) {
ktype = keys[i].getEType();
if (EType.isSupported(ktype)) {
Integer kv = keys[i].getKeyVersionNumber();
- if (etype == ktype && (kvno == null || kvno.equals(kv))) {
- return keys[i];
+ if (etype == ktype) {
+ etypeFound = true;
+ if (versionMatches(kvno, kv)) {
+ return keys[i];
+ }
}
}
}
+
// Key not found.
// allow DES key to be used for the DES etypes
if ((etype == EncryptedData.ETYPE_DES_CBC_CRC ||
@@ -543,12 +565,16 @@
if (ktype == EncryptedData.ETYPE_DES_CBC_CRC ||
ktype == EncryptedData.ETYPE_DES_CBC_MD5) {
Integer kv = keys[i].getKeyVersionNumber();
- if (kvno == null || kvno.equals(kv)) {
+ etypeFound = true;
+ if (versionMatches(kvno, kv)) {
return new EncryptionKey(etype, keys[i].getBytes());
}
}
}
}
+ if (etypeFound) {
+ throw new KrbException(Krb5.KRB_AP_ERR_BADKEYVER);
+ }
return null;
}
}
--- a/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java Wed Jul 05 17:04:56 2017 +0200
@@ -31,25 +31,26 @@
package sun.security.krb5;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.util.Locale;
import sun.security.krb5.internal.Krb5;
import sun.security.krb5.internal.UDPClient;
import sun.security.krb5.internal.TCPClient;
import java.io.IOException;
-import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
import java.util.StringTokenizer;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
public abstract class KrbKdcReq {
- /**
- * Default port for a KDC.
- */
- private static final int DEFAULT_KDC_PORT = Krb5.KDC_INET_DEFAULT_PORT;
-
// Currently there is no option to specify retries
// in the kerberos configuration file
@@ -66,7 +67,48 @@
private static int udpPrefLimit = -1;
+ private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy";
+
+ /**
+ * What to do when a KDC is unavailable, specified in the
+ * java.security file with key krb5.kdc.bad.policy.
+ * Possible values can be TRY_LAST or TRY_LESS
+ */
+ private enum BpType {
+ NONE, TRY_LAST, TRY_LESS
+ }
+ private static int tryLessMaxRetries = 1;
+ private static int tryLessTimeout = 5000;
+
+ private static final BpType badPolicy;
+
static {
+ String value = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ public String run() {
+ return Security.getProperty(BAD_POLICY_KEY);
+ }
+ });
+ if (value != null) {
+ value = value.toLowerCase(Locale.ENGLISH);
+ String[] ss = value.split(":");
+ if ("tryless".equals(ss[0])) {
+ if (ss.length > 1) {
+ String[] params = ss[1].split(",");
+ tryLessMaxRetries = Integer.parseInt(params[0]);
+ if (params.length > 1) {
+ tryLessTimeout = Integer.parseInt(params[1]);
+ }
+ }
+ badPolicy = BpType.TRY_LESS;
+ } else if ("trylast".equals(ss[0])) {
+ badPolicy = BpType.TRY_LAST;
+ } else {
+ badPolicy = BpType.NONE;
+ }
+ } else {
+ badPolicy = BpType.NONE;
+ }
/*
* Get default timeout.
@@ -131,22 +173,16 @@
}
}
- /*
- * Get timeout.
- */
-
- int timeout = getKdcTimeout(realm);
-
String kdcList = cfg.getKDCList(realm);
if (kdcList == null) {
throw new KrbException("Cannot get kdc for realm " + realm);
}
String tempKdc = null; // may include the port number also
- StringTokenizer st = new StringTokenizer(kdcList);
- while (st.hasMoreTokens()) {
- tempKdc = st.nextToken();
+ for (String tmp: KdcAccessibility.list(kdcList)) {
+ tempKdc = tmp;
try {
send(realm,tempKdc,useTCP);
+ KdcAccessibility.removeBad(tempKdc);
break;
} catch (Exception e) {
if (DEBUG) {
@@ -154,6 +190,7 @@
tempKdc);
e.printStackTrace(System.out);
}
+ KdcAccessibility.addBad(tempKdc);
savedException = e;
}
}
@@ -174,16 +211,21 @@
if (obuf == null)
return;
- PrivilegedActionException savedException = null;
+
int port = Krb5.KDC_INET_DEFAULT_PORT;
+ int retries = DEFAULT_KDC_RETRY_LIMIT;
+ int timeout = getKdcTimeout(realm);
- /*
- * Get timeout.
- */
- int timeout = getKdcTimeout(realm);
- /*
- * Get port number for this KDC.
- */
+ if (badPolicy == BpType.TRY_LESS &&
+ KdcAccessibility.isBad(tempKdc)) {
+ if (retries > tryLessMaxRetries) {
+ retries = tryLessMaxRetries; // less retries
+ }
+ if (timeout > tryLessTimeout) {
+ timeout = tryLessTimeout; // less time
+ }
+ }
+
String kdc = null;
String portStr = null;
@@ -225,12 +267,12 @@
+ port + ", timeout="
+ timeout
+ ", number of retries ="
- + DEFAULT_KDC_RETRY_LIMIT
+ + retries
+ ", #bytes=" + obuf.length);
}
KdcCommunication kdcCommunication =
- new KdcCommunication(kdc, port, useTCP, timeout, obuf);
+ new KdcCommunication(kdc, port, useTCP, timeout, retries, obuf);
try {
ibuf = AccessController.doPrivileged(kdcCommunication);
if (DEBUG) {
@@ -258,14 +300,16 @@
private int port;
private boolean useTCP;
private int timeout;
+ private int retries;
private byte[] obuf;
public KdcCommunication(String kdc, int port, boolean useTCP,
- int timeout, byte[] obuf) {
+ int timeout, int retries, byte[] obuf) {
this.kdc = kdc;
this.port = port;
this.useTCP = useTCP;
this.timeout = timeout;
+ this.retries = retries;
this.obuf = obuf;
}
@@ -294,7 +338,7 @@
} else {
// For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to
// get the response
- for (int i=1; i <= DEFAULT_KDC_RETRY_LIMIT; i++) {
+ for (int i=1; i <= retries; i++) {
UDPClient kdcClient = new UDPClient(kdc, port, timeout);
if (DEBUG) {
@@ -310,7 +354,7 @@
* Send the data to the kdc.
*/
- kdcClient.send(obuf);
+ kdcClient.send(obuf);
/*
* And get a response.
@@ -323,7 +367,7 @@
System.out.println ("SocketTimeOutException with " +
"attempt: " + i);
}
- if (i == DEFAULT_KDC_RETRY_LIMIT) {
+ if (i == retries) {
ibuf = null;
throw se;
}
@@ -385,4 +429,67 @@
return -1;
}
+
+ /**
+ * Maintains a KDC accessible list. Unavailable KDCs are put into a
+ * blacklist, when a KDC in the blacklist is available, it's removed
+ * from there. No insertion order in the blacklist.
+ *
+ * There are two methods to deal with KDCs in the blacklist. 1. Only try
+ * them when there's no KDC not on the blacklist. 2. Still try them, but
+ * with lesser number of retries and smaller timeout value.
+ */
+ static class KdcAccessibility {
+ // Known bad KDCs
+ private static Set<String> bads = new HashSet<String>();
+
+ private static synchronized void addBad(String kdc) {
+ if (DEBUG) {
+ System.out.println(">>> KdcAccessibility: add " + kdc);
+ }
+ bads.add(kdc);
+ }
+
+ private static synchronized void removeBad(String kdc) {
+ if (DEBUG) {
+ System.out.println(">>> KdcAccessibility: remove " + kdc);
+ }
+ bads.remove(kdc);
+ }
+
+ private static synchronized boolean isBad(String kdc) {
+ return bads.contains(kdc);
+ }
+
+ public static synchronized void reset() {
+ if (DEBUG) {
+ System.out.println(">>> KdcAccessibility: reset");
+ }
+ bads.clear();
+ }
+
+ // Returns a preferred KDC list by putting the bad ones at the end
+ private static synchronized String[] list(String kdcList) {
+ StringTokenizer st = new StringTokenizer(kdcList);
+ List<String> list = new ArrayList<String>();
+ if (badPolicy == BpType.TRY_LAST) {
+ List<String> badkdcs = new ArrayList<String>();
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ if (bads.contains(t)) badkdcs.add(t);
+ else list.add(t);
+ }
+ // Bad KDCs are put at last
+ list.addAll(badkdcs);
+ } else {
+ // All KDCs are returned in their original order,
+ // This include TRY_LESS and NONE
+ while (st.hasMoreTokens()) {
+ list.add(st.nextToken());
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ }
+ }
}
+
--- a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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,11 +50,12 @@
import sun.security.krb5.internal.crypto.KeyUsage;
import sun.security.jgss.krb5.Krb5Util;
+import sun.security.krb5.KrbException;
+import sun.security.krb5.internal.Krb5;
import sun.security.ssl.Debug;
import sun.security.ssl.HandshakeInStream;
import sun.security.ssl.HandshakeOutStream;
-import sun.security.ssl.KerberosClientKeyExchange;
import sun.security.ssl.ProtocolVersion;
/**
@@ -188,7 +189,14 @@
// See if we have the right key to decrypt the ticket to get
// the session key.
int encPartKeyType = encPart.getEType();
- KerberosKey dkey = findKey(encPartKeyType, serverKeys);
+ Integer encPartKeyVersion = encPart.getKeyVersionNumber();
+ KerberosKey dkey = null;
+ try {
+ dkey = findKey(encPartKeyType, encPartKeyVersion, serverKeys);
+ } catch (KrbException ke) { // a kvno mismatch
+ throw new IOException(
+ "Cannot find key matching version number", ke);
+ }
if (dkey == null) {
// %%% Should print string repr of etype
throw new IOException(
@@ -355,12 +363,34 @@
return localPrincipal;
}
- private static KerberosKey findKey(int etype, KerberosKey[] keys) {
+ /**
+ * Determines if a kvno matches another kvno. Used in the method
+ * findKey(etype, version, keys). Always returns true if either input
+ * is null or zero, in case any side does not have kvno info available.
+ *
+ * Note: zero is included because N/A is not a legal value for kvno
+ * in javax.security.auth.kerberos.KerberosKey. Therefore, the info
+ * that the kvno is N/A might be lost when converting between
+ * EncryptionKey and KerberosKey.
+ */
+ private static boolean versionMatches(Integer v1, int v2) {
+ if (v1 == null || v1 == 0 || v2 == 0) {
+ return true;
+ }
+ return v1.equals(v2);
+ }
+
+ private static KerberosKey findKey(int etype, Integer version,
+ KerberosKey[] keys) throws KrbException {
int ktype;
+ boolean etypeFound = false;
for (int i = 0; i < keys.length; i++) {
ktype = keys[i].getKeyType();
if (etype == ktype) {
- return keys[i];
+ etypeFound = true;
+ if (versionMatches(version, keys[i].getVersionNumber())) {
+ return keys[i];
+ }
}
}
// Key not found.
@@ -370,14 +400,20 @@
for (int i = 0; i < keys.length; i++) {
ktype = keys[i].getKeyType();
if (ktype == EncryptedData.ETYPE_DES_CBC_CRC ||
- ktype == EncryptedData.ETYPE_DES_CBC_MD5) {
- return new KerberosKey(keys[i].getPrincipal(),
- keys[i].getEncoded(),
- etype,
- keys[i].getVersionNumber());
+ ktype == EncryptedData.ETYPE_DES_CBC_MD5) {
+ etypeFound = true;
+ if (versionMatches(version, keys[i].getVersionNumber())) {
+ return new KerberosKey(keys[i].getPrincipal(),
+ keys[i].getEncoded(),
+ etype,
+ keys[i].getVersionNumber());
+ }
}
}
}
+ if (etypeFound) {
+ throw new KrbException(Krb5.KRB_AP_ERR_BADKEYVER);
+ }
return null;
}
}
--- a/jdk/src/share/lib/security/java.security Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/lib/security/java.security Wed Jul 05 17:04:56 2017 +0200
@@ -55,10 +55,10 @@
#
# Select the source of seed data for SecureRandom. By default an
-# attempt is made to use the entropy gathering device specified by
+# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
-# accessing the URL then the traditional system/thread activity
-# algorithm is used.
+# accessing the URL then the traditional system/thread activity
+# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
@@ -72,7 +72,7 @@
# The entropy gathering device is described as a URL and can also
# be specified with the system property "java.security.egd". For example,
# -Djava.security.egd=file:/dev/urandom
-# Specifying this system property will override the securerandom.source
+# Specifying this system property will override the securerandom.source
# setting.
#
@@ -149,7 +149,7 @@
security.overridePropertiesFile=true
#
-# Determines the default key and trust manager factory algorithms for
+# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=SunX509
@@ -168,10 +168,10 @@
# is to cache for 30 seconds.
#
# NOTE: setting this to anything other than the default value can have
-# serious security implications. Do not set it unless
+# serious security implications. Do not set it unless
# you are sure you are not exposed to DNS spoofing attack.
#
-#networkaddress.cache.ttl=-1
+#networkaddress.cache.ttl=-1
# The Java-level namelookup cache policy for failed lookups:
#
@@ -183,7 +183,7 @@
# the WINS name service in addition to DNS, name service lookups
# that fail may take a noticeably long time to return (approx. 5 seconds).
# For this reason the default caching policy is to maintain these
-# results for 10 seconds.
+# results for 10 seconds.
#
#
networkaddress.cache.negative.ttl=10
@@ -192,7 +192,7 @@
# Properties to configure OCSP for certificate revocation checking
#
-# Enable OCSP
+# Enable OCSP
#
# By default, OCSP is not used for certificate revocation checking.
# This property enables the use of OCSP when set to the value "true".
@@ -201,7 +201,7 @@
#
# Example,
# ocsp.enable=true
-
+
#
# Location of the OCSP responder
#
@@ -213,15 +213,15 @@
#
# Example,
# ocsp.responderURL=http://ocsp.example.net:80
-
+
#
# Subject name of the OCSP responder's certificate
#
# By default, the certificate of the OCSP responder is that of the issuer
# of the certificate being validated. This property identifies the certificate
-# of the OCSP responder when the default does not apply. Its value is a string
-# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. In cases where
+# of the OCSP responder when the default does not apply. Its value is a string
+# distinguished name (defined in RFC 2253) which identifies a certificate in
+# the set of certificates supplied during cert path validation. In cases where
# the subject name alone is not sufficient to uniquely identify the certificate
# then both the "ocsp.responderCertIssuerName" and
# "ocsp.responderCertSerialNumber" properties must be used instead. When this
@@ -237,14 +237,14 @@
# of the certificate being validated. This property identifies the certificate
# of the OCSP responder when the default does not apply. Its value is a string
# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. When this
-# property is set then the "ocsp.responderCertSerialNumber" property must also
-# be set. When the "ocsp.responderCertSubjectName" property is set then this
+# the set of certificates supplied during cert path validation. When this
+# property is set then the "ocsp.responderCertSerialNumber" property must also
+# be set. When the "ocsp.responderCertSubjectName" property is set then this
# property is ignored.
#
# Example,
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
-
+
#
# Serial number of the OCSP responder's certificate
#
@@ -259,4 +259,31 @@
#
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
-
+
+#
+# Policy for failed Kerberos KDC lookups:
+#
+# When a KDC is unavailable (network error, service failure, etc), it is
+# put inside a blacklist and accessed less often for future requests. The
+# value (case-insensitive) for this policy can be:
+#
+# tryLast
+# KDCs in the blacklist are always tried after those not on the list.
+#
+# tryLess[:max_retries,timeout]
+# KDCs in the blacklist are still tried by their order in the configuration,
+# but with smaller max_retries and timeout values. max_retries and timeout
+# are optional numerical parameters (default 1 and 5000, which means once
+# and 5 seconds). Please notes that if any of the values defined here is
+# more than what is defined in krb5.conf, it will be ignored.
+#
+# Whenever a KDC is detected as available, it is removed from the blacklist.
+# The blacklist is reset when krb5.conf is reloaded. You can add
+# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
+# reloaded whenever a JAAS authentication is attempted.
+#
+# Example,
+# krb5.kdc.bad.policy = tryLast
+# krb5.kdc.bad.policy = tryLess:2,2000
+krb5.kdc.bad.policy = tryLast
+
--- a/jdk/src/share/native/java/lang/StrictMath.c Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/share/native/java/lang/StrictMath.c Wed Jul 05 17:04:56 2017 +0200
@@ -95,18 +95,6 @@
}
JNIEXPORT jdouble JNICALL
-Java_java_lang_StrictMath_ceil(JNIEnv *env, jclass unused, jdouble d)
-{
- return (jdouble) jceil((double)d);
-}
-
-JNIEXPORT jdouble JNICALL
-Java_java_lang_StrictMath_floor(JNIEnv *env, jclass unused, jdouble d)
-{
- return (jdouble) jfloor((double)d);
-}
-
-JNIEXPORT jdouble JNICALL
Java_java_lang_StrictMath_atan2(JNIEnv *env, jclass unused, jdouble d1, jdouble d2)
{
return (jdouble) jatan2((double)d1, (double)d2);
--- a/jdk/src/windows/native/java/net/SocketInputStream.c Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/src/windows/native/java/net/SocketInputStream.c Wed Jul 05 17:04:56 2017 +0200
@@ -121,6 +121,9 @@
newfd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
if (newfd == -1) {
NET_ThrowSocketException(env, "Socket Closed");
+ if (bufP != BUF) {
+ free(bufP);
+ }
return -1;
}
}
--- a/jdk/test/Makefile Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/Makefile Wed Jul 05 17:04:56 2017 +0200
@@ -291,7 +291,7 @@
fi ; \
testExitCode=`$(CAT) $(EXITCODE)`; \
$(ECHO) "EXIT CODE: $${testExitCode}"; \
- exit ${testExitCode}
+ exit $${testExitCode}
BUNDLE_UP_AND_EXIT = \
( \
@@ -300,7 +300,7 @@
$(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
$(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
if [ -r "$${_summary}" ] ; then \
- $(ECHO) "Summary: $${_summary}" > $(STATS_TXT); \
+ $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
$(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
$(EGREP) ' Passed\.' $(RUNLIST) \
| $(EGREP) -v ' Error\.' \
@@ -370,7 +370,8 @@
endif
# With samevm, you cannot use -javaoptions?
ifeq ($(USE_JTREG_SAMEVM),true)
- EXTRA_JTREG_OPTIONS += -samevm $(JAVA_ARGS) $(JAVA_ARGS:%=-vmoption:%)
+ JTREG_SAMEVM_OPTION = -samevm
+ EXTRA_JTREG_OPTIONS += $(JTREG_SAMEVM_OPTION) $(JAVA_ARGS) $(JAVA_ARGS:%=-vmoption:%)
JTREG_TEST_OPTIONS = $(JAVA_VM_ARGS:%=-vmoption:%)
else
JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
@@ -418,8 +419,9 @@
$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests
endef
define SummaryInfo
-$(ECHO) "Summary for: $?"
+$(ECHO) "########################################################"
$(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME))
+$(ECHO) "########################################################"
endef
# ------------------------------------------------------------------
@@ -446,10 +448,14 @@
jdk_beans2: java/beans/Beans java/beans/EventHandler java/beans/XMLDecoder \
java/beans/PropertyEditor
$(call RunOthervmBatch)
+
+# Stable othervm testruns (minus items from PROBLEM_LIST)
+# Using samevm has serious problems with these tests
JDK_ALL_TARGETS += jdk_beans3
jdk_beans3: java/beans/XMLEncoder
$(call RunOthervmBatch)
+# All beans tests
jdk_beans: jdk_beans1 jdk_beans2 jdk_beans3
@$(SummaryInfo)
@@ -475,6 +481,7 @@
jdk_management2: com/sun/jmx com/sun/management sun/management
$(call RunOthervmBatch)
+# All management tests
jdk_management: jdk_management1 jdk_management2
@$(SummaryInfo)
@@ -506,10 +513,14 @@
jdk_nio2: java/nio/Buffer java/nio/ByteOrder \
java/nio/channels java/nio/BufferPoolMXBean java/nio/MappedByteBuffer
$(call RunOthervmBatch)
+
+# Stable othervm testruns (minus items from PROBLEM_LIST)
+# Using samevm has serious problems with these tests
JDK_ALL_TARGETS += jdk_nio3
jdk_nio3: com/sun/nio sun/nio
$(call RunOthervmBatch)
+# All nio tests
jdk_nio: jdk_nio1 jdk_nio2 jdk_nio3
@$(SummaryInfo)
@@ -529,10 +540,14 @@
JDK_ALL_TARGETS += jdk_security2
jdk_security2: javax/crypto com/sun/crypto
$(call RunOthervmBatch)
+
+# Stable othervm testruns (minus items from PROBLEM_LIST)
+# Using samevm has serious problems with these tests
JDK_ALL_TARGETS += jdk_security3
jdk_security3: com/sun/security lib/security javax/security sun/security
$(call RunOthervmBatch)
+# All security tests
jdk_security: jdk_security1 jdk_security2 jdk_security3
@$(SummaryInfo)
@@ -547,15 +562,18 @@
jdk_text: java/text sun/text
$(call RunSamevmBatch)
-# Stable othervm testruns (minus items from PROBLEM_LIST)
-# Using samevm has serious problems with these tests
+# Stable samevm testruns (minus items from PROBLEM_LIST)
JDK_ALL_TARGETS += jdk_tools1
jdk_tools1: com/sun/jdi
$(call RunSamevmBatch)
+
+# Stable othervm testruns (minus items from PROBLEM_LIST)
+# Using samevm has serious problems with these tests
JDK_ALL_TARGETS += jdk_tools2
jdk_tools2: com/sun/tools sun/jvmstat sun/tools tools vm com/sun/servicetag com/sun/tracing
$(call RunOthervmBatch)
+# All tools tests
jdk_tools: jdk_tools1 jdk_tools2
@$(SummaryInfo)
@@ -567,7 +585,9 @@
# ------------------------------------------------------------------
# Run all tests
-jdk_all: $(filter-out jdk_awt jdk_rmi jdk_swing, $(JDK_ALL_TARGETS))
+FILTER_OUT_LIST=jdk_awt jdk_rmi jdk_swing
+JDK_ALL_STABLE_TARGETS := $(filter-out $(FILTER_OUT_LIST), $(JDK_ALL_TARGETS))
+jdk_all: $(JDK_ALL_STABLE_TARGETS)
@$(SummaryInfo)
# These are all phony targets
@@ -581,16 +601,22 @@
JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
# Only run automatic tests
JTREG_BASIC_OPTIONS += -a
+# Always turn on assertions
+JTREG_ASSERT_OPTION = -ea -esa
+JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION)
# Report details on all failed or error tests, times too
JTREG_BASIC_OPTIONS += -v:fail,error,time
# Retain all files for failing tests
JTREG_BASIC_OPTIONS += -retain:fail,error
# Ignore tests are not run and completely silent about it
-JTREG_BASIC_OPTIONS += -ignore:quiet
-# Multiple by 2 the timeout numbers
-JTREG_BASIC_OPTIONS += -timeoutFactor:2
+JTREG_IGNORE_OPTION = -ignore:quiet
+JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
+# Multiple by 4 the timeout numbers
+JTREG_TIMEOUT_OPTION = -timeoutFactor:4
+JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
# Boost the max memory for jtreg to avoid gc thrashing
-JTREG_BASIC_OPTIONS += -J-Xmx512m
+JTREG_MEMORY_OPTION = -J-Xmx512m
+JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
# Make sure jtreg exists
$(JTREG): $(JT_HOME)
--- a/jdk/test/ProblemList.txt Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/ProblemList.txt Wed Jul 05 17:04:56 2017 +0200
@@ -431,6 +431,11 @@
# jdk_management
+# 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
@@ -494,10 +499,6 @@
# Problems with rounding add failures on solaris-sparcv9 and -server
java/math/BigDecimal/AddTests.java solaris-sparcv9
-# Problems on windows with samevm, missing inputstream close()?
-# Also times out on solaris-sparcv9 -server
-java/math/BigInteger/BigIntegerTest.java generic-all
-
# Should be samevm? But seems problematic with samevm on windows
java/math/BigInteger/ModPow65537.java generic-all
@@ -581,6 +582,14 @@
# Suspect many of these tests auffer from using fixed ports, no concrete
# evidence.
+# Dies on Solaris 10 sparc and sparcv9, Linux -ea -esa with
+# Interrupted or IO exception, maybe writing to non-unique named file?
+com/sun/net/httpserver/bugs/B6373555.java generic-all
+
+# Dies on pretty much all platforms when run with -ea -esa, Assertion error
+java/net/CookieHandler/TestHttpCookie.java generic-all
+java/net/URLClassLoader/closetest/CloseTest.java generic-all
+
# Fails on OpenSolaris, BindException unexpected
java/net/BindException/Test.java generic-all
@@ -717,6 +726,9 @@
# Connection refused, windows samevm
sun/net/www/protocol/http/DigestTest.java generic-all
+# Fails on Fedora 9 32bit & 64bit & Solaris 10, wrong proxy for http://localhost/index.html
+java/net/ProxySelector/B6737819.java generic-all
+
############################################################################
# jdk_nio
@@ -724,6 +736,33 @@
# Suspect many of these tests auffer from using fixed ports, no concrete
# evidence.
+# Fails with -ea -esa, Assertion error, but only on Solaris 10 machines?
+com/sun/nio/sctp/SctpChannel/Send.java generic-all
+com/sun/nio/sctp/SctpChannel/Shutdown.java generic-all
+
+# Fails on Windows 2000, Can't delete test directory .\x.SetLastModified.dir
+# at SetLastModified.main(SetLastModified.java:107)
+java/io/File/SetLastModified.java generic-all
+
+# Fails on Solaris 10 x64, address already in use
+java/nio/channels/DatagramChannel/SRTest.java generic-all
+
+# Fails on Solaris 10 x86, times out
+java/nio/channels/DatagramChannel/Sender.java generic-all
+
+# Fails on Fedora 9 x86, address in use
+java/nio/channels/Selector/SelectWrite.java generic-all
+
+# Fails on Fedora 9 32bit times out
+java/nio/channels/DatagramChannel/EmptyBuffer.java generic-all
+
+# Fails on Windows 2000, ExceptionInInitializerError
+# in WindowsAsynchronousServerSocketChannelImpl.java:316
+java/nio/channels/AsynchronousChannelGroup/Unbounded.java generic-all
+
+# Fails on Windows 2000, times out
+java/nio/channels/FileChannel/Transfer.java generic-all
+
# Fails on OpenSolaris, IllegalStateException: Cannot add or remove addresses
# from a channel that is bound to the wildcard address
com/sun/nio/sctp/SctpChannel/Bind.java generic-all
@@ -893,6 +932,48 @@
# jdk_security
+# Fails with -ea -esa, but only on Solaris sparc? Suspect it is timing out
+sun/security/tools/keytool/standard.sh generic-all
+
+# Fails on Solaris 10 X64, address already in use
+sun/security/krb5/auto/HttpNegotiateServer.java generic-all
+
+# Fails on almost all platforms
+# java.lang.UnsupportedClassVersionError: SerialTest :
+# Unsupported major.minor version 51.0
+# at java.lang.ClassLoader.defineClass1(Native Method)
+sun/security/util/Oid/S11N.sh generic-all
+
+# Fails on Fedora 9 32bit
+# GSSException: Failure unspecified at GSS-API level (Mechanism level:
+# Invalid argument (400) - Cannot find key of appropriate type to decrypt
+# AP REP - DES CBC mode with MD5)
+# at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:778)
+sun/security/krb5/auto/NonMutualSpnego.java generic-all
+
+# Fails on Solaris 10 sparc, GSSException: Failure unspecified at GSS-API level
+# Also fails on Windows 2000 similar way
+sun/security/krb5/auto/ok-as-delegate.sh generic-all
+
+# Fails on Windows 2000, GSSException: Failure unspecified at GSS-API level
+# (Mechanism level: Request is a replay (34))
+sun/security/krb5/auto/ok-as-delegate-xrealm.sh generic-all
+
+# Fails on Windows 2000, ExceptionInInitializerError
+sun/security/mscapi/AccessKeyStore.sh generic-all
+
+# Fails on Windows 2000, UnsatisfiedLinkError: libnspr4.dll: Access is denied
+sun/security/pkcs11/KeyAgreement/TestDH.java generic-all
+
+# Fails on Windows 2000, UnsatisfiedLinkError: libnspr4.dll: Access is denied
+sun/security/pkcs11/fips/ClientJSSEServerJSSE.java generic-all
+
+# Fails on Solaris 10, KrbException: Additional pre-authentication required (25)
+sun/security/krb5/auto/basic.sh generic-all
+
+# Fails on Fedora 9 64bit, PKCS11Exception: CKR_DEVICE_ERROR
+sun/security/pkcs11/KeyAgreement/TestDH.java generic-all
+
# Run too slow on Solaris 10 sparc
sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java solaris-sparc
sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java solaris-sparc
@@ -1088,6 +1169,16 @@
# So most if not all tools tests are now being run with "othervm" mode.
# Some of these tools tests have a tendency to use fixed ports, bad idea.
+# Fails with -ea -esa on Solaris, Assertion error (Solaris specific test)
+com/sun/tracing/BasicFunctionality.java generic-all
+
+# Fails on Fedora 9 32bit, jps output differs problem
+sun/tools/jstatd/jstatdDefaults.sh generic-all
+
+# Fails on Linux Fedora 9 32bit, Could not read data for remote JVM 16133
+# jstat output differs from expected output
+sun/tools/jstatd/jstatdExternalRegistry.sh generic-all
+
# Output of jps differs from expected output.
# Invalid argument count on solaris-sparc and x64
sun/tools/jstatd/jstatdPort.sh generic-all
@@ -1099,6 +1190,11 @@
sun/tools/jps/jps-Vvml_2.sh generic-all
sun/tools/jps/jps-m_2.sh generic-all
+# Fails on Solaris 10 sparcv9, shell exits with 1
+# Turning off use of shared archive because of choice of garbage collector or large pages
+# Could not synchronize with target
+sun/tools/jps/jps-v_1.sh generic-all
+
# Fails on OpenSolaris "Could not synchronize with target"
sun/tools/jps/jps-Defaults.sh generic-all
sun/tools/jps/jps-V_2.sh generic-all
@@ -1160,6 +1256,12 @@
# jdk_util
+# Fails with -ea -esa on all platforms with Assertion error
+java/util/ResourceBundle/Test4300693.java generic-all
+
+# Failing on all -client 32bit platforms starting with b77? See 6908348.
+java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java generic-all
+
# Assert error, failures, on Linux Fedora 9 -server
# Windows samevm failure, assert error "Passed = 134, failed = 2"
java/util/Arrays/ArrayObjectMethods.java generic-all
--- a/jdk/test/com/sun/jdi/NoLaunchOptionTest.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/com/sun/jdi/NoLaunchOptionTest.java Wed Jul 05 17:04:56 2017 +0200
@@ -31,6 +31,9 @@
* @build VMConnection
* @run main/othervm NoLaunchOptionTest
*/
+
+import java.net.ServerSocket;
+
public class NoLaunchOptionTest extends Object {
private Process subprocess;
private int subprocessStatus;
@@ -121,12 +124,19 @@
}
public static void main(String[] args) throws Exception {
+ // find a free port
+ ServerSocket ss = new ServerSocket(0);
+ int port = ss.getLocalPort();
+ ss.close();
+ String address = String.valueOf(port);
+
String javaExe = System.getProperty("java.home") +
java.io.File.separator + "bin" +
java.io.File.separator + "java";
String targetClass = "NotAClass";
String cmds [] = {javaExe,
- "-agentlib:jdwp=transport=dt_socket,address=8000," +
+ "-agentlib:jdwp=transport=dt_socket,address=" +
+ address + "," +
"onthrow=java.lang.ClassNotFoundException,suspend=n",
targetClass};
NoLaunchOptionTest myTest = new NoLaunchOptionTest();
--- a/jdk/test/com/sun/jdi/OptionTest.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/com/sun/jdi/OptionTest.java Wed Jul 05 17:04:56 2017 +0200
@@ -32,6 +32,9 @@
* @run compile -g VMConnection.java
* @run main/othervm OptionTest
*/
+
+import java.net.ServerSocket;
+
public class OptionTest extends Object {
private Process subprocess;
private int subprocessStatus;
@@ -122,12 +125,18 @@
}
public static void main(String[] args) throws Exception {
+ // find a free port
+ ServerSocket ss = new ServerSocket(0);
+ int port = ss.getLocalPort();
+ ss.close();
+ String address = String.valueOf(port);
+
String javaExe = System.getProperty("java.home") +
java.io.File.separator + "bin" +
java.io.File.separator + "java";
String targetClass = "HelloWorld";
String baseOptions = "transport=dt_socket" +
- ",address=8000" +
+ ",address=" + address +
",server=y" +
",suspend=n";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/dyn/MethodHandlesTest.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,1839 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @summary unit tests for java.dyn.MethodHandles
+ * @compile -XDinvokedynamic MethodHandlesTest.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic jdk.java.dyn.MethodHandlesTest
+ */
+
+package jdk.java.dyn;
+
+import java.dyn.*;
+import java.dyn.MethodHandles.Lookup;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+
+/**
+ *
+ * @author jrose
+ */
+public class MethodHandlesTest {
+ // How much output?
+ static int verbosity = 1;
+
+ // Set this true during development if you want to fast-forward to
+ // a particular new, non-working test. Tests which are known to
+ // work (or have recently worked) test this flag and return on true.
+ static boolean CAN_SKIP_WORKING = false;
+ //static { CAN_SKIP_WORKING = true; }
+
+ // Set true to test more calls. If false, some tests are just
+ // lookups, without exercising the actual method handle.
+ static boolean DO_MORE_CALLS = false;
+
+
+ @Test
+ public void testFirst() throws Throwable {
+ verbosity += 9; try {
+ // left blank for debugging
+ } finally { verbosity -= 9; }
+ }
+
+ // current failures
+ @Test @Ignore("failure in call to makeRawRetypeOnly in ToGeneric")
+ public void testFail_1() throws Throwable {
+ testSpreadArguments(int.class, 0, 6);
+ }
+ @Test @Ignore("failure in JVM when expanding the stack")
+ public void testFail_2() throws Throwable {
+ // if CONV_OP_IMPLEMENTED_MASK includes OP_SPREAD_ARGS, this crashes:
+ testSpreadArguments(Object.class, 0, 2);
+ }
+ @Test @Ignore("IllArgEx failure in call to ToGeneric.make")
+ public void testFail_3() throws Throwable {
+ testSpreadArguments(int.class, 1, 2);
+ }
+ @Test @Ignore("IllArgEx failure in call to ToGeneric.make")
+ public void testFail_4() throws Throwable {
+ testCollectArguments(int.class, 1, 2);
+ }
+ @Test @Ignore("cannot collect leading primitive types")
+ public void testFail_5() throws Throwable {
+ testInvokers(MethodType.genericMethodType(2).changeParameterType(0, int.class));
+ }
+ @Test @Ignore("should not insert arguments beyond MethodHandlePushLimit")
+ public void testFail_6() throws Throwable {
+ testInsertArguments(0, 0, MAX_ARG_INCREASE+1);
+ }
+ static final int MAX_ARG_INCREASE = 3;
+
+ public MethodHandlesTest() {
+ }
+
+ String testName;
+ int posTests, negTests;
+ @After
+ public void printCounts() {
+ if (verbosity >= 1 && (posTests | negTests) != 0) {
+ System.out.println();
+ if (posTests != 0) System.out.println("=== "+testName+": "+posTests+" positive test cases run");
+ if (negTests != 0) System.out.println("=== "+testName+": "+negTests+" negative test cases run");
+ }
+ }
+ void countTest(boolean positive) {
+ if (positive) ++posTests;
+ else ++negTests;
+ }
+ void countTest() { countTest(true); }
+ void startTest(String name) {
+ if (testName != null) printCounts();
+ if (verbosity >= 0)
+ System.out.println(name);
+ posTests = negTests = 0;
+ testName = name;
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ calledLog.clear();
+ calledLog.add(null);
+ nextArg = 1000000;
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ }
+
+ static List<Object> calledLog = new ArrayList<Object>();
+ static Object logEntry(String name, Object... args) {
+ return Arrays.asList(name, Arrays.asList(args));
+ }
+ static Object called(String name, Object... args) {
+ Object entry = logEntry(name, args);
+ calledLog.add(entry);
+ return entry;
+ }
+ static void assertCalled(String name, Object... args) {
+ Object expected = logEntry(name, args);
+ Object actual = calledLog.get(calledLog.size() - 1);
+ if (expected.equals(actual)) return;
+ System.out.println("assertCalled "+name+":");
+ System.out.println("expected: "+expected);
+ System.out.println("actual: "+actual);
+ System.out.println("ex. types: "+getClasses(expected));
+ System.out.println("act. types: "+getClasses(actual));
+ assertEquals("previous method call types", expected, actual);
+ assertEquals("previous method call", expected, actual);
+ }
+ static void printCalled(MethodHandle target, String name, Object... args) {
+ if (verbosity >= 2)
+ System.out.println("calling "+logEntry(name, args)+" on "+target);
+ }
+
+ static Object castToWrapper(Object value, Class<?> dst) {
+ Object wrap = null;
+ if (value instanceof Number)
+ wrap = castToWrapperOrNull(((Number)value).longValue(), dst);
+ if (value instanceof Character)
+ wrap = castToWrapperOrNull((char)(Character)value, dst);
+ if (wrap != null) return wrap;
+ return dst.cast(value);
+ }
+
+ static Object castToWrapperOrNull(long value, Class<?> dst) {
+ if (dst == int.class || dst == Integer.class)
+ return (int)(value);
+ if (dst == long.class || dst == Long.class)
+ return (long)(value);
+ if (dst == char.class || dst == Character.class)
+ return (char)(value);
+ if (dst == short.class || dst == Short.class)
+ return (short)(value);
+ if (dst == float.class || dst == Float.class)
+ return (float)(value);
+ if (dst == double.class || dst == Double.class)
+ return (double)(value);
+ if (dst == byte.class || dst == Byte.class)
+ return (byte)(value);
+ if (dst == boolean.class || dst == boolean.class)
+ return ((value % 29) & 1) == 0;
+ return null;
+ }
+
+ static int nextArg;
+ static Object randomArg(Class<?> param) {
+ Object wrap = castToWrapperOrNull(nextArg, param);
+ if (wrap != null) {
+ nextArg++;
+ return wrap;
+ }
+// import sun.dyn.util.Wrapper;
+// Wrapper wrap = Wrapper.forBasicType(dst);
+// if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst))
+// wrap = Wrapper.forWrapperType(dst);
+// if (wrap != Wrapper.OBJECT)
+// return wrap.wrap(nextArg++);
+ if (param.isInterface() || param.isAssignableFrom(String.class))
+ return "#"+(nextArg++);
+ else
+ try {
+ return param.newInstance();
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ }
+ return null; // random class not Object, String, Integer, etc.
+ }
+ static Object[] randomArgs(Class<?>... params) {
+ Object[] args = new Object[params.length];
+ for (int i = 0; i < args.length; i++)
+ args[i] = randomArg(params[i]);
+ return args;
+ }
+ static Object[] randomArgs(int nargs, Class<?> param) {
+ Object[] args = new Object[nargs];
+ for (int i = 0; i < args.length; i++)
+ args[i] = randomArg(param);
+ return args;
+ }
+
+ static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
+ return Arrays.copyOf(a, a.length, atype);
+ }
+ static <T> T[] cat(T[] a, T... b) {
+ int alen = a.length, blen = b.length;
+ if (blen == 0) return a;
+ T[] c = Arrays.copyOf(a, alen + blen);
+ System.arraycopy(b, 0, c, alen, blen);
+ return c;
+ }
+ static Integer[] boxAll(int... vx) {
+ Integer[] res = new Integer[vx.length];
+ for (int i = 0; i < res.length; i++) {
+ res[i] = vx[i];
+ }
+ return res;
+ }
+ static Object getClasses(Object x) {
+ if (x == null) return x;
+ if (x instanceof String) return x; // keep the name
+ if (x instanceof List) {
+ // recursively report classes of the list elements
+ Object[] xa = ((List)x).toArray();
+ for (int i = 0; i < xa.length; i++)
+ xa[i] = getClasses(xa[i]);
+ return Arrays.asList(xa);
+ }
+ return x.getClass().getSimpleName();
+ }
+
+ static MethodHandle changeArgTypes(MethodHandle target, Class<?> argType) {
+ return changeArgTypes(target, 0, 999, argType);
+ }
+ static MethodHandle changeArgTypes(MethodHandle target,
+ int beg, int end, Class<?> argType) {
+ MethodType targetType = target.type();
+ end = Math.min(end, targetType.parameterCount());
+ ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>(targetType.parameterList());
+ Collections.fill(argTypes.subList(beg, end), argType);
+ MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
+ return MethodHandles.convertArguments(target, ttype2);
+ }
+
+ // This lookup is good for all members in and under MethodHandlesTest.
+ static final Lookup PRIVATE = MethodHandles.lookup();
+ // This lookup is good for package-private members but not private ones.
+ static final Lookup PACKAGE = PackageSibling.lookup();
+ // This lookup is good only for public members.
+ static final Lookup PUBLIC = MethodHandles.publicLookup();
+
+ // Subject methods...
+ static class Example implements IntExample {
+ final String name;
+ public Example() { name = "Example#"+(nextArg++); }
+ protected Example(String name) { this.name = name; }
+ protected Example(int x) { this(); called("protected <init>", this, x); }
+ @Override public String toString() { return name; }
+
+ public void v0() { called("v0", this); }
+ void pkg_v0() { called("pkg_v0", this); }
+ private void pri_v0() { called("pri_v0", this); }
+ public static void s0() { called("s0"); }
+ static void pkg_s0() { called("pkg_s0"); }
+ private static void pri_s0() { called("pri_s0"); }
+
+ public Object v1(Object x) { return called("v1", this, x); }
+ public Object v2(Object x, Object y) { return called("v2", this, x, y); }
+ public Object v2(Object x, int y) { return called("v2", this, x, y); }
+ public Object v2(int x, Object y) { return called("v2", this, x, y); }
+ public Object v2(int x, int y) { return called("v2", this, x, y); }
+ public static Object s1(Object x) { return called("s1", x); }
+ public static Object s2(int x) { return called("s2", x); }
+ public static Object s3(long x) { return called("s3", x); }
+ public static Object s4(int x, int y) { return called("s4", x, y); }
+ public static Object s5(long x, int y) { return called("s5", x, y); }
+ public static Object s6(int x, long y) { return called("s6", x, y); }
+ public static Object s7(float x, double y) { return called("s7", x, y); }
+ }
+ public static class PubExample extends Example {
+ }
+ static class SubExample extends Example {
+ @Override public void v0() { called("Sub/v0", this); }
+ @Override void pkg_v0() { called("Sub/pkg_v0", this); }
+ private SubExample(int x) { called("<init>", this, x); }
+ public SubExample() { super("SubExample#"+(nextArg++)); }
+ }
+ public static interface IntExample {
+ public void v0();
+ static class Impl implements IntExample {
+ public void v0() { called("Int/v0", this); }
+ final String name;
+ public Impl() { name = "Example#"+(nextArg++); }
+ }
+ }
+
+ static final Object[][][] ACCESS_CASES = {
+ { { false, PUBLIC }, { false, PACKAGE }, { false, PRIVATE } },
+ { { false, PUBLIC }, { false, PACKAGE }, { true, PRIVATE } },
+ { { false, PUBLIC }, { true, PACKAGE }, { true, PRIVATE } },
+ { { true, PUBLIC }, { true, PACKAGE }, { true, PRIVATE } },
+ };
+
+ static Object[][] accessCases(Class<?> defc, String name) {
+ if (name.contains("pri_")) {
+ return ACCESS_CASES[1]; // PRIVATE only
+ } else if (name.contains("pkg_")) {
+ return ACCESS_CASES[2]; // not PUBLIC
+ } else {
+ assertTrue(name.indexOf('_') < 0);
+ boolean pubc = Modifier.isPublic(defc.getModifiers());
+ if (pubc)
+ return ACCESS_CASES[3]; // all access levels
+ return ACCESS_CASES[2]; // PACKAGE but not PUBLIC
+ }
+ }
+
+ @Test
+ public void testFindStatic() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("findStatic");
+ testFindStatic(PubExample.class, void.class, "s0");
+ testFindStatic(Example.class, void.class, "s0");
+ testFindStatic(Example.class, void.class, "pkg_s0");
+ testFindStatic(Example.class, void.class, "pri_s0");
+
+ testFindStatic(Example.class, Object.class, "s1", Object.class);
+ testFindStatic(Example.class, Object.class, "s2", int.class);
+ testFindStatic(Example.class, Object.class, "s3", long.class);
+ testFindStatic(Example.class, Object.class, "s4", int.class, int.class);
+ testFindStatic(Example.class, Object.class, "s5", long.class, int.class);
+ testFindStatic(Example.class, Object.class, "s6", int.class, long.class);
+ testFindStatic(Example.class, Object.class, "s7", float.class, double.class);
+
+ testFindStatic(false, PRIVATE, Example.class, void.class, "bogus");
+ }
+
+ void testFindStatic(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ for (Object[] ac : accessCases(defc, name)) {
+ testFindStatic((Boolean)ac[0], (Lookup)ac[1], defc, ret, name, params);
+ }
+ }
+ void testFindStatic(Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ testFindStatic(true, lookup, defc, ret, name, params);
+ }
+ void testFindStatic(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ countTest(positive);
+ MethodType type = MethodType.methodType(ret, params);
+ MethodHandle target = null;
+ RuntimeException noAccess = null;
+ try {
+ target = lookup.findStatic(defc, name, type);
+ } catch (NoAccessException ex) {
+ noAccess = ex;
+ }
+ if (verbosity >= 2)
+ System.out.println("findStatic "+lookup+": "+defc+"."+name+"/"+type+" => "+target
+ +(noAccess == null ? "" : " !! "+noAccess));
+ if (positive && noAccess != null) throw noAccess;
+ assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+ if (!positive) return; // negative test failed as expected
+ assertEquals(type, target.type());
+ assertTrue(target.toString().contains(name)); // rough check
+ if (!DO_MORE_CALLS && lookup != PRIVATE) return;
+ Object[] args = randomArgs(params);
+ printCalled(target, name, args);
+ target.invokeVarargs(args);
+ assertCalled(name, args);
+ System.out.print(':');
+ }
+
+ @Test
+ public void testFindVirtual() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("findVirtual");
+ testFindVirtual(Example.class, void.class, "v0");
+ testFindVirtual(Example.class, void.class, "pkg_v0");
+ testFindVirtual(Example.class, void.class, "pri_v0");
+ testFindVirtual(Example.class, Object.class, "v1", Object.class);
+ testFindVirtual(Example.class, Object.class, "v2", Object.class, Object.class);
+ testFindVirtual(Example.class, Object.class, "v2", Object.class, int.class);
+ testFindVirtual(Example.class, Object.class, "v2", int.class, Object.class);
+ testFindVirtual(Example.class, Object.class, "v2", int.class, int.class);
+ testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus");
+ // test dispatch
+ testFindVirtual(SubExample.class, SubExample.class, void.class, "Sub/v0");
+ testFindVirtual(SubExample.class, Example.class, void.class, "Sub/v0");
+ testFindVirtual(SubExample.class, IntExample.class, void.class, "Sub/v0");
+ testFindVirtual(SubExample.class, SubExample.class, void.class, "Sub/pkg_v0");
+ testFindVirtual(SubExample.class, Example.class, void.class, "Sub/pkg_v0");
+ testFindVirtual(Example.class, IntExample.class, void.class, "v0");
+ testFindVirtual(IntExample.Impl.class, IntExample.class, void.class, "Int/v0");
+ }
+
+ void testFindVirtual(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ Class<?> rcvc = defc;
+ testFindVirtual(rcvc, defc, ret, name, params);
+ }
+ void testFindVirtual(Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ for (Object[] ac : accessCases(defc, name)) {
+ testFindVirtual((Boolean)ac[0], (Lookup)ac[1], rcvc, defc, ret, name, params);
+ }
+ }
+ void testFindVirtual(Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ testFindVirtual(true, lookup, rcvc, defc, ret, name, params);
+ }
+ void testFindVirtual(boolean positive, Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ countTest(positive);
+ String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo
+ MethodType type = MethodType.methodType(ret, params);
+ MethodHandle target = null;
+ RuntimeException noAccess = null;
+ try {
+ target = lookup.findVirtual(defc, methodName, type);
+ } catch (NoAccessException ex) {
+ noAccess = ex;
+ }
+ if (verbosity >= 2)
+ System.out.println("findVirtual "+lookup+": "+defc+"."+name+"/"+type+" => "+target
+ +(noAccess == null ? "" : " !! "+noAccess));
+ if (positive && noAccess != null) throw noAccess;
+ assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+ if (!positive) return; // negative test failed as expected
+ Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
+ MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
+ MethodType ttype = target.type();
+ ttype = ttype.changeParameterType(0, defc); // FIXME: test this
+ assertEquals(typeWithSelf, ttype);
+ assertTrue(target.toString().contains(methodName)); // rough check
+ if (!DO_MORE_CALLS && lookup != PRIVATE) return;
+ Object[] argsWithSelf = randomArgs(paramsWithSelf);
+ if (rcvc != defc) argsWithSelf[0] = randomArg(rcvc);
+ printCalled(target, name, argsWithSelf);
+ target.invokeVarargs(argsWithSelf);
+ assertCalled(name, argsWithSelf);
+ System.out.print(':');
+ }
+
+ @Test
+ public void testFindSpecial() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("findSpecial");
+ testFindSpecial(Example.class, void.class, "v0");
+ testFindSpecial(Example.class, void.class, "pkg_v0");
+ testFindSpecial(false, PRIVATE, Example.class, void.class, "<init>", int.class);
+ testFindSpecial(false, PRIVATE, Example.class, void.class, "bogus");
+ }
+
+ void testFindSpecial(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ testFindSpecial(true, PRIVATE, defc, ret, name, params);
+ testFindSpecial(false, PACKAGE, defc, ret, name, params);
+ testFindSpecial(false, PUBLIC, defc, ret, name, params);
+ }
+ void testFindSpecial(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ countTest(positive);
+ MethodType type = MethodType.methodType(ret, params);
+ MethodHandle target = null;
+ RuntimeException noAccess = null;
+ try {
+ target = lookup.findSpecial(defc, name, type, defc);
+ } catch (NoAccessException ex) {
+ noAccess = ex;
+ }
+ if (verbosity >= 2)
+ System.out.println("findSpecial "+defc+"."+name+"/"+type+" => "+target
+ +(noAccess == null ? "" : " !! "+noAccess));
+ if (positive && noAccess != null) throw noAccess;
+ assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+ if (!positive) return; // negative test failed as expected
+ Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
+ MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
+ MethodType ttype = target.type();
+ ttype = ttype.changeParameterType(0, defc); // FIXME: test this
+ assertEquals(typeWithSelf, ttype);
+ assertTrue(target.toString().contains(name)); // rough check
+ if (!DO_MORE_CALLS && lookup != PRIVATE) return;
+ Object[] args = randomArgs(paramsWithSelf);
+ printCalled(target, name, args);
+ target.invokeVarargs(args);
+ assertCalled(name, args);
+ System.out.print(':');
+ }
+
+ @Test
+ public void testBind() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("bind");
+ testBind(Example.class, void.class, "v0");
+ testBind(Example.class, void.class, "pkg_v0");
+ testBind(Example.class, void.class, "pri_v0");
+ testBind(Example.class, Object.class, "v1", Object.class);
+ testBind(Example.class, Object.class, "v2", Object.class, Object.class);
+ testBind(Example.class, Object.class, "v2", Object.class, int.class);
+ testBind(Example.class, Object.class, "v2", int.class, Object.class);
+ testBind(Example.class, Object.class, "v2", int.class, int.class);
+ testBind(false, PRIVATE, Example.class, void.class, "bogus");
+ testBind(SubExample.class, void.class, "Sub/v0");
+ testBind(SubExample.class, void.class, "Sub/pkg_v0");
+ testBind(IntExample.Impl.class, void.class, "Int/v0");
+ }
+
+ void testBind(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ for (Object[] ac : accessCases(defc, name)) {
+ testBind((Boolean)ac[0], (Lookup)ac[1], defc, ret, name, params);
+ }
+ }
+
+ void testBind(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ countTest(positive);
+ String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo
+ MethodType type = MethodType.methodType(ret, params);
+ Object receiver = randomArg(defc);
+ MethodHandle target = null;
+ RuntimeException noAccess = null;
+ try {
+ target = lookup.bind(receiver, methodName, type);
+ } catch (NoAccessException ex) {
+ noAccess = ex;
+ }
+ if (verbosity >= 2)
+ System.out.println("bind "+receiver+"."+name+"/"+type+" => "+target
+ +(noAccess == null ? "" : " !! "+noAccess));
+ if (positive && noAccess != null) throw noAccess;
+ assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+ if (!positive) return; // negative test failed as expected
+ assertEquals(type, target.type());
+ Object[] args = randomArgs(params);
+ printCalled(target, name, args);
+ target.invokeVarargs(args);
+ Object[] argsWithReceiver = cat(array(Object[].class, receiver), args);
+ assertCalled(name, argsWithReceiver);
+ System.out.print(':');
+ }
+
+ @Test
+ public void testUnreflect() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("unreflect");
+ testUnreflect(Example.class, true, void.class, "s0");
+ testUnreflect(Example.class, true, void.class, "pkg_s0");
+ testUnreflect(Example.class, true, void.class, "pri_s0");
+
+ testUnreflect(Example.class, true, Object.class, "s1", Object.class);
+ testUnreflect(Example.class, true, Object.class, "s2", int.class);
+ //testUnreflect(Example.class, true, Object.class, "s3", long.class);
+ //testUnreflect(Example.class, true, Object.class, "s4", int.class, int.class);
+ //testUnreflect(Example.class, true, Object.class, "s5", long.class, int.class);
+ //testUnreflect(Example.class, true, Object.class, "s6", int.class, long.class);
+
+ testUnreflect(Example.class, false, void.class, "v0");
+ testUnreflect(Example.class, false, void.class, "pkg_v0");
+ testUnreflect(Example.class, false, void.class, "pri_v0");
+ testUnreflect(Example.class, false, Object.class, "v1", Object.class);
+ testUnreflect(Example.class, false, Object.class, "v2", Object.class, Object.class);
+ testUnreflect(Example.class, false, Object.class, "v2", Object.class, int.class);
+ testUnreflect(Example.class, false, Object.class, "v2", int.class, Object.class);
+ testUnreflect(Example.class, false, Object.class, "v2", int.class, int.class);
+ }
+
+ void testUnreflect(Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ for (Object[] ac : accessCases(defc, name)) {
+ testUnreflect((Boolean)ac[0], (Lookup)ac[1], defc, isStatic, ret, name, params);
+ }
+ }
+ void testUnreflect(boolean positive, Lookup lookup, Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
+ countTest(positive);
+ MethodType type = MethodType.methodType(ret, params);
+ Method rmethod = null;
+ MethodHandle target = null;
+ RuntimeException noAccess = null;
+ try {
+ rmethod = defc.getDeclaredMethod(name, params);
+ } catch (NoSuchMethodException ex) {
+ throw new NoAccessException(ex);
+ }
+ assertEquals(isStatic, Modifier.isStatic(rmethod.getModifiers()));
+ try {
+ target = lookup.unreflect(rmethod);
+ } catch (NoAccessException ex) {
+ noAccess = ex;
+ }
+ if (verbosity >= 2)
+ System.out.println("unreflect "+defc+"."+name+"/"+type+" => "+target
+ +(noAccess == null ? "" : " !! "+noAccess));
+ if (positive && noAccess != null) throw noAccess;
+ assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+ if (!positive) return; // negative test failed as expected
+ Class<?>[] paramsMaybeWithSelf = params;
+ if (!isStatic) {
+ paramsMaybeWithSelf = cat(array(Class[].class, (Class)defc), params);
+ }
+ MethodType typeMaybeWithSelf = MethodType.methodType(ret, paramsMaybeWithSelf);
+ MethodType ttype = target.type();
+ if (!isStatic)
+ ttype = ttype.changeParameterType(0, defc); // FIXME: test this
+ assertEquals(typeMaybeWithSelf, ttype);
+ Object[] argsMaybeWithSelf = randomArgs(paramsMaybeWithSelf);
+ printCalled(target, name, argsMaybeWithSelf);
+ target.invokeVarargs(argsMaybeWithSelf);
+ assertCalled(name, argsMaybeWithSelf);
+ System.out.print(':');
+ }
+
+ @Test @Ignore("unimplemented")
+ public void testUnreflectSpecial() throws Throwable {
+ Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
+ startTest("unreflectSpecial");
+ Method m = null;
+ MethodHandle expResult = null;
+ MethodHandle result = lookup.unreflectSpecial(m, Example.class);
+ assertEquals(expResult, result);
+ fail("The test case is a prototype.");
+ }
+
+ public static class HasFields {
+ boolean fZ = false;
+ byte fB = (byte)'B';
+ short fS = (short)'S';
+ char fC = 'C';
+ int fI = 'I';
+ long fJ = 'J';
+ float fF = 'F';
+ double fD = 'D';
+ static boolean sZ = true;
+ static byte sB = 1+(byte)'B';
+ static short sS = 1+(short)'S';
+ static char sC = 1+'C';
+ static int sI = 1+'I';
+ static long sJ = 1+'J';
+ static float sF = 1+'F';
+ static double sD = 1+'D';
+
+ Object fL = 'L';
+ String fR = "R";
+ static Object sL = 'M';
+ static String sR = "S";
+
+ static final Object[][] CASES;
+ static {
+ ArrayList<Object[]> cases = new ArrayList<Object[]>();
+ Object types[][] = {
+ {'L',Object.class}, {'R',String.class},
+ {'I',int.class}, {'J',long.class},
+ {'F',float.class}, {'D',double.class},
+ {'Z',boolean.class}, {'B',byte.class},
+ {'S',short.class}, {'C',char.class},
+ };
+ HasFields fields = new HasFields();
+ for (Object[] t : types) {
+ for (int kind = 0; kind <= 1; kind++) {
+ boolean isStatic = (kind != 0);
+ char btc = (Character)t[0];
+ String name = (isStatic ? "s" : "f") + btc;
+ Class<?> type = (Class<?>) t[1];
+ Object value;
+ Field field;
+ try {
+ field = HasFields.class.getDeclaredField(name);
+ } catch (Exception ex) {
+ throw new InternalError("no field HasFields."+name);
+ }
+ try {
+ value = field.get(fields);
+ } catch (Exception ex) {
+ throw new InternalError("cannot fetch field HasFields."+name);
+ }
+ if (type == float.class) {
+ float v = 'F';
+ if (isStatic) v++;
+ assert(value.equals(v));
+ }
+ assert(name.equals(field.getName()));
+ assert(type.equals(field.getType()));
+ assert(isStatic == (Modifier.isStatic(field.getModifiers())));
+ cases.add(new Object[]{ field, value });
+ }
+ }
+ CASES = cases.toArray(new Object[0][]);
+ }
+ }
+
+ @Test
+ public void testUnreflectGetter() throws Throwable {
+ Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
+ startTest("unreflectGetter");
+ for (Object[] c : HasFields.CASES) {
+ Field f = (Field)c[0];
+ Object value = c[1];
+ Class<?> type = f.getType();
+ if (type.isPrimitive() && type != int.class)
+ continue; //FIXME
+ testUnreflectGetter(lookup, f, type, value);
+ }
+ }
+ public void testUnreflectGetter(MethodHandles.Lookup lookup,
+ Field f, Class<?> type, Object value) throws Throwable {
+ countTest(true);
+ boolean isStatic = Modifier.isStatic(f.getModifiers());
+ MethodType expType = MethodType.methodType(type, HasFields.class);
+ if (isStatic) expType = expType.dropParameterTypes(0, 1);
+ MethodHandle mh = lookup.unreflectGetter(f);
+ assertSame(mh.type(), expType);
+ assertEquals(mh.toString(), f.getName());
+ HasFields fields = new HasFields();
+ Object sawValue;
+ Class<?> rtype = type;
+ if (type != int.class) rtype = Object.class;
+ mh = MethodHandles.convertArguments(mh, mh.type().generic().changeReturnType(rtype));
+ Object expValue = value;
+ for (int i = 0; i <= 1; i++) {
+ if (isStatic) {
+ if (type == int.class)
+ sawValue = mh.<int>invoke(); // do these exactly
+ else
+ sawValue = mh.invoke();
+ } else {
+ if (type == int.class)
+ sawValue = mh.<int>invoke((Object) fields);
+ else
+ sawValue = mh.invoke((Object) fields);
+ }
+ assertEquals(sawValue, expValue);
+ Object random = randomArg(type);
+ f.set(fields, random);
+ expValue = random;
+ }
+ f.set(fields, value); // put it back
+ }
+
+
+ @Test
+ public void testUnreflectSetter() throws Throwable {
+ Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
+ startTest("unreflectSetter");
+ for (Object[] c : HasFields.CASES) {
+ Field f = (Field)c[0];
+ Object value = c[1];
+ Class<?> type = f.getType();
+ if (type.isPrimitive() && type != int.class)
+ continue; //FIXME
+ testUnreflectSetter(lookup, f, type, value);
+ }
+ }
+ public void testUnreflectSetter(MethodHandles.Lookup lookup,
+ Field f, Class<?> type, Object value) throws Throwable {
+ countTest(true);
+ boolean isStatic = Modifier.isStatic(f.getModifiers());
+ MethodType expType = MethodType.methodType(void.class, HasFields.class, type);
+ if (isStatic) expType = expType.dropParameterTypes(0, 1);
+ MethodHandle mh = lookup.unreflectSetter(f);
+ assertSame(mh.type(), expType);
+ assertEquals(mh.toString(), f.getName());
+ HasFields fields = new HasFields();
+ Object sawValue;
+ Class<?> vtype = type;
+ if (type != int.class) vtype = Object.class;
+ int last = mh.type().parameterCount() - 1;
+ mh = MethodHandles.convertArguments(mh, mh.type().generic().changeReturnType(void.class).changeParameterType(last, vtype));
+ assertEquals(f.get(fields), value); // clean to start with
+ for (int i = 0; i <= 1; i++) {
+ Object putValue = randomArg(type);
+ if (isStatic) {
+ if (type == int.class)
+ mh.<void>invoke((int)(Integer)putValue); // do these exactly
+ else
+ mh.<void>invoke(putValue);
+ } else {
+ if (type == int.class)
+ mh.<void>invoke((Object) fields, (int)(Integer)putValue);
+ else
+ mh.<void>invoke((Object) fields, putValue);
+ }
+ assertEquals(f.get(fields), putValue);
+ }
+ f.set(fields, value); // put it back
+ }
+
+ @Test
+ public void testArrayElementGetter() throws Throwable {
+ startTest("arrayElementGetter");
+ testArrayElementGetterSetter(new Object[10], false);
+ testArrayElementGetterSetter(new String[10], false);
+ testArrayElementGetterSetter(new int[10], false);
+ // FIXME: Do the other primitive types.
+ //testArrayElementGetterSetter(new float[10], false);
+ }
+
+ @Test
+ public void testArrayElementSetter() throws Throwable {
+ startTest("arrayElementSetter");
+ testArrayElementGetterSetter(new Object[10], true);
+ testArrayElementGetterSetter(new String[10], true);
+ testArrayElementGetterSetter(new int[10], true);
+ // FIXME: Do the other primitive types.
+ //testArrayElementGetterSetter(new float[10], true);
+ }
+
+ public void testArrayElementGetterSetter(Object array, boolean testSetter) throws Throwable {
+ countTest(true);
+ Class<?> arrayType = array.getClass();
+ Class<?> elemType = arrayType.getComponentType();
+ MethodType expType = !testSetter
+ ? MethodType.methodType(elemType, arrayType, int.class)
+ : MethodType.methodType(void.class, arrayType, int.class, elemType);
+ MethodHandle mh = !testSetter
+ ? MethodHandles.arrayElementGetter(arrayType)
+ : MethodHandles.arrayElementSetter(arrayType);
+ assertSame(mh.type(), expType);
+ //assertEquals(mh.toString(), f.getName());
+ Object sawValue, expValue;
+ List<Object> model = array2list(array);
+ int length = Array.getLength(array);
+ for (int i = 0; i < length; i++) {
+ // update array element
+ Object random = randomArg(elemType);
+ model.set(i, random);
+ if (testSetter) {
+ if (elemType == int.class)
+ mh.<void>invoke((int[]) array, i, (int)(Integer)random);
+ else
+ mh.invokeGeneric(array, i, random);
+ assertEquals(model, array2list(array));
+ } else {
+ Array.set(array, i, random);
+
+ }
+ // observe array element
+ sawValue = Array.get(array, i);
+ if (!testSetter) {
+ expValue = sawValue;
+ if (elemType == int.class)
+ sawValue = mh.<int>invoke((int[]) array, i);
+ else
+ sawValue = mh.invokeGeneric(array, i);
+ assertEquals(sawValue, expValue);
+ assertEquals(model, array2list(array));
+ }
+ }
+ }
+
+ List<Object> array2list(Object array) {
+ int length = Array.getLength(array);
+ ArrayList<Object> model = new ArrayList<Object>(length);
+ for (int i = 0; i < length; i++)
+ model.add(Array.get(array, i));
+ return model;
+ }
+
+ static class Callee {
+ static Object id() { return called("id"); }
+ static Object id(Object x) { return called("id", x); }
+ static Object id(Object x, Object y) { return called("id", x, y); }
+ static Object id(Object x, Object y, Object z) { return called("id", x, y, z); }
+ static Object id(Object... vx) { return called("id", vx); }
+ static MethodHandle ofType(int n) {
+ return ofType(Object.class, n);
+ }
+ static MethodHandle ofType(Class<?> rtype, int n) {
+ if (n == -1)
+ return ofType(MethodType.methodType(rtype, Object[].class));
+ return ofType(MethodType.genericMethodType(n).changeReturnType(rtype));
+ }
+ static MethodHandle ofType(Class<?> rtype, Class<?>... ptypes) {
+ return ofType(MethodType.methodType(rtype, ptypes));
+ }
+ static MethodHandle ofType(MethodType type) {
+ Class<?> rtype = type.returnType();
+ String pfx = "";
+ if (rtype != Object.class)
+ pfx = rtype.getSimpleName().substring(0, 1).toLowerCase();
+ String name = pfx+"id";
+ return PRIVATE.findStatic(Callee.class, name, type);
+ }
+ }
+
+ @Test
+ public void testConvertArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("convertArguments");
+ testConvert(Callee.ofType(1), null, "id", int.class);
+ testConvert(Callee.ofType(1), null, "id", String.class);
+ testConvert(Callee.ofType(1), null, "id", Integer.class);
+ testConvert(Callee.ofType(1), null, "id", short.class);
+ }
+
+ void testConvert(MethodHandle id, Class<?> rtype, String name, Class<?>... params) throws Throwable {
+ testConvert(true, id, rtype, name, params);
+ }
+
+ void testConvert(boolean positive, MethodHandle id, Class<?> rtype, String name, Class<?>... params) throws Throwable {
+ countTest(positive);
+ MethodType idType = id.type();
+ if (rtype == null) rtype = idType.returnType();
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] == null) params[i] = idType.parameterType(i);
+ }
+ // simulate the pairwise conversion
+ MethodType newType = MethodType.methodType(rtype, params);
+ Object[] args = randomArgs(newType.parameterArray());
+ Object[] convArgs = args.clone();
+ for (int i = 0; i < args.length; i++) {
+ Class<?> src = newType.parameterType(i);
+ Class<?> dst = idType.parameterType(i);
+ if (src != dst)
+ convArgs[i] = castToWrapper(convArgs[i], dst);
+ }
+ Object convResult = id.invokeVarargs(convArgs);
+ {
+ Class<?> dst = newType.returnType();
+ Class<?> src = idType.returnType();
+ if (src != dst)
+ convResult = castToWrapper(convResult, dst);
+ }
+ MethodHandle target = null;
+ RuntimeException error = null;
+ try {
+ target = MethodHandles.convertArguments(id, newType);
+ } catch (RuntimeException ex) {
+ error = ex;
+ }
+ if (verbosity >= 2)
+ System.out.println("convert "+id+ " to "+newType+" => "+target
+ +(error == null ? "" : " !! "+error));
+ if (positive && error != null) throw error;
+ assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+ if (!positive) return; // negative test failed as expected
+ assertEquals(newType, target.type());
+ printCalled(target, id.toString(), args);
+ Object result = target.invokeVarargs(args);
+ assertCalled(name, convArgs);
+ assertEquals(convResult, result);
+ System.out.print(':');
+ }
+
+ @Test
+ public void testPermuteArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("permuteArguments");
+ testPermuteArguments(4, Integer.class, 2, String.class, 0);
+ //testPermuteArguments(6, Integer.class, 0, null, 30);
+ //testPermuteArguments(4, Integer.class, 1, int.class, 6);
+ }
+ public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
+ if (verbosity >= 1)
+ System.out.println("permuteArguments "+max+"*"+type1.getName()
+ +(t2c==0?"":"/"+t2c+"*"+type2.getName())
+ +(dilution > 0 ? " with dilution "+dilution : ""));
+ int t2pos = t2c == 0 ? 0 : 1;
+ for (int inargs = t2pos+1; inargs <= max; inargs++) {
+ Class<?>[] types = new Class<?>[inargs];
+ Arrays.fill(types, type1);
+ if (t2c != 0) {
+ // Fill in a middle range with type2:
+ Arrays.fill(types, t2pos, Math.min(t2pos+t2c, inargs), type2);
+ }
+ Object[] args = randomArgs(types);
+ int numcases = 1;
+ for (int outargs = 0; outargs <= max; outargs++) {
+ if (outargs - inargs >= MAX_ARG_INCREASE) continue;
+ int[] reorder = new int[outargs];
+ int casStep = dilution + 1;
+ // Avoid some common factors:
+ while ((casStep > 2 && casStep % 2 == 0 && inargs % 2 == 0) ||
+ (casStep > 3 && casStep % 3 == 0 && inargs % 3 == 0))
+ casStep++;
+ for (int cas = 0; cas < numcases; cas += casStep) {
+ for (int i = 0, c = cas; i < outargs; i++) {
+ reorder[i] = c % inargs;
+ c /= inargs;
+ }
+ testPermuteArguments(args, types, reorder);
+ }
+ numcases *= inargs;
+ if (dilution > 10 && outargs >= 4) {
+ // Do some special patterns, which we probably missed.
+ // Replication of a single argument or argument pair.
+ for (int i = 0; i < inargs; i++) {
+ Arrays.fill(reorder, i);
+ testPermuteArguments(args, types, reorder);
+ for (int d = 1; d <= 2; d++) {
+ if (i + d >= inargs) continue;
+ for (int j = 1; j < outargs; j += 2)
+ reorder[j] += 1;
+ testPermuteArguments(args, types, reorder);
+ testPermuteArguments(args, types, reverse(reorder));
+ }
+ }
+ // Repetition of a sequence of 3 or more arguments.
+ for (int i = 1; i < inargs; i++) {
+ for (int len = 3; len <= inargs; len++) {
+ for (int j = 0; j < outargs; j++)
+ reorder[j] = (i + (j % len)) % inargs;
+ testPermuteArguments(args, types, reorder);
+ testPermuteArguments(args, types, reverse(reorder));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static int[] reverse(int[] reorder) {
+ reorder = reorder.clone();
+ for (int i = 0, imax = reorder.length / 2; i < imax; i++) {
+ int j = reorder.length - 1 - i;
+ int tem = reorder[i];
+ reorder[i] = reorder[j];
+ reorder[j] = tem;
+ }
+ return reorder;
+ }
+
+ void testPermuteArguments(Object[] args, Class<?>[] types, int[] reorder) throws Throwable {
+ countTest();
+ if (args == null && types == null) {
+ int max = 0;
+ for (int j : reorder) {
+ if (max < j) max = j;
+ }
+ args = randomArgs(max+1, Integer.class);
+ }
+ if (args == null) {
+ args = randomArgs(types);
+ }
+ if (types == null) {
+ types = new Class<?>[args.length];
+ for (int i = 0; i < args.length; i++)
+ types[i] = args[i].getClass();
+ }
+ int inargs = args.length, outargs = reorder.length;
+ assert(inargs == types.length);
+ if (verbosity >= 2)
+ System.out.println("permuteArguments "+Arrays.toString(reorder));
+ Object[] permArgs = new Object[outargs];
+ Class<?>[] permTypes = new Class<?>[outargs];
+ for (int i = 0; i < outargs; i++) {
+ permArgs[i] = args[reorder[i]];
+ permTypes[i] = types[reorder[i]];
+ }
+ if (verbosity >= 3) {
+ System.out.println("in args: "+Arrays.asList(args));
+ System.out.println("out args: "+Arrays.asList(permArgs));
+ System.out.println("in types: "+Arrays.asList(types));
+ System.out.println("out types: "+Arrays.asList(permTypes));
+ }
+ MethodType inType = MethodType.methodType(Object.class, types);
+ MethodType outType = MethodType.methodType(Object.class, permTypes);
+ MethodHandle target = MethodHandles.convertArguments(ValueConversions.varargsList(outargs), outType);
+ MethodHandle newTarget = MethodHandles.permuteArguments(target, inType, reorder);
+ Object result = newTarget.invokeVarargs(args);
+ Object expected = Arrays.asList(permArgs);
+ assertEquals(expected, result);
+ }
+
+
+ @Test
+ public void testSpreadArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("spreadArguments");
+ for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+ if (verbosity >= 2)
+ System.out.println("spreadArguments "+argType);
+ for (int nargs = 0; nargs < 10; nargs++) {
+ if (argType == int.class && nargs >= 6) continue; // FIXME Fail_1
+ for (int pos = 0; pos < nargs; pos++) {
+ if (argType == int.class && pos > 0) continue; // FIXME Fail_3
+ testSpreadArguments(argType, pos, nargs);
+ }
+ }
+ }
+ }
+ public void testSpreadArguments(Class<?> argType, int pos, int nargs) throws Throwable {
+ countTest();
+ MethodHandle target = ValueConversions.varargsArray(nargs);
+ MethodHandle target2 = changeArgTypes(target, argType);
+ if (verbosity >= 2)
+ System.out.println("spread into "+target2+" ["+pos+".."+nargs+"]");
+ Object[] args = randomArgs(target2.type().parameterArray());
+ // make sure the target does what we think it does:
+ if (pos == 0 && nargs < 5) {
+ Object[] check = (Object[]) target.invokeVarargs(args);
+ assertArrayEquals(args, check);
+ switch (nargs) {
+ case 0:
+ check = target.<Object[]>invoke();
+ assertArrayEquals(args, check);
+ break;
+ case 1:
+ check = target.<Object[]>invoke(args[0]);
+ assertArrayEquals(args, check);
+ break;
+ case 2:
+ check = target.<Object[]>invoke(args[0], args[1]);
+ assertArrayEquals(args, check);
+ break;
+ }
+ }
+ List<Class<?>> newParams = new ArrayList<Class<?>>(target2.type().parameterList());
+ { // modify newParams in place
+ List<Class<?>> spreadParams = newParams.subList(pos, nargs);
+ spreadParams.clear(); spreadParams.add(Object[].class);
+ }
+ MethodType newType = MethodType.methodType(Object.class, newParams);
+ MethodHandle result = MethodHandles.spreadArguments(target2, newType);
+ Object[] returnValue;
+ if (pos == 0) {
+ returnValue = (Object[]) result.invoke(args);
+ } else {
+ Object[] args1 = Arrays.copyOfRange(args, 0, pos+1);
+ args1[pos] = Arrays.copyOfRange(args, pos, args.length);
+ returnValue = (Object[]) result.invokeVarargs(args1);
+ }
+ assertArrayEquals(args, returnValue);
+ }
+
+ @Test
+ public void testCollectArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("collectArguments");
+ for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+ if (verbosity >= 2)
+ System.out.println("collectArguments "+argType);
+ for (int nargs = 0; nargs < 10; nargs++) {
+ for (int pos = 0; pos < nargs; pos++) {
+ if (argType == int.class) continue; // FIXME Fail_4
+ testCollectArguments(argType, pos, nargs);
+ }
+ }
+ }
+ }
+ public void testCollectArguments(Class<?> argType, int pos, int nargs) throws Throwable {
+ countTest();
+ // fake up a MH with the same type as the desired adapter:
+ MethodHandle fake = ValueConversions.varargsArray(nargs);
+ fake = changeArgTypes(fake, argType);
+ MethodType newType = fake.type();
+ Object[] args = randomArgs(newType.parameterArray());
+ // here is what should happen:
+ Object[] collectedArgs = Arrays.copyOfRange(args, 0, pos+1);
+ collectedArgs[pos] = Arrays.copyOfRange(args, pos, args.length);
+ // here is the MH which will witness the collected argument tail:
+ MethodHandle target = ValueConversions.varargsArray(pos+1);
+ target = changeArgTypes(target, 0, pos, argType);
+ target = changeArgTypes(target, pos, pos+1, Object[].class);
+ if (verbosity >= 2)
+ System.out.println("collect from "+Arrays.asList(args)+" ["+pos+".."+nargs+"]");
+ MethodHandle result = MethodHandles.collectArguments(target, newType);
+ Object[] returnValue = (Object[]) result.invokeVarargs(args);
+// assertTrue(returnValue.length == pos+1 && returnValue[pos] instanceof Object[]);
+// returnValue[pos] = Arrays.asList((Object[]) returnValue[pos]);
+// collectedArgs[pos] = Arrays.asList((Object[]) collectedArgs[pos]);
+ assertArrayEquals(collectedArgs, returnValue);
+ }
+
+ @Test
+ public void testInsertArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("insertArguments");
+ for (int nargs = 0; nargs <= 4; nargs++) {
+ for (int ins = 0; ins <= 4; ins++) {
+ if (ins > MAX_ARG_INCREASE) continue; // FIXME Fail_6
+ for (int pos = 0; pos <= nargs; pos++) {
+ testInsertArguments(nargs, pos, ins);
+ }
+ }
+ }
+ }
+
+ void testInsertArguments(int nargs, int pos, int ins) throws Throwable {
+ countTest();
+ MethodHandle target = ValueConversions.varargsArray(nargs + ins);
+ Object[] args = randomArgs(target.type().parameterArray());
+ List<Object> resList = Arrays.asList(args);
+ List<Object> argsToPass = new ArrayList<Object>(resList);
+ List<Object> argsToInsert = argsToPass.subList(pos, pos + ins);
+ if (verbosity >= 2)
+ System.out.println("insert: "+argsToInsert+" into "+target);
+ MethodHandle target2 = MethodHandles.insertArguments(target, pos,
+ (Object[]) argsToInsert.toArray());
+ argsToInsert.clear(); // remove from argsToInsert
+ Object res2 = target2.invokeVarargs(argsToPass);
+ Object res2List = Arrays.asList((Object[])res2);
+ if (verbosity >= 2)
+ System.out.println("result: "+res2List);
+ //if (!resList.equals(res2List))
+ // System.out.println("*** fail at n/p/i = "+nargs+"/"+pos+"/"+ins+": "+resList+" => "+res2List);
+ assertEquals(resList, res2List);
+ }
+
+ @Test
+ public void testFilterArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("filterArguments");
+ for (int nargs = 1; nargs <= 6; nargs++) {
+ for (int pos = 0; pos < nargs; pos++) {
+ testFilterArguments(nargs, pos);
+ }
+ }
+ }
+
+ void testFilterArguments(int nargs, int pos) throws Throwable {
+ countTest();
+ MethodHandle target = ValueConversions.varargsList(nargs);
+ MethodHandle filter = ValueConversions.varargsList(1);
+ filter = MethodHandles.convertArguments(filter, filter.type().generic());
+ Object[] argsToPass = randomArgs(nargs, Object.class);
+ if (verbosity >= 2)
+ System.out.println("filter "+target+" at "+pos+" with "+filter);
+ MethodHandle[] filters = new MethodHandle[pos*2+1];
+ filters[pos] = filter;
+ MethodHandle target2 = MethodHandles.filterArguments(target, filters);
+ // Simulate expected effect of filter on arglist:
+ Object[] filteredArgs = argsToPass.clone();
+ filteredArgs[pos] = filter.invoke(filteredArgs[pos]);
+ List<Object> expected = Arrays.asList(filteredArgs);
+ Object result = target2.invokeVarargs(argsToPass);
+ if (verbosity >= 2)
+ System.out.println("result: "+result);
+ if (!expected.equals(result))
+ System.out.println("*** fail at n/p = "+nargs+"/"+pos+": "+argsToPass+" => "+result);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testFoldArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("foldArguments");
+ for (int nargs = 0; nargs <= 4; nargs++) {
+ for (int fold = 0; fold <= nargs; fold++) {
+ for (int pos = 0; pos <= nargs; pos++) {
+ testFoldArguments(nargs, pos, fold);
+ }
+ }
+ }
+ }
+
+ void testFoldArguments(int nargs, int pos, int fold) throws Throwable {
+ if (pos != 0) return; // can fold only at pos=0 for now
+ countTest();
+ MethodHandle target = ValueConversions.varargsList(1 + nargs);
+ MethodHandle combine = ValueConversions.varargsList(fold);
+ List<Object> argsToPass = Arrays.asList(randomArgs(nargs, Object.class));
+ if (verbosity >= 2)
+ System.out.println("fold "+target+" with "+combine);
+ MethodHandle target2 = MethodHandles.foldArguments(target, combine);
+ // Simulate expected effect of combiner on arglist:
+ List<Object> expected = new ArrayList<Object>(argsToPass);
+ List<Object> argsToFold = expected.subList(pos, pos + fold);
+ if (verbosity >= 2)
+ System.out.println("fold: "+argsToFold+" into "+target2);
+ Object foldedArgs = combine.invokeVarargs(argsToFold);
+ argsToFold.add(0, foldedArgs);
+ Object result = target2.invokeVarargs(argsToPass);
+ if (verbosity >= 2)
+ System.out.println("result: "+result);
+ if (!expected.equals(result))
+ System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testDropArguments() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("dropArguments");
+ for (int nargs = 0; nargs <= 4; nargs++) {
+ for (int drop = 1; drop <= 4; drop++) {
+ for (int pos = 0; pos <= nargs; pos++) {
+ testDropArguments(nargs, pos, drop);
+ }
+ }
+ }
+ }
+
+ void testDropArguments(int nargs, int pos, int drop) throws Throwable {
+ countTest();
+ MethodHandle target = ValueConversions.varargsArray(nargs);
+ Object[] args = randomArgs(target.type().parameterArray());
+ MethodHandle target2 = MethodHandles.dropArguments(target, pos,
+ Collections.nCopies(drop, Object.class).toArray(new Class[0]));
+ List<Object> resList = Arrays.asList(args);
+ List<Object> argsToDrop = new ArrayList<Object>(resList);
+ for (int i = drop; i > 0; i--) {
+ argsToDrop.add(pos, "blort#"+i);
+ }
+ Object res2 = target2.invokeVarargs(argsToDrop);
+ Object res2List = Arrays.asList((Object[])res2);
+ //if (!resList.equals(res2List))
+ // System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
+ assertEquals(resList, res2List);
+ }
+
+ @Test
+ public void testInvokers() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker");
+ // exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
+ Set<MethodType> done = new HashSet<MethodType>();
+ for (int i = 0; i <= 6; i++) {
+ MethodType gtype = MethodType.genericMethodType(i);
+ for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+ for (int j = -1; j < i; j++) {
+ MethodType type = gtype;
+ if (j < 0)
+ type = type.changeReturnType(argType);
+ else if (argType == void.class)
+ continue;
+ else
+ type = type.changeParameterType(j, argType);
+ if (argType.isPrimitive() && j != i-1) continue; // FIXME Fail_5
+ if (done.add(type))
+ testInvokers(type);
+ MethodType vtype = type.changeReturnType(void.class);
+ if (done.add(vtype))
+ testInvokers(vtype);
+ }
+ }
+ }
+ }
+
+ public void testInvokers(MethodType type) throws Throwable {
+ if (verbosity >= 2)
+ System.out.println("test invokers for "+type);
+ int nargs = type.parameterCount();
+ boolean testRetCode = type.returnType() != void.class;
+ MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "invokee",
+ MethodType.genericMethodType(0, true));
+ target = MethodHandles.collectArguments(target, type);
+ Object[] args = randomArgs(type.parameterArray());
+ List<Object> targetPlusArgs = new ArrayList<Object>(Arrays.asList(args));
+ targetPlusArgs.add(0, target);
+ int code = (Integer) invokee(args);
+ Object log = logEntry("invokee", args);
+ assertEquals(log.hashCode(), code);
+ assertCalled("invokee", args);
+ MethodHandle inv;
+ Object result;
+ // exact invoker
+ countTest();
+ calledLog.clear();
+ inv = MethodHandles.exactInvoker(type);
+ result = inv.invokeVarargs(targetPlusArgs);
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ // generic invoker
+ countTest();
+ inv = MethodHandles.genericInvoker(type);
+ if (nargs <= 3) {
+ calledLog.clear();
+ switch (nargs) {
+ case 0:
+ result = inv.invoke(target);
+ break;
+ case 1:
+ result = inv.invoke(target, args[0]);
+ break;
+ case 2:
+ result = inv.invoke(target, args[0], args[1]);
+ break;
+ case 3:
+ result = inv.invoke(target, args[0], args[1], args[2]);
+ break;
+ }
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ }
+ calledLog.clear();
+ result = inv.invokeVarargs(targetPlusArgs);
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ // varargs invoker #0
+ calledLog.clear();
+ inv = MethodHandles.varargsInvoker(type, 0);
+ result = inv.invoke(target, args);
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ if (nargs >= 1) {
+ // varargs invoker #1
+ calledLog.clear();
+ inv = MethodHandles.varargsInvoker(type, 1);
+ result = inv.invoke(target, args[0], Arrays.copyOfRange(args, 1, nargs));
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ }
+ if (nargs >= 2) {
+ // varargs invoker #2
+ calledLog.clear();
+ inv = MethodHandles.varargsInvoker(type, 2);
+ result = inv.invoke(target, args[0], args[1], Arrays.copyOfRange(args, 2, nargs));
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ }
+ if (nargs >= 3) {
+ // varargs invoker #3
+ calledLog.clear();
+ inv = MethodHandles.varargsInvoker(type, 3);
+ result = inv.invoke(target, args[0], args[1], args[2], Arrays.copyOfRange(args, 3, nargs));
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ }
+ for (int k = 0; k <= nargs; k++) {
+ // varargs invoker #0..N
+ countTest();
+ calledLog.clear();
+ inv = MethodHandles.varargsInvoker(type, k);
+ List<Object> targetPlusVarArgs = new ArrayList<Object>(targetPlusArgs);
+ List<Object> tailList = targetPlusVarArgs.subList(1+k, 1+nargs);
+ Object[] tail = tailList.toArray();
+ tailList.clear(); tailList.add(tail);
+ result = inv.invokeVarargs(targetPlusVarArgs);
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ }
+ // dynamic invoker
+ countTest();
+ CallSite site = new CallSite(MethodHandlesTest.class, "foo", type);
+ inv = MethodHandles.dynamicInvoker(site);
+ site.setTarget(target);
+ calledLog.clear();
+ result = inv.invokeVarargs(args);
+ if (testRetCode) assertEquals(code, result);
+ assertCalled("invokee", args);
+ }
+
+ static Object invokee(Object... args) {
+ return called("invokee", args).hashCode();
+ }
+
+ private static final String MISSING_ARG = "missingArg";
+ static Object targetIfEquals() {
+ return called("targetIfEquals");
+ }
+ static Object fallbackIfNotEquals() {
+ return called("fallbackIfNotEquals");
+ }
+ static Object targetIfEquals(Object x) {
+ assertEquals(x, MISSING_ARG);
+ return called("targetIfEquals", x);
+ }
+ static Object fallbackIfNotEquals(Object x) {
+ assertFalse(x.toString(), x.equals(MISSING_ARG));
+ return called("fallbackIfNotEquals", x);
+ }
+ static Object targetIfEquals(Object x, Object y) {
+ assertEquals(x, y);
+ return called("targetIfEquals", x, y);
+ }
+ static Object fallbackIfNotEquals(Object x, Object y) {
+ assertFalse(x.toString(), x.equals(y));
+ return called("fallbackIfNotEquals", x, y);
+ }
+ static Object targetIfEquals(Object x, Object y, Object z) {
+ assertEquals(x, y);
+ return called("targetIfEquals", x, y, z);
+ }
+ static Object fallbackIfNotEquals(Object x, Object y, Object z) {
+ assertFalse(x.toString(), x.equals(y));
+ return called("fallbackIfNotEquals", x, y, z);
+ }
+
+ @Test
+ public void testGuardWithTest() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("guardWithTest");
+ for (int nargs = 0; nargs <= 3; nargs++) {
+ if (nargs != 2) continue; // FIXME: test more later
+ testGuardWithTest(nargs, Object.class);
+ testGuardWithTest(nargs, String.class);
+ }
+ }
+ void testGuardWithTest(int nargs, Class<?> argClass) throws Throwable {
+ countTest();
+ MethodHandle test = PRIVATE.findVirtual(Object.class, "equals", MethodType.methodType(boolean.class, Object.class));
+ MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs));
+ MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs));
+ while (test.type().parameterCount() < nargs)
+ test = MethodHandles.dropArguments(test, test.type().parameterCount()-1, Object.class);
+ while (test.type().parameterCount() > nargs)
+ test = MethodHandles.insertArguments(test, 0, MISSING_ARG);
+ if (argClass != Object.class) {
+ test = changeArgTypes(test, argClass);
+ target = changeArgTypes(target, argClass);
+ fallback = changeArgTypes(fallback, argClass);
+ }
+ MethodHandle mh = MethodHandles.guardWithTest(test, target, fallback);
+ assertEquals(target.type(), mh.type());
+ Object[][] argLists = {
+ { },
+ { "foo" }, { MISSING_ARG },
+ { "foo", "foo" }, { "foo", "bar" },
+ { "foo", "foo", "baz" }, { "foo", "bar", "baz" }
+ };
+ for (Object[] argList : argLists) {
+ if (argList.length != nargs) continue;
+ boolean equals;
+ switch (nargs) {
+ case 0: equals = true; break;
+ case 1: equals = MISSING_ARG.equals(argList[0]); break;
+ default: equals = argList[0].equals(argList[1]); break;
+ }
+ String willCall = (equals ? "targetIfEquals" : "fallbackIfNotEquals");
+ if (verbosity >= 2)
+ System.out.println(logEntry(willCall, argList));
+ Object result = mh.invokeVarargs(argList);
+ assertCalled(willCall, argList);
+ }
+ }
+
+ @Test
+ public void testCatchException() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("catchException");
+ for (int nargs = 2; nargs <= 6; nargs++) {
+ for (int ti = 0; ti <= 1; ti++) {
+ boolean throwIt = (ti != 0);
+ testCatchException(int.class, new ClassCastException("testing"), throwIt, nargs);
+ testCatchException(void.class, new java.io.IOException("testing"), throwIt, nargs);
+ testCatchException(String.class, new LinkageError("testing"), throwIt, nargs);
+ }
+ }
+ }
+
+ private static <T extends Throwable>
+ Object throwOrReturn(Object normal, T exception) throws T {
+ if (exception != null) throw exception;
+ return normal;
+ }
+
+ void testCatchException(Class<?> returnType, Throwable thrown, boolean throwIt, int nargs) throws Throwable {
+ countTest();
+ if (verbosity >= 2)
+ System.out.println("catchException rt="+returnType+" throw="+throwIt+" nargs="+nargs);
+ Class<? extends Throwable> exType = thrown.getClass();
+ MethodHandle throwOrReturn
+ = PRIVATE.findStatic(MethodHandlesTest.class, "throwOrReturn",
+ MethodType.methodType(Object.class, Object.class, Throwable.class));
+ MethodHandle thrower = throwOrReturn;
+ while (thrower.type().parameterCount() < nargs)
+ thrower = MethodHandles.dropArguments(thrower, thrower.type().parameterCount(), Object.class);
+ MethodHandle target = MethodHandles.catchException(thrower,
+ thrown.getClass(), ValueConversions.varargsList(1+nargs));
+ assertEquals(thrower.type(), target.type());
+ //System.out.println("catching with "+target+" : "+throwOrReturn);
+ Object[] args = randomArgs(nargs, Object.class);
+ args[1] = (throwIt ? thrown : null);
+ Object returned = target.invokeVarargs(args);
+ //System.out.println("return from "+target+" : "+returned);
+ if (!throwIt) {
+ assertSame(args[0], returned);
+ } else {
+ List<Object> catchArgs = new ArrayList<Object>(Arrays.asList(args));
+ catchArgs.add(0, thrown);
+ assertEquals(catchArgs, returned);
+ }
+ }
+
+ @Test
+ public void testThrowException() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("throwException");
+ testThrowException(int.class, new ClassCastException("testing"));
+ testThrowException(void.class, new java.io.IOException("testing"));
+ testThrowException(String.class, new LinkageError("testing"));
+ }
+
+ void testThrowException(Class<?> returnType, Throwable thrown) throws Throwable {
+ countTest();
+ Class<? extends Throwable> exType = thrown.getClass();
+ MethodHandle target = MethodHandles.throwException(returnType, exType);
+ //System.out.println("throwing with "+target+" : "+thrown);
+ MethodType expectedType = MethodType.methodType(returnType, exType);
+ assertEquals(expectedType, target.type());
+ Throwable caught = null;
+ try {
+ Object res = target.invokeGeneric(thrown);
+ fail("got "+res+" instead of throwing "+thrown);
+ } catch (Throwable ex) {
+ if (ex != thrown) {
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ }
+ caught = ex;
+ }
+ assertSame(thrown, caught);
+ }
+
+ @Test
+ public void testCastFailure() throws Throwable {
+ if (CAN_SKIP_WORKING) return;
+ startTest("testCastFailure");
+ testCastFailure("cast/argument", 11000);
+ testCastFailure("unbox/argument", 11000);
+ testCastFailure("cast/return", 11000);
+ testCastFailure("unbox/return", 11000);
+ }
+
+ static class Surprise extends JavaMethodHandle {
+ Surprise() { super("value"); }
+ Object value(Object x) {
+ trace("value", x);
+ if (boo != null) return boo;
+ return x;
+ }
+ Object boo;
+ void boo(Object x) { boo = x; }
+
+ static void trace(String x, Object y) {
+ if (verbosity > 8) System.out.println(x+"="+y);
+ }
+ static Object refIdentity(Object x) { trace("ref.x", x); return x; }
+ static Integer boxIdentity(Integer x) { trace("box.x", x); return x; }
+ static int intIdentity(int x) { trace("int.x", x); return x; }
+ static MethodHandle REF_IDENTITY = PRIVATE.findStatic(
+ Surprise.class, "refIdentity",
+ MethodType.methodType(Object.class, Object.class));
+ static MethodHandle BOX_IDENTITY = PRIVATE.findStatic(
+ Surprise.class, "boxIdentity",
+ MethodType.methodType(Integer.class, Integer.class));
+ static MethodHandle INT_IDENTITY = PRIVATE.findStatic(
+ Surprise.class, "intIdentity",
+ MethodType.methodType(int.class, int.class));
+ }
+
+ void testCastFailure(String mode, int okCount) throws Throwable {
+ countTest(false);
+ if (verbosity > 1) System.out.println("mode="+mode);
+ Surprise boo = new Surprise();
+ MethodHandle identity = Surprise.REF_IDENTITY, surprise = boo;
+ if (mode.endsWith("/return")) {
+ if (mode.equals("unbox/return")) {
+ // fail on return to ((Integer)surprise).intValue
+ surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(int.class, Object.class));
+ identity = MethodHandles.convertArguments(identity, MethodType.methodType(int.class, Object.class));
+ } else if (mode.equals("cast/return")) {
+ // fail on return to (Integer)surprise
+ surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(Integer.class, Object.class));
+ identity = MethodHandles.convertArguments(identity, MethodType.methodType(Integer.class, Object.class));
+ }
+ } else if (mode.endsWith("/argument")) {
+ MethodHandle callee = null;
+ if (mode.equals("unbox/argument")) {
+ // fail on handing surprise to int argument
+ callee = Surprise.INT_IDENTITY;
+ } else if (mode.equals("cast/argument")) {
+ // fail on handing surprise to Integer argument
+ callee = Surprise.BOX_IDENTITY;
+ }
+ if (callee != null) {
+ callee = MethodHandles.convertArguments(callee, MethodType.genericMethodType(1));
+ surprise = MethodHandles.filterArguments(callee, surprise);
+ identity = MethodHandles.filterArguments(callee, identity);
+ }
+ }
+ assertNotSame(mode, surprise, boo);
+ identity = MethodHandles.convertArguments(identity, MethodType.genericMethodType(1));
+ surprise = MethodHandles.convertArguments(surprise, MethodType.genericMethodType(1));
+ Object x = 42;
+ for (int i = 0; i < okCount; i++) {
+ Object y = identity.invoke(x);
+ assertEquals(x, y);
+ Object z = surprise.invoke(x);
+ assertEquals(x, z);
+ }
+ boo.boo("Boo!");
+ Object y = identity.invoke(x);
+ assertEquals(x, y);
+ try {
+ Object z = surprise.invoke(x);
+ System.out.println("Failed to throw; got z="+z);
+ assertTrue(false);
+ } catch (Exception ex) {
+ if (verbosity > 1)
+ System.out.println("caught "+ex);
+ if (verbosity > 2)
+ ex.printStackTrace();
+ assertTrue(ex instanceof ClassCastException
+ // FIXME: accept only one of the two for any given unit test
+ || ex instanceof WrongMethodTypeException
+ );
+ }
+ }
+
+}
+// Local abbreviated copy of sun.dyn.util.ValueConversions
+class ValueConversions {
+ private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
+ private static final Object[] NO_ARGS_ARRAY = {};
+ private static Object[] makeArray(Object... args) { return args; }
+ private static Object[] array() { return NO_ARGS_ARRAY; }
+ private static Object[] array(Object a0)
+ { return makeArray(a0); }
+ private static Object[] array(Object a0, Object a1)
+ { return makeArray(a0, a1); }
+ private static Object[] array(Object a0, Object a1, Object a2)
+ { return makeArray(a0, a1, a2); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3)
+ { return makeArray(a0, a1, a2, a3); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4)
+ { return makeArray(a0, a1, a2, a3, a4); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5)
+ { return makeArray(a0, a1, a2, a3, a4, a5); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9)
+ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ static MethodHandle[] makeArrays() {
+ ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = arrays.size();
+ MethodType type = MethodType.genericMethodType(nargs).changeReturnType(Object[].class);
+ String name = "array";
+ MethodHandle array = null;
+ try {
+ array = lookup.findStatic(ValueConversions.class, name, type);
+ } catch (NoAccessException ex) {
+ }
+ if (array == null) break;
+ arrays.add(array);
+ }
+ assert(arrays.size() == 11); // current number of methods
+ return arrays.toArray(new MethodHandle[0]);
+ }
+ static final MethodHandle[] ARRAYS = makeArrays();
+
+ /** Return a method handle that takes the indicated number of Object
+ * arguments and returns an Object array of them, as if for varargs.
+ */
+ public static MethodHandle varargsArray(int nargs) {
+ if (nargs < ARRAYS.length)
+ return ARRAYS[nargs];
+ // else need to spin bytecode or do something else fancy
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
+ private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
+ private static List<Object> list() { return NO_ARGS_LIST; }
+ private static List<Object> list(Object a0)
+ { return makeList(a0); }
+ private static List<Object> list(Object a0, Object a1)
+ { return makeList(a0, a1); }
+ private static List<Object> list(Object a0, Object a1, Object a2)
+ { return makeList(a0, a1, a2); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
+ { return makeList(a0, a1, a2, a3); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4)
+ { return makeList(a0, a1, a2, a3, a4); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5)
+ { return makeList(a0, a1, a2, a3, a4, a5); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9)
+ { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ static MethodHandle[] makeLists() {
+ ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = arrays.size();
+ MethodType type = MethodType.genericMethodType(nargs).changeReturnType(List.class);
+ String name = "list";
+ MethodHandle array = null;
+ try {
+ array = lookup.findStatic(ValueConversions.class, name, type);
+ } catch (NoAccessException ex) {
+ }
+ if (array == null) break;
+ arrays.add(array);
+ }
+ assert(arrays.size() == 11); // current number of methods
+ return arrays.toArray(new MethodHandle[0]);
+ }
+ static final MethodHandle[] LISTS = makeLists();
+
+ /** Return a method handle that takes the indicated number of Object
+ * arguments and returns List.
+ */
+ public static MethodHandle varargsList(int nargs) {
+ if (nargs < LISTS.length)
+ return LISTS[nargs];
+ // else need to spin bytecode or do something else fancy
+ throw new UnsupportedOperationException("NYI");
+ }
+}
+// This guy tests access from outside the same package member, but inside
+// the package itself.
+class PackageSibling {
+ static Lookup lookup() {
+ return MethodHandles.lookup();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/CeilAndFloorTests.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6908131
+ * @summary Check for correct implementation of Math.ceil and Math.floor
+ */
+
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+public class CeilAndFloorTests {
+ private static int testCeilCase(double input, double expected) {
+ int failures = 0;
+ failures += Tests.test("Math.ceil", input, Math.ceil(input), expected);
+ failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected);
+ return failures;
+ }
+
+ private static int testFloorCase(double input, double expected) {
+ int failures = 0;
+ failures += Tests.test("Math.floor", input, Math.floor(input), expected);
+ failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected);
+ return failures;
+ }
+
+ private static int nearIntegerTests() {
+ int failures = 0;
+
+ double [] fixedPoints = {
+ -0.0,
+ 0.0,
+ -1.0,
+ 1.0,
+ -0x1.0p52,
+ 0x1.0p52,
+ -Double.MAX_VALUE,
+ Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY,
+ Double.NaN,
+ };
+
+ for(double fixedPoint : fixedPoints) {
+ failures += testCeilCase(fixedPoint, fixedPoint);
+ failures += testFloorCase(fixedPoint, fixedPoint);
+ }
+
+ for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) {
+ double powerOfTwo = Math.scalb(1.0, i);
+ double neighborDown = FpUtils.nextDown(powerOfTwo);
+ double neighborUp = Math.nextUp(powerOfTwo);
+
+ if (i < 0) {
+ failures += testCeilCase( powerOfTwo, 1.0);
+ failures += testCeilCase(-powerOfTwo, -0.0);
+
+ failures += testFloorCase( powerOfTwo, 0.0);
+ failures += testFloorCase(-powerOfTwo, -1.0);
+
+ failures += testCeilCase( neighborDown, 1.0);
+ failures += testCeilCase(-neighborDown, -0.0);
+
+ failures += testFloorCase( neighborUp, 0.0);
+ failures += testFloorCase(-neighborUp, -1.0);
+ } else {
+ failures += testCeilCase(powerOfTwo, powerOfTwo);
+ failures += testFloorCase(powerOfTwo, powerOfTwo);
+
+ if (neighborDown==Math.rint(neighborDown)) {
+ failures += testCeilCase( neighborDown, neighborDown);
+ failures += testCeilCase(-neighborDown, -neighborDown);
+
+ failures += testFloorCase( neighborDown, neighborDown);
+ failures += testFloorCase(-neighborDown,-neighborDown);
+ } else {
+ failures += testCeilCase( neighborDown, powerOfTwo);
+ failures += testFloorCase(-neighborDown, -powerOfTwo);
+ }
+
+ if (neighborUp==Math.rint(neighborUp)) {
+ failures += testCeilCase(neighborUp, neighborUp);
+ failures += testCeilCase(-neighborUp, -neighborUp);
+
+ failures += testFloorCase(neighborUp, neighborUp);
+ failures += testFloorCase(-neighborUp, -neighborUp);
+ } else {
+ failures += testFloorCase(neighborUp, powerOfTwo);
+ failures += testCeilCase(-neighborUp, -powerOfTwo);
+ }
+ }
+ }
+
+ for(int i = -(0x10000); i <= 0x10000; i++) {
+ double d = (double) i;
+ double neighborDown = FpUtils.nextDown(d);
+ double neighborUp = Math.nextUp(d);
+
+ failures += testCeilCase( d, d);
+ failures += testCeilCase(-d, -d);
+
+ failures += testFloorCase( d, d);
+ failures += testFloorCase(-d, -d);
+
+ if (Math.abs(d) > 1.0) {
+ failures += testCeilCase( neighborDown, d);
+ failures += testCeilCase(-neighborDown, -d+1);
+
+ failures += testFloorCase( neighborUp, d);
+ failures += testFloorCase(-neighborUp, -d-1);
+ }
+ }
+
+ return failures;
+ }
+
+ public static int roundingTests() {
+ int failures = 0;
+ double [][] testCases = {
+ { Double.MIN_VALUE, 1.0},
+ {-Double.MIN_VALUE, -0.0},
+ { FpUtils.nextDown(DoubleConsts.MIN_NORMAL), 1.0},
+ {-FpUtils.nextDown(DoubleConsts.MIN_NORMAL), -0.0},
+ { DoubleConsts.MIN_NORMAL, 1.0},
+ {-DoubleConsts.MIN_NORMAL, -0.0},
+
+ { 0.1, 1.0},
+ {-0.1, -0.0},
+
+ { 0.5, 1.0},
+ {-0.5, -0.0},
+
+ { 1.5, 2.0},
+ {-1.5, -1.0},
+
+ { 2.5, 3.0},
+ {-2.5, -2.0},
+
+ { FpUtils.nextDown(1.0), 1.0},
+ { FpUtils.nextDown(-1.0), -1.0},
+
+ { Math.nextUp(1.0), 2.0},
+ { Math.nextUp(-1.0), -0.0},
+
+ { 0x1.0p51, 0x1.0p51},
+ {-0x1.0p51, -0x1.0p51},
+
+ { FpUtils.nextDown(0x1.0p51), 0x1.0p51},
+ {-Math.nextUp(0x1.0p51), -0x1.0p51},
+
+ { Math.nextUp(0x1.0p51), 0x1.0p51+1},
+ {-FpUtils.nextDown(0x1.0p51), -0x1.0p51+1},
+
+ { FpUtils.nextDown(0x1.0p52), 0x1.0p52},
+ {-Math.nextUp(0x1.0p52), -0x1.0p52-1.0},
+
+ { Math.nextUp(0x1.0p52), 0x1.0p52+1.0},
+ {-FpUtils.nextDown(0x1.0p52), -0x1.0p52+1.0},
+ };
+
+ for(double[] testCase : testCases) {
+ failures += testCeilCase(testCase[0], testCase[1]);
+ failures += testFloorCase(-testCase[0], -testCase[1]);
+ }
+ return failures;
+ }
+
+ public static void main(String... args) {
+ int failures = 0;
+
+ failures += nearIntegerTests();
+ failures += roundingTests();
+
+ if (failures > 0) {
+ System.err.println("Testing {Math, StrictMath}.ceil incurred "
+ + failures + " failures.");
+ throw new RuntimeException();
+ }
+ }
+}
--- a/jdk/test/java/math/BigInteger/BigIntegerTest.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/math/BigInteger/BigIntegerTest.java Wed Jul 05 17:04:56 2017 +0200
@@ -642,37 +642,71 @@
for(int i = 0; i < bitPatterns.length; i++) {
BigInteger b1 = new BigInteger(bitPatterns[i], 16);
+ BigInteger b2 = null;
File f = new File("serialtest");
FileOutputStream fos = new FileOutputStream(f);
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(b1);
- oos.flush();
- oos.close();
- FileInputStream fis = new FileInputStream(f);
- ObjectInputStream ois = new ObjectInputStream(fis);
- BigInteger b2 = (BigInteger)ois.readObject();
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
+ try {
+ oos.writeObject(b1);
+ oos.flush();
+ } finally {
+ oos.close();
+ }
- if (!b1.equals(b2) ||
- !b1.equals(b1.or(b2))) {
- failCount++;
- System.err.println("Serialized failed for hex " +
- b1.toString(16));
+ FileInputStream fis = new FileInputStream(f);
+ try {
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ try {
+ b2 = (BigInteger)ois.readObject();
+ } finally {
+ ois.close();
+ }
+ } finally {
+ fis.close();
+ }
+
+ if (!b1.equals(b2) ||
+ !b1.equals(b1.or(b2))) {
+ failCount++;
+ System.err.println("Serialized failed for hex " +
+ b1.toString(16));
+ }
+ } finally {
+ fos.close();
}
f.delete();
}
for(int i=0; i<10; i++) {
BigInteger b1 = fetchNumber(rnd.nextInt(100));
+ BigInteger b2 = null;
File f = new File("serialtest");
FileOutputStream fos = new FileOutputStream(f);
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(b1);
- oos.flush();
- oos.close();
- FileInputStream fis = new FileInputStream(f);
- ObjectInputStream ois = new ObjectInputStream(fis);
- BigInteger b2 = (BigInteger)ois.readObject();
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
+ try {
+ oos.writeObject(b1);
+ oos.flush();
+ } finally {
+ oos.close();
+ }
+
+ FileInputStream fis = new FileInputStream(f);
+ try {
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ try {
+ b2 = (BigInteger)ois.readObject();
+ } finally {
+ ois.close();
+ }
+ } finally {
+ fis.close();
+ }
+ } finally {
+ fos.close();
+ }
if (!b1.equals(b2) ||
!b1.equals(b1.or(b2)))
--- a/jdk/test/java/nio/Buffer/Basic-X.java.template Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/Basic-X.java.template Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final $type$[] VALUES = {
+ $Fulltype$.MIN_VALUE,
+ ($type$) -1,
+ ($type$) 0,
+ ($type$) 1,
+ $Fulltype$.MAX_VALUE,
+#if[float]
+ $Fulltype$.NEGATIVE_INFINITY,
+ $Fulltype$.POSITIVE_INFINITY,
+ $Fulltype$.NaN,
+ ($type$) -0.0,
+#end[float]
+#if[double]
+ $Fulltype$.NEGATIVE_INFINITY,
+ $Fulltype$.POSITIVE_INFINITY,
+ $Fulltype$.NaN,
+ ($type$) -0.0,
+#end[double]
+ };
+
private static void relGet($Type$Buffer b) {
int n = b.capacity();
$type$ v;
@@ -309,6 +329,12 @@
#end[byte]
+ private static void fail(String problem,
+ $Type$Buffer xb, $Type$Buffer yb,
+ $type$ x, $type$ y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for ($type$ x : VALUES) {
+ $Type$Buffer xb = $Type$Buffer.wrap(new $type$[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for ($type$ y : VALUES) {
+ $Type$Buffer yb = $Type$Buffer.wrap(new $type$[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != $Fulltype$.compare(x, y)) {
+#if[float]
+ if (x == 0.0 && y == 0.0) continue;
+#end[float]
+#if[double]
+ if (x == 0.0 && y == 0.0) continue;
+#end[double]
+ fail("Incorrect results for $Type$Buffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for $Type$Buffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicByte.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicByte.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final byte[] VALUES = {
+ Byte.MIN_VALUE,
+ (byte) -1,
+ (byte) 0,
+ (byte) 1,
+ Byte.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(ByteBuffer b) {
int n = b.capacity();
byte v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ ByteBuffer xb, ByteBuffer yb,
+ byte x, byte y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (byte x : VALUES) {
+ ByteBuffer xb = ByteBuffer.wrap(new byte[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (byte y : VALUES) {
+ ByteBuffer yb = ByteBuffer.wrap(new byte[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Byte.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for ByteBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for ByteBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicChar.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicChar.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final char[] VALUES = {
+ Character.MIN_VALUE,
+ (char) -1,
+ (char) 0,
+ (char) 1,
+ Character.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(CharBuffer b) {
int n = b.capacity();
char v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ CharBuffer xb, CharBuffer yb,
+ char x, char y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (char x : VALUES) {
+ CharBuffer xb = CharBuffer.wrap(new char[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (char y : VALUES) {
+ CharBuffer yb = CharBuffer.wrap(new char[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Character.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for CharBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for CharBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicDouble.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicDouble.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final double[] VALUES = {
+ Double.MIN_VALUE,
+ (double) -1,
+ (double) 0,
+ (double) 1,
+ Double.MAX_VALUE,
+
+
+
+
+
+
+
+ Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY,
+ Double.NaN,
+ (double) -0.0,
+
+ };
+
private static void relGet(DoubleBuffer b) {
int n = b.capacity();
double v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ DoubleBuffer xb, DoubleBuffer yb,
+ double x, double y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (double x : VALUES) {
+ DoubleBuffer xb = DoubleBuffer.wrap(new double[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (double y : VALUES) {
+ DoubleBuffer yb = DoubleBuffer.wrap(new double[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Double.compare(x, y)) {
+
+
+
+
+ if (x == 0.0 && y == 0.0) continue;
+
+ fail("Incorrect results for DoubleBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for DoubleBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicFloat.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicFloat.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final float[] VALUES = {
+ Float.MIN_VALUE,
+ (float) -1,
+ (float) 0,
+ (float) 1,
+ Float.MAX_VALUE,
+
+ Float.NEGATIVE_INFINITY,
+ Float.POSITIVE_INFINITY,
+ Float.NaN,
+ (float) -0.0,
+
+
+
+
+
+
+
+ };
+
private static void relGet(FloatBuffer b) {
int n = b.capacity();
float v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ FloatBuffer xb, FloatBuffer yb,
+ float x, float y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (float x : VALUES) {
+ FloatBuffer xb = FloatBuffer.wrap(new float[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (float y : VALUES) {
+ FloatBuffer yb = FloatBuffer.wrap(new float[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Float.compare(x, y)) {
+
+ if (x == 0.0 && y == 0.0) continue;
+
+
+
+
+ fail("Incorrect results for FloatBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for FloatBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicInt.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicInt.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final int[] VALUES = {
+ Integer.MIN_VALUE,
+ (int) -1,
+ (int) 0,
+ (int) 1,
+ Integer.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(IntBuffer b) {
int n = b.capacity();
int v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ IntBuffer xb, IntBuffer yb,
+ int x, int y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (int x : VALUES) {
+ IntBuffer xb = IntBuffer.wrap(new int[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (int y : VALUES) {
+ IntBuffer yb = IntBuffer.wrap(new int[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Integer.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for IntBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for IntBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicLong.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicLong.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final long[] VALUES = {
+ Long.MIN_VALUE,
+ (long) -1,
+ (long) 0,
+ (long) 1,
+ Long.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(LongBuffer b) {
int n = b.capacity();
long v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ LongBuffer xb, LongBuffer yb,
+ long x, long y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (long x : VALUES) {
+ LongBuffer xb = LongBuffer.wrap(new long[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (long y : VALUES) {
+ LongBuffer yb = LongBuffer.wrap(new long[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Long.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for LongBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for LongBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicShort.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/BasicShort.java Wed Jul 05 17:04:56 2017 +0200
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final short[] VALUES = {
+ Short.MIN_VALUE,
+ (short) -1,
+ (short) 0,
+ (short) 1,
+ Short.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(ShortBuffer b) {
int n = b.capacity();
short v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ ShortBuffer xb, ShortBuffer yb,
+ short x, short y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (short x : VALUES) {
+ ShortBuffer xb = ShortBuffer.wrap(new short[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (short y : VALUES) {
+ ShortBuffer yb = ShortBuffer.wrap(new short[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Short.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for ShortBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for ShortBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
--- a/jdk/test/java/nio/Buffer/genBasic.sh Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/nio/Buffer/genBasic.sh Wed Jul 05 17:04:56 2017 +0200
@@ -36,5 +36,3 @@
gen long Long Long
gen float Float Float
gen double Double Double
-
-rm -rf build
--- a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Wed Jul 05 17:04:56 2017 +0200
@@ -146,13 +146,13 @@
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
+ oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8);
+
+ /* TODO: unbounded queue implementations are prone to OOME
+ oneRun(new PriorityBlockingQueue<Integer>(iters / 2 * pairs), pairs, iters / 4);
oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
oneRun(new LTQasSQ<Integer>(), pairs, iters);
oneRun(new HalfSyncLTQ<Integer>(), pairs, iters);
- oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8);
-
- /* PriorityBlockingQueue is unbounded
- oneRun(new PriorityBlockingQueue<Integer>(iters / 2 * pairs), pairs, iters / 4);
*/
}
--- a/jdk/test/java/util/jar/JarFile/TurkCert.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/java/util/jar/JarFile/TurkCert.java Wed Jul 05 17:04:56 2017 +0200
@@ -26,6 +26,7 @@
* @bug 4624534
* @summary Make sure jar certificates work for Turkish locale
* @author kladko
+ * @run main/othervm TurkCert
*/
import java.util.*;
--- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java Wed Jul 05 17:04:56 2017 +0200
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4635230 6283345 6303830 6824440
+ * @bug 4635230 6283345 6303830 6824440 6867348
* @summary Basic unit tests for generating XML Signatures with JSR 105
* @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
* X509KeySelector.java GenerationTests.java
@@ -126,13 +126,14 @@
test_create_signature_x509_is();
test_create_signature_x509_ski();
test_create_signature_x509_sn();
-// test_create_signature();
+ test_create_signature();
test_create_exc_signature();
test_create_sign_spec();
test_create_signature_enveloping_sha256_dsa();
test_create_signature_enveloping_sha384_rsa_sha256();
test_create_signature_enveloping_sha512_rsa_sha384();
test_create_signature_enveloping_sha512_rsa_sha512();
+ test_create_signature_reference_dependency();
}
private static void setup() throws Exception {
@@ -410,6 +411,55 @@
System.out.println();
}
+ static void test_create_signature_reference_dependency() throws Exception {
+ System.out.println("* Generating signature-reference-dependency.xml");
+ // create references
+ List<Reference> refs = Collections.singletonList
+ (fac.newReference("#object-1", sha1));
+
+ // create SignedInfo
+ SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs);
+
+ // create objects
+ List<XMLStructure> objs = new ArrayList<XMLStructure>();
+
+ // Object 1
+ List<Reference> manRefs = Collections.singletonList
+ (fac.newReference("#object-2", sha1));
+ objs.add(fac.newXMLObject(Collections.singletonList
+ (fac.newManifest(manRefs, "manifest-1")), "object-1", null, null));
+
+ // Object 2
+ Document doc = db.newDocument();
+ Element nc = doc.createElementNS(null, "NonCommentandus");
+ nc.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
+ nc.appendChild(doc.createComment(" Commentandum "));
+ objs.add(fac.newXMLObject(Collections.singletonList
+ (new DOMStructure(nc)), "object-2", null, null));
+
+ // create XMLSignature
+ XMLSignature sig = fac.newXMLSignature(si, rsa, objs, "signature", null);
+ DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc);
+
+ sig.sign(dsc);
+
+// dumpDocument(doc, new PrintWriter(System.out));
+
+ DOMValidateContext dvc = new DOMValidateContext
+ (kvks, doc.getDocumentElement());
+ XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
+
+ if (sig.equals(sig2) == false) {
+ throw new Exception
+ ("Unmarshalled signature is not equal to generated signature");
+ }
+ if (sig2.validate(dvc) == false) {
+ throw new Exception("Validation of generated signature failed");
+ }
+
+ System.out.println();
+ }
+
static void test_create_signature() throws Exception {
System.out.println("* Generating signature.xml");
@@ -645,6 +695,7 @@
envDoc.getElementsByTagName("YoursSincerely").item(0);
DOMSignContext dsc = new DOMSignContext(signingKey, ys);
+ dsc.setURIDereferencer(httpUd);
sig.sign(dsc);
@@ -660,6 +711,7 @@
DOMValidateContext dvc = new DOMValidateContext
(new X509KeySelector(ks), sigElement);
+ dvc.setURIDereferencer(httpUd);
File f = new File(
System.getProperty("dir.test.vector.baltimore") +
System.getProperty("file.separator") +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/BadKdc.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import sun.security.krb5.Config;
+
+public class BadKdc {
+
+ // Matches the krb5 debug output:
+ // >>> KDCCommunication: kdc=kdc.rabbit.hole UDP:14319, timeout=2000,...
+ // ^ kdc# ^ timeout
+ static final Pattern re = Pattern.compile(
+ ">>> KDCCommunication: kdc=kdc.rabbit.hole UDP:(\\d)...., " +
+ "timeout=(\\d)000,");
+ public static void go(int[]... expected)
+ throws Exception {
+ System.setProperty("sun.security.krb5.debug", "true");
+
+ // Make sure KDCs' ports starts with 1 and 2 and 3,
+ // useful for checking debug output.
+ int p1 = 10000 + new java.util.Random().nextInt(10000);
+ int p2 = 20000 + new java.util.Random().nextInt(10000);
+ int p3 = 30000 + new java.util.Random().nextInt(10000);
+
+ FileWriter fw = new FileWriter("alternative-krb5.conf");
+
+ fw.write("[libdefaults]\n" +
+ "default_realm = " + OneKDC.REALM + "\n" +
+ "kdc_timeout = 2000\n");
+ fw.write("[realms]\n" + OneKDC.REALM + " = {\n" +
+ "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" +
+ "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" +
+ "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" +
+ "}\n");
+
+ fw.close();
+ System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
+ Config.refresh();
+
+ // Turn on k3 only
+ KDC k3 = on(p3);
+
+ test(expected[0]);
+ test(expected[1]);
+ Config.refresh();
+ test(expected[2]);
+
+ k3.terminate(); // shutdown k3
+ on(p2); // k2 is on
+ test(expected[3]);
+ on(p1); // k1 and k2 is on
+ test(expected[4]);
+ }
+
+ private static KDC on(int p) throws Exception {
+ KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true);
+ k.addPrincipal(OneKDC.USER, OneKDC.PASS);
+ k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
+ return k;
+ }
+
+ /**
+ * One round of test for max_retries and timeout.
+ * @param timeout the expected timeout
+ * @param expected the expected kdc# timeout kdc# timeout...
+ */
+ private static void test(int... expected) throws Exception {
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ PrintStream oldout = System.out;
+ System.setOut(new PrintStream(bo));
+ Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ System.setOut(oldout);
+
+ String[] lines = new String(bo.toByteArray()).split("\n");
+ System.out.println("----------------- TEST -----------------");
+ int count = 0;
+ for (String line: lines) {
+ Matcher m = re.matcher(line);
+ if (m.find()) {
+ System.out.println(line);
+ if (Integer.parseInt(m.group(1)) != expected[count++] ||
+ Integer.parseInt(m.group(2)) != expected[count++]) {
+ throw new Exception("Fail here");
+ }
+ }
+ }
+ if (count != expected.length) {
+ throw new Exception("Less rounds");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/BadKdc1.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6843127
+ * @run main/timeout=300 BadKdc1
+ * @summary krb5 should not try to access unavailable kdc too often
+ */
+
+import java.io.*;
+import java.security.Security;
+
+public class BadKdc1 {
+
+ public static void main(String[] args)
+ throws Exception {
+ Security.setProperty("krb5.kdc.bad.policy", "tryLess");
+ BadKdc.go(
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
+ // The above line means try kdc1 for 2 seconds, then kdc1
+ // for 2 seconds,..., finally kdc3 for 2 seconds.
+ new int[]{1,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
+ // refresh
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
+ // k3 off, k2 on
+ new int[]{1,2,2,2,1,2,2,2}, // 1
+ // k1 on
+ new int[]{1,2,1,2} // empty
+ );
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/BadKdc2.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6843127
+ * @run main/timeout=300 BadKdc2
+ * @summary krb5 should not try to access unavailable kdc too often
+ */
+
+import java.io.*;
+import java.security.Security;
+
+public class BadKdc2 {
+
+ public static void main(String[] args)
+ throws Exception {
+ Security.setProperty("krb5.kdc.bad.policy", "tryLess:2,1000");
+ BadKdc.go(
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
+ new int[]{1,1,1,1,2,1,2,1,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
+ // refresh
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
+ // k3 off, k2 on
+ new int[]{1,1,1,1,2,1,1,1,1,1,2,2}, // 1
+ // k1 on
+ new int[]{1,1,1,2} // empty
+ );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/BadKdc3.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6843127
+ * @run main/timeout=300 BadKdc3
+ * @summary krb5 should not try to access unavailable kdc too often
+ */
+
+import java.io.*;
+import java.security.Security;
+
+public class BadKdc3 {
+
+ public static void main(String[] args)
+ throws Exception {
+ Security.setProperty("krb5.kdc.bad.policy", "tryLast");
+ BadKdc.go(
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,3,2}, // 1, 2
+ new int[]{3,2,3,2}, // 1, 2
+ // refresh
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,3,2}, // 1, 2
+ // k3 off, k2 on
+ new int[]{3,2,3,2,3,2,1,2,1,2,1,2,2,2,2,2}, // 1, 3
+ // k1 on
+ new int[]{2,2,2,2} // 1, 3
+ );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/BadKdc4.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6843127
+ * @run main/timeout=300 BadKdc4
+ * @summary krb5 should not try to access unavailable kdc too often
+ */
+
+import java.io.*;
+import java.security.Security;
+
+public class BadKdc4 {
+
+ public static void main(String[] args)
+ throws Exception {
+ Security.setProperty("krb5.kdc.bad.policy", "");
+ BadKdc.go(
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
+ // refresh
+ new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
+ // k3 off, k2 on
+ new int[]{1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2},
+ // k1 on
+ new int[]{1,2,1,2}
+ );
+ }
+}
--- a/jdk/test/sun/security/krb5/auto/KDC.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/sun/security/krb5/auto/KDC.java Wed Jul 05 17:04:56 2017 +0200
@@ -141,6 +141,10 @@
// Options
private Map<Option,Object> options = new HashMap<Option,Object>();
+ private Thread thread1, thread2, thread3;
+ DatagramSocket u1 = null;
+ ServerSocket t1 = null;
+
/**
* Option names, to be expanded forever.
*/
@@ -480,8 +484,9 @@
Method stringToKey = EncryptionKey.class.getDeclaredMethod("stringToKey", char[].class, String.class, byte[].class, Integer.TYPE);
stringToKey.setAccessible(true);
Integer kvno = null;
- // For service whose password ending with a number, use it as kvno
- if (p.toString().indexOf('/') >= 0) {
+ // For service whose password ending with a number, use it as kvno.
+ // Kvno must be postive.
+ if (p.toString().indexOf('/') > 0) {
char[] pass = getPassword(p, server);
if (Character.isDigit(pass[pass.length-1])) {
kvno = pass[pass.length-1] - '0';
@@ -940,8 +945,6 @@
* @throws java.io.IOException for any communication error
*/
protected void startServer(int port, boolean asDaemon) throws IOException {
- DatagramSocket u1 = null;
- ServerSocket t1 = null;
if (port > 0) {
u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1"));
t1 = new ServerSocket(port);
@@ -966,7 +969,7 @@
this.port = port;
// The UDP consumer
- Thread thread = new Thread() {
+ thread1 = new Thread() {
public void run() {
while (true) {
try {
@@ -982,11 +985,11 @@
}
}
};
- thread.setDaemon(asDaemon);
- thread.start();
+ thread1.setDaemon(asDaemon);
+ thread1.start();
// The TCP consumer
- thread = new Thread() {
+ thread2 = new Thread() {
public void run() {
while (true) {
try {
@@ -1004,11 +1007,11 @@
}
}
};
- thread.setDaemon(asDaemon);
- thread.start();
+ thread2.setDaemon(asDaemon);
+ thread2.start();
// The dispatcher
- thread = new Thread() {
+ thread3 = new Thread() {
public void run() {
while (true) {
try {
@@ -1018,10 +1021,21 @@
}
}
};
- thread.setDaemon(true);
- thread.start();
+ thread3.setDaemon(true);
+ thread3.start();
}
+ public void terminate() {
+ try {
+ thread1.stop();
+ thread2.stop();
+ thread3.stop();
+ u1.close();
+ t1.close();
+ } catch (Exception e) {
+ // OK
+ }
+ }
/**
* Helper class to encapsulate a job in a KDC.
*/
--- a/jdk/test/sun/security/krb5/auto/MoreKvno.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/sun/security/krb5/auto/MoreKvno.java Wed Jul 05 17:04:56 2017 +0200
@@ -24,15 +24,20 @@
/*
* @test
* @bug 6893158
+ * @bug 6907425
* @summary AP_REQ check should use key version number
*/
+import org.ietf.jgss.GSSException;
import sun.security.jgss.GSSUtil;
+import sun.security.krb5.KrbException;
import sun.security.krb5.PrincipalName;
import sun.security.krb5.internal.ktab.KeyTab;
+import sun.security.krb5.internal.Krb5;
public class MoreKvno {
+ static PrincipalName p;
public static void main(String[] args)
throws Exception {
@@ -41,21 +46,40 @@
// Rewrite keytab, 3 set of keys with different kvno
KeyTab ktab = KeyTab.create(OneKDC.KTAB);
- PrincipalName p = new PrincipalName(OneKDC.SERVER+"@"+OneKDC.REALM, PrincipalName.KRB_NT_SRV_HST);
- ktab.addEntry(p, "pass0".toCharArray(), 0);
+ p = new PrincipalName(
+ OneKDC.SERVER+"@"+OneKDC.REALM, PrincipalName.KRB_NT_SRV_HST);
+ ktab.addEntry(p, "pass1".toCharArray(), 1);
+ ktab.addEntry(p, "pass3".toCharArray(), 3);
ktab.addEntry(p, "pass2".toCharArray(), 2);
- ktab.addEntry(p, "pass1".toCharArray(), 1);
ktab.save();
- kdc.addPrincipal(OneKDC.SERVER, "pass1".toCharArray());
- go(OneKDC.SERVER, "com.sun.security.jgss.krb5.accept");
- kdc.addPrincipal(OneKDC.SERVER, "pass2".toCharArray());
+ char[] pass = "pass2".toCharArray();
+ kdc.addPrincipal(OneKDC.SERVER, pass);
+ go(OneKDC.SERVER, "com.sun.security.jgss.krb5.accept", pass);
+
+ pass = "pass3".toCharArray();
+ kdc.addPrincipal(OneKDC.SERVER, pass);
// "server" initiate also, check pass2 is used at authentication
- go(OneKDC.SERVER, "server");
+ go(OneKDC.SERVER, "server", pass);
+
+ try {
+ pass = "pass4".toCharArray();
+ kdc.addPrincipal(OneKDC.SERVER, pass);
+ go(OneKDC.SERVER, "com.sun.security.jgss.krb5.accept", pass);
+ throw new Exception("This test should fail");
+ } catch (GSSException gsse) {
+ KrbException ke = (KrbException)gsse.getCause();
+ if (ke.returnCode() != Krb5.KRB_AP_ERR_BADKEYVER) {
+ throw new Exception("Not expected failure code: " +
+ ke.returnCode());
+ }
+ }
}
- static void go(String server, String entry) throws Exception {
+ static void go(String server, String entry, char[] pass) throws Exception {
Context c, s;
+
+ // Part 1: Test keytab
c = Context.fromUserPass("dummy", "bogus".toCharArray(), false);
s = Context.fromJAAS(entry);
@@ -66,5 +90,17 @@
s.dispose();
c.dispose();
+
+ // Part 2: Test username/password pair
+ c = Context.fromUserPass("dummy", "bogus".toCharArray(), false);
+ s = Context.fromUserPass(p.getNameString(), pass, true);
+
+ c.startAsClient(server, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+ Context.handshake(c, s);
+
+ s.dispose();
+ c.dispose();
}
}
--- a/jdk/test/sun/security/krb5/auto/OneKDC.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/sun/security/krb5/auto/OneKDC.java Wed Jul 05 17:04:56 2017 +0200
@@ -24,8 +24,6 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.security.Security;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
--- a/jdk/test/sun/security/krb5/auto/SSL.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/sun/security/krb5/auto/SSL.java Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Sun Microsystems, Inc. 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 6894643
+ * @bug 6894643 6913636
* @summary Test JSSE Kerberos ciphersuite
*/
import java.io.*;
@@ -32,12 +32,13 @@
import java.security.Principal;
import java.util.Date;
import sun.security.jgss.GSSUtil;
+import sun.security.krb5.PrincipalName;
+import sun.security.krb5.internal.ktab.KeyTab;
public class SSL {
private static final String KRB5_CIPHER = "TLS_KRB5_WITH_3DES_EDE_CBC_SHA";
private static final int LOOP_LIMIT = 1;
- private static final char[] PASS = "secret".toCharArray();
private static int loopCount = 0;
private static volatile String server;
private static volatile int port;
@@ -54,12 +55,39 @@
kdc.addPrincipal(OneKDC.USER, OneKDC.PASS);
kdc.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
- kdc.addPrincipal("host/" + server, PASS);
KDC.saveConfig(OneKDC.KRB5_CONF, kdc);
System.setProperty("java.security.krb5.conf", OneKDC.KRB5_CONF);
+ // Add 3 versions of keys into keytab
+ KeyTab ktab = KeyTab.create(OneKDC.KTAB);
+ PrincipalName service = new PrincipalName(
+ "host/" + server, PrincipalName.KRB_NT_SRV_HST);
+ ktab.addEntry(service, "pass1".toCharArray(), 1);
+ ktab.addEntry(service, "pass2".toCharArray(), 2);
+ ktab.addEntry(service, "pass3".toCharArray(), 3);
+ ktab.save();
+
+ // and use the middle one as the real key
+ kdc.addPrincipal("host/" + server, "pass2".toCharArray());
+
+ // JAAS config entry name ssl
+ System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF);
+ File f = new File(OneKDC.JAAS_CONF);
+ FileOutputStream fos = new FileOutputStream(f);
+ fos.write((
+ "ssl {\n" +
+ " com.sun.security.auth.module.Krb5LoginModule required\n" +
+ " principal=\"host/" + server + "\"\n" +
+ " useKeyTab=true\n" +
+ " keyTab=" + OneKDC.KTAB + "\n" +
+ " isInitiator=false\n" +
+ " storeKey=true;\n};\n"
+ ).getBytes());
+ fos.close();
+ f.deleteOnExit();
+
final Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
- final Context s = Context.fromUserPass("host/" + server, PASS, true);
+ final Context s = Context.fromJAAS("ssl");
c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/Test5653.java Wed Jul 05 17:04:56 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6895424
+ * @summary RFC 5653
+ */
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+import sun.security.jgss.GSSUtil;
+
+public class Test5653 {
+
+ public static void main(String[] args)
+ throws Exception {
+
+ Oid oldOid = new Oid("1.3.6.1.5.6.2");
+ new OneKDC(null).writeJAASConf();
+
+ System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+ GSSManager m = GSSManager.getInstance();
+ boolean found = false;
+
+ // Test 1: the getMechsForName() method accepts it.
+ for (Oid tmp: m.getMechsForName(oldOid)) {
+ if (tmp.equals(GSSUtil.GSS_KRB5_MECH_OID)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new Exception("Cannot found krb5 mech for old name type");
+ }
+
+ // Test 2: the createName() method accepts it.
+ GSSName name = m.createName("server@host.rabbit.hole", oldOid);
+
+ // Test 3: its getStringNameType() output is correct
+ if (!name.getStringNameType().equals(GSSName.NT_HOSTBASED_SERVICE)) {
+ throw new Exception("GSSName not correct name type");
+ }
+
+ // Test 4: everything still works.
+ GSSContext c1 = m.createContext(
+ name,
+ GSSUtil.GSS_KRB5_MECH_OID,
+ null,
+ GSSContext.DEFAULT_LIFETIME);
+ byte[] token = c1.initSecContext(new byte[0], 0, 0);
+
+ Context s;
+ s = Context.fromJAAS("server");
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ s.x().acceptSecContext(token, 0, token.length);
+ }
+}
--- a/jdk/test/sun/security/util/Oid/S11N.sh Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/sun/security/util/Oid/S11N.sh Wed Jul 05 17:04:56 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc. 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
@@ -21,8 +21,8 @@
# have any questions.
#
# @test
-# @bug 4811968
-# @summary Serialization compatibility with old versions
+# @bug 4811968 6908628
+# @summary Serialization compatibility with old versions (and fix)
# @author Weijun Wang
#
# set a few environment variables so that the shell-script can run stand-alone
@@ -99,7 +99,8 @@
# the test code
-${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}SerialTest.java || exit 10
+${TESTJAVA}${FS}bin${FS}javac -target 1.4 -source 1.4 \
+ -d . ${TESTSRC}${FS}SerialTest.java || exit 10
OLDJAVA="
/java/re/j2se/1.6.0/latest/binaries/${PF}
@@ -161,4 +162,10 @@
rm -f tmp.oid.serial.old
rm -f SerialTest.class
+for oldj in ${OLDJAVA}; do
+ if [ ! -d ${oldj} ]; then
+ echo WARNING: ${oldj} is missing. Test incomplete! > /dev/stderr
+ fi
+done
+
exit 0
--- a/jdk/test/sun/tools/jhat/HatRun.java Thu Dec 17 14:10:20 2009 -0800
+++ b/jdk/test/sun/tools/jhat/HatRun.java Wed Jul 05 17:04:56 2017 +0200
@@ -166,8 +166,10 @@
jre_home );
String cdir = System.getProperty("test.classes", ".");
String os_arch = System.getProperty("os.arch");
- boolean d64 = os_arch.equals("sparcv9") ||
- os_arch.equals("amd64");
+ String os_name = System.getProperty("os.name");
+ boolean d64 = os_name.equals("SunOS") && (
+ os_arch.equals("sparcv9") ||
+ os_arch.equals("amd64"));
String isa_dir = d64?(File.separator+os_arch):"";
String java = jre_home
+ File.separator + "bin" + isa_dir