提交 19f7df4c 编写于 作者: L lana

Merge

...@@ -71,3 +71,6 @@ f2dce7210cc00453c23e53edeec7156f112ca382 jdk7-b92 ...@@ -71,3 +71,6 @@ f2dce7210cc00453c23e53edeec7156f112ca382 jdk7-b92
cf44386c8fe3fbdb9da14346be25d19fd1092f71 jdk7-b94 cf44386c8fe3fbdb9da14346be25d19fd1092f71 jdk7-b94
db951e984ccf50756160fee3078c791300b0917e jdk7-b95 db951e984ccf50756160fee3078c791300b0917e jdk7-b95
51b9e5dbc2da0631414484b934ac3fb62e48a2c6 jdk7-b96 51b9e5dbc2da0631414484b934ac3fb62e48a2c6 jdk7-b96
b1903d7528d33b521df42bc9291bdcdd2f444a29 jdk7-b97
82593186fa54ab12f17af31f86a7bf364efaf4df jdk7-b98
2587c9f0b60dc3146b4247b8674ada456a643d6f jdk7-b99
...@@ -320,6 +320,7 @@ override LIBCXX = -lstdc++ ...@@ -320,6 +320,7 @@ override LIBCXX = -lstdc++
endif endif
override LIBPOSIX4 = override LIBPOSIX4 =
override LIBSOCKET = override LIBSOCKET =
override LIBNSL =
override LIBTHREAD = override LIBTHREAD =
override MOOT_PRIORITIES = true override MOOT_PRIORITIES = true
override NO_INTERRUPTIBLE_IO = true override NO_INTERRUPTIBLE_IO = true
......
...@@ -645,6 +645,9 @@ LIBM = /usr/lib$(ISA_DIR)/libm.so.2 ...@@ -645,6 +645,9 @@ LIBM = /usr/lib$(ISA_DIR)/libm.so.2
# Socket library # Socket library
LIBSOCKET = -lsocket LIBSOCKET = -lsocket
# Network Services library
LIBNSL = -lnsl
# GLOBAL_KPIC: If set means all libraries are PIC, position independent code # GLOBAL_KPIC: If set means all libraries are PIC, position independent code
# EXCEPT for select compiles # EXCEPT for select compiles
# If a .o file is compiled non-PIC then it should be forced # If a .o file is compiled non-PIC then it should be forced
......
...@@ -54,6 +54,13 @@ EXCLUDE_PROPWARN_PKGS = com.sun.java.swing.plaf.windows \ ...@@ -54,6 +54,13 @@ EXCLUDE_PROPWARN_PKGS = com.sun.java.swing.plaf.windows \
# This is a stopgap until 6839872 is fixed. # This is a stopgap until 6839872 is fixed.
EXCLUDE_PROPWARN_PKGS += sun.dyn EXCLUDE_PROPWARN_PKGS += sun.dyn
#
# Include the exported private packages in ct.sym.
# This is an interim solution until the ct.sym is replaced
# with a new module system (being discussed for JDK 7).
#
EXPORTED_PRIVATE_PKGS = com.sun.servicetag
# 64-bit solaris has a few special cases. We define the variable # 64-bit solaris has a few special cases. We define the variable
# SOLARIS64 for use in this Makefile to easily test those cases # SOLARIS64 for use in this Makefile to easily test those cases
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
...@@ -982,7 +989,7 @@ initial-image-jdk:: initial-image-jdk-setup \ ...@@ -982,7 +989,7 @@ initial-image-jdk:: initial-image-jdk-setup \
-processor com.sun.tools.javac.sym.CreateSymbols \ -processor com.sun.tools.javac.sym.CreateSymbols \
-Acom.sun.tools.javac.sym.Jar=$(RT_JAR) \ -Acom.sun.tools.javac.sym.Jar=$(RT_JAR) \
-Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \ -Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \
$(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) $(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) $(EXPORTED_PRIVATE_PKGS)
$(BOOT_JAR_CMD) c0f $(LIBDIR)/ct.sym \ $(BOOT_JAR_CMD) c0f $(LIBDIR)/ct.sym \
-C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS) -C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup) @$(java-vm-cleanup)
......
...@@ -35,9 +35,6 @@ ifndef JDK_MAKE_SHARED_DIR ...@@ -35,9 +35,6 @@ ifndef JDK_MAKE_SHARED_DIR
JDK_MAKE_SHARED_DIR = $(JDK_TOPDIR)/make/common/shared JDK_MAKE_SHARED_DIR = $(JDK_TOPDIR)/make/common/shared
endif endif
ifndef CONTROL_TOPDIR
CONTROL_TOPDIR=$(TOPDIR)
endif
ifndef HOTSPOT_TOPDIR ifndef HOTSPOT_TOPDIR
HOTSPOT_TOPDIR=$(TOPDIR)/hotspot HOTSPOT_TOPDIR=$(TOPDIR)/hotspot
endif endif
......
...@@ -331,23 +331,50 @@ ifeq ($(_ms_sdk),) ...@@ -331,23 +331,50 @@ ifeq ($(_ms_sdk),)
endif endif
endif endif
# Compilers for 64bit may be from SDK. For VS 2010 we use those. # Compilers for 64bit may be from the free SDK, or Visual Studio Professional
# The Express compilers don't contain 64 bit compilers, so in # The free Express compilers don't contain 64 bit compilers, which is why
# that case, you additionally need the SDK. At this time, # you instead need the SDK.
# there's no 64 bit SDK available that has VS 2010. # So for VS2010 based builds, either VS2010 Pro with the 7.0a SDK, or
# Presumably SDK v7.1 will provide that and we may want to update # the Windows 7.1 standalone SDK with compilers may be used.
# the logic here to work with that. # Release enginering will use VS2010 Pro, so the frequency of testing of
# However official builds will use the Professional version. # SDK based builds will depend entirely on individual usage.
ifeq ($(ARCH_DATA_MODEL), 64) ifeq ($(ARCH_DATA_MODEL), 64)
ifdef VS100COMNTOOLS # /Common7/Tools directory, use ../../Vc ifdef VS100COMNTOOLS # /Common7/Tools directory, use ../../Vc
# VS2010 default location is used when building 64 bit using the 7.1 SDK
# This is safe to hardwire as the SDK installer won't let you change it
# and the VS2010 variable is only used if the compilers are from the SDK
xVS2010 :="$(_program_files32)/Microsoft Visual Studio 10.0/"
VS2010 :=$(call FullPath,$(xVS2010))
xVS100COMNTOOLS :="$(subst \,/,$(VS100COMNTOOLS))" xVS100COMNTOOLS :="$(subst \,/,$(VS100COMNTOOLS))"
_vs100tools :=$(call FullPath,$(xVS100COMNTOOLS)) _vs100tools :=$(call FullPath,$(xVS100COMNTOOLS))
endif endif
ifneq ($(_vs100tools),) ifneq ($(_vs100tools),)
_compiler_bin :=$(_vs100tools)/../../Vc/bin/amd64 _compiler_bin :=$(_vs100tools)/../../Vc/bin/amd64
_redist_sdk :=$(_vs100tools)/../../Vc/redist/x64/Microsoft.VC100.CRT x_redist_sdk :=$(_vs100tools)/../../Vc/redist/x64/Microsoft.VC100.CRT
xMSSDK70 :="$(_program_files32)/Microsoft SDKs/Windows/v7.0a/" _redist_sdk :=$(call FullPath,$(x_redist_sdk))
MSSDK70 :=$(call FullPath,$(xMSSDK70)) # The SDK doesn't have the redist directory, but the DLL is installed
# into the windows directory.
ifeq ($(_redist_sdk),)
_redist_sdk :=c:/windows/system32
endif
# Not currently using MSSDK7n, but maybe we can make use of it for
# doing default location lookup to find some SDK tools that presently
# require the developer to explicitly set the path.
# The 7.0a path is from VS2010 Pro, the 7.1 path is the standalone SDK.
# Either will work for us.
# If a developer chooses to install the standalone SDK in some other
# location, then this will fail to find it, which won't matter so long as
# we aren't using this variable. If we do they'd still need to set the
# ALT_MSDEVTOOLS_PATH as now.
# %WindowsSdkDir% could be referenced instead but the SDK installer
# doesn't set it and in the case of the VS2010 compilers,
# you can't change this location in the installer anyway.
xMSSDK7n :="$(_program_files32)/Microsoft SDKs/Windows/v7.0a/"
MSSDK7n :=$(call FullPath,$(xMSSDK7n))
ifeq ($(MSSDK7n),)
xMSSDK7n :="$(_program_files32)/Microsoft SDKs/Windows/v7.1/"
MSSDK7n :=$(call FullPath,$(xMSSDK7n))
endif
else else
xVS2008 :="$(_program_files32)/Microsoft Visual Studio 9.0/" xVS2008 :="$(_program_files32)/Microsoft Visual Studio 9.0/"
VS2008 :=$(call FullPath,$(xVS2008)) VS2008 :=$(call FullPath,$(xVS2008))
...@@ -355,7 +382,7 @@ ifeq ($(ARCH_DATA_MODEL), 64) ...@@ -355,7 +382,7 @@ ifeq ($(ARCH_DATA_MODEL), 64)
_compiler_bin :=$(VS2008)/VC/Bin/$(ARCH) _compiler_bin :=$(VS2008)/VC/Bin/$(ARCH)
xMSSDK61 :="$(_program_files)/Microsoft SDKs/Windows/v6.1/" xMSSDK61 :="$(_program_files)/Microsoft SDKs/Windows/v6.1/"
MSSDK61 :=$(call FullPath,$(xMSSDK61)) MSSDK61 :=$(call FullPath,$(xMSSDK61))
_redist_sdk :=$(VS2008)/VC/redist/x86/Microsoft.VC90.CRT _redist_sdk :=$(VS2008)/VC/redist/x64/Microsoft.VC90.CRT
else else
ifneq ($(_ms_sdk),) ifneq ($(_ms_sdk),)
ifeq ($(ARCH), ia64) ifeq ($(ARCH), ia64)
......
...@@ -234,6 +234,7 @@ CORE_PKGS = \ ...@@ -234,6 +234,7 @@ CORE_PKGS = \
javax.xml.ws.http \ javax.xml.ws.http \
javax.xml.ws.soap \ javax.xml.ws.soap \
javax.xml.ws.spi \ javax.xml.ws.spi \
javax.xml.ws.spi.http \
javax.xml.ws.wsaddressing \ javax.xml.ws.wsaddressing \
javax.xml.transform \ javax.xml.transform \
javax.xml.transform.sax \ javax.xml.transform.sax \
......
...@@ -86,5 +86,5 @@ endif ...@@ -86,5 +86,5 @@ endif
# Things that must be linked in. # Things that must be linked in.
# #
ifneq ($(PLATFORM), windows) ifneq ($(PLATFORM), windows)
OTHER_LDLIBS += $(LIBSOCKET) -lnsl $(LIBM) -ldl OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) $(LIBM) -ldl
endif endif
...@@ -204,7 +204,7 @@ ifeq ($(PLATFORM),windows) ...@@ -204,7 +204,7 @@ ifeq ($(PLATFORM),windows)
OTHER_LDLIBS += $(JVMLIB) -libpath:$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) fdlibm.lib \ OTHER_LDLIBS += $(JVMLIB) -libpath:$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) fdlibm.lib \
-libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib -libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib
else else
OTHER_LDLIBS += $(JVMLIB) -lverify $(LIBSOCKET) -lnsl -ldl \ OTHER_LDLIBS += $(JVMLIB) -lverify $(LIBSOCKET) $(LIBNSL) -ldl \
-L$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) -lfdlibm.$(ARCH) -L$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) -lfdlibm.$(ARCH)
endif endif
......
...@@ -84,7 +84,7 @@ OTHER_INCLUDES = -I$(SRCDIR) \ ...@@ -84,7 +84,7 @@ OTHER_INCLUDES = -I$(SRCDIR) \
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
OTHER_LDLIBS += wsock32.lib winmm.lib OTHER_LDLIBS += wsock32.lib winmm.lib
else else
OTHER_LDLIBS += $(LIBSOCKET) -lnsl -ldl OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) -ldl
endif endif
# #
......
...@@ -96,7 +96,7 @@ include $(BUILDDIR)/common/Library.gmk ...@@ -96,7 +96,7 @@ include $(BUILDDIR)/common/Library.gmk
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
OTHER_LDLIBS = ws2_32.lib $(JVMLIB) OTHER_LDLIBS = ws2_32.lib $(JVMLIB)
else else
OTHER_LDLIBS = $(LIBSOCKET) -lnsl -ldl $(JVMLIB) OTHER_LDLIBS = $(LIBSOCKET) $(LIBNSL) -ldl $(JVMLIB)
endif endif
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
OTHER_LDLIBS += -lpthread OTHER_LDLIBS += -lpthread
......
...@@ -38,11 +38,11 @@ FILES_m = mapfile-vers ...@@ -38,11 +38,11 @@ FILES_m = mapfile-vers
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
OTHER_LDLIBS += -lnsl $(LIBSOCKET) -lpthread OTHER_LDLIBS += $(LIBNSL) $(LIBSOCKET) -lpthread
endif endif
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS += -lnsl $(LIBSOCKET) OTHER_LDLIBS += $(LIBNSL) $(LIBSOCKET)
endif endif
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
......
...@@ -39,10 +39,10 @@ ifeq ($(PLATFORM), windows) ...@@ -39,10 +39,10 @@ ifeq ($(PLATFORM), windows)
EXTRA_LIBS += wsock32.lib winmm.lib EXTRA_LIBS += wsock32.lib winmm.lib
endif endif
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS += $(LIBSOCKET) -lnsl -ldl OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) -ldl
endif endif
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
OTHER_LDLIBS += $(LIBSOCKET) -lnsl -ldl -lpthread OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) -ldl -lpthread
endif endif
# #
......
...@@ -204,8 +204,8 @@ Provided NetBeans projects ...@@ -204,8 +204,8 @@ Provided NetBeans projects
note that pretty much regardless of your hardware, this *will* take note that pretty much regardless of your hardware, this *will* take
a long time, and use *lots* of disk space (more than 3GB). The a long time, and use *lots* of disk space (more than 3GB). The
results of the build are in results of the build are in
*install-dir*/control/build/*platform*-*arch* and *install-dir*/build/*platform*-*arch* and
*install-dir*/control/build/*platform*-*arch*-fastdebug. *install-dir*/build/*platform*-*arch*-fastdebug.
Consult the project's README file for details. Consult the project's README file for details.
......
...@@ -10,6 +10,6 @@ project code, you might prefer to build it from the command line using ant. ...@@ -10,6 +10,6 @@ project code, you might prefer to build it from the command line using ant.
Please note: the results of building this project are *not* put in the place Please note: the results of building this project are *not* put in the place
used by other projects. In this case, the results are place in used by other projects. In this case, the results are place in
<install-dir>/control/build/<platform>-<arch> <install-dir>/build/<platform>-<arch>
and and
<install-dir>/control/build/<platform>-<arch>-fastdebug <install-dir>/build/<platform>-<arch>-fastdebug
...@@ -34,11 +34,11 @@ ...@@ -34,11 +34,11 @@
<import file="../common/shared.xml"/> <import file="../common/shared.xml"/>
<target name="-build-make" depends="-make.init" if="use.make"> <target name="-build-make" depends="-make.init" if="use.make">
<make-run target="dev" dir="${root}/../control/make" opts="SKIP_COMPARE_IMAGES=true"/> <make-run target="dev" dir="${root}/.." opts="SKIP_COMPARE_IMAGES=true"/>
</target> </target>
<target name="-clean-make" depends="-make.init" if="use.make"> <target name="-clean-make" depends="-make.init" if="use.make">
<make-run target="clean" dir="${root}/../control/make"/> <make-run target="clean" dir="${root}/.."/>
</target> </target>
</project> </project>
...@@ -37,7 +37,7 @@ PRODUCT = sun ...@@ -37,7 +37,7 @@ PRODUCT = sun
# This re-directs all the class files to a separate location # This re-directs all the class files to a separate location
CLASSDESTDIR = $(TEMPDIR)/classes CLASSDESTDIR = $(TEMPDIR)/classes
OTHER_JAVACFLAGS += -Xlint:serial -Werror OTHER_JAVACFLAGS += -Xlint:serial,-deprecation -Werror
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# #
......
...@@ -52,5 +52,11 @@ build: copy-files ...@@ -52,5 +52,11 @@ build: copy-files
copy-files: $(FILES_copy) copy-files: $(FILES_copy)
$(SERVICEDIR)/%: $(SHARE_SRC)/classes/sun/java2d/pisces/META-INF/services/% ifneq ($(PLATFORM), windows)
SERVICE_SRC = $(PLATFORM_SRC)
else
SERVICE_SRC = $(SHARE_SRC)
endif
$(SERVICEDIR)/%: $(SERVICE_SRC)/classes/sun/java2d/pisces/META-INF/services/%
$(install-file) $(install-file)
...@@ -49,7 +49,8 @@ AUTO_FILES_JAVA_DIRS = \ ...@@ -49,7 +49,8 @@ AUTO_FILES_JAVA_DIRS = \
# Extra jstat files # Extra jstat files
FILES_copy += \ FILES_copy += \
$(CLASSDESTDIR)/sun/tools/jstat/resources/jstat_options $(CLASSDESTDIR)/sun/tools/jstat/resources/jstat_options \
$(CLASSDESTDIR)/sun/tools/jstat/resources/jstat_unsupported_options
# Extra jhat files # Extra jhat files
JHAT_RESOURCEDIR = $(CLASSDESTDIR)/com/sun/tools/hat/resources JHAT_RESOURCEDIR = $(CLASSDESTDIR)/com/sun/tools/hat/resources
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include FT_FREETYPE_H #include FT_FREETYPE_H
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER > 1400 #if _MSC_VER > 1400 && _MSC_VER < 1600
/* /*
* When building for Microsoft Windows, your program has a dependency * When building for Microsoft Windows, your program has a dependency
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
"publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif /* _M_AMD64 */ #endif /* _M_AMD64 */
#endif /* _MSC_VER > 1400 */ #endif /* _MSC_VER > 1400 && _MSC_VER < 1600 */
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#define QUOTEMACRO(x) QUOTEME(x) #define QUOTEMACRO(x) QUOTEME(x)
......
/* /*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -47,10 +47,13 @@ interface Constants { ...@@ -47,10 +47,13 @@ interface Constants {
public final static short JAVA5_MAX_CLASS_MAJOR_VERSION = 49; public final static short JAVA5_MAX_CLASS_MAJOR_VERSION = 49;
public final static short JAVA5_MAX_CLASS_MINOR_VERSION = 0; public final static short JAVA5_MAX_CLASS_MINOR_VERSION = 0;
// NOTE: ASSUMED for now
public final static short JAVA6_MAX_CLASS_MAJOR_VERSION = 50; public final static short JAVA6_MAX_CLASS_MAJOR_VERSION = 50;
public final static short JAVA6_MAX_CLASS_MINOR_VERSION = 0; public final static short JAVA6_MAX_CLASS_MINOR_VERSION = 0;
public final static short JAVA7_MAX_CLASS_MAJOR_VERSION = 51;
public final static short JAVA7_MAX_CLASS_MINOR_VERSION = 0;
public final static int JAVA_PACKAGE_MAGIC = 0xCAFED00D; public final static int JAVA_PACKAGE_MAGIC = 0xCAFED00D;
public final static int JAVA5_PACKAGE_MAJOR_VERSION = 150; public final static int JAVA5_PACKAGE_MAJOR_VERSION = 150;
public final static int JAVA5_PACKAGE_MINOR_VERSION = 7; public final static int JAVA5_PACKAGE_MINOR_VERSION = 7;
......
/* /*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -57,8 +57,8 @@ class Package implements Constants { ...@@ -57,8 +57,8 @@ class Package implements Constants {
// These fields can be adjusted by driver properties. // These fields can be adjusted by driver properties.
short min_class_majver = JAVA_MIN_CLASS_MAJOR_VERSION; short min_class_majver = JAVA_MIN_CLASS_MAJOR_VERSION;
short min_class_minver = JAVA_MIN_CLASS_MINOR_VERSION; short min_class_minver = JAVA_MIN_CLASS_MINOR_VERSION;
short max_class_majver = JAVA6_MAX_CLASS_MAJOR_VERSION; short max_class_majver = JAVA7_MAX_CLASS_MAJOR_VERSION;
short max_class_minver = JAVA6_MAX_CLASS_MINOR_VERSION; short max_class_minver = JAVA7_MAX_CLASS_MINOR_VERSION;
short observed_max_class_majver = min_class_majver; short observed_max_class_majver = min_class_majver;
short observed_max_class_minver = min_class_minver; short observed_max_class_minver = min_class_minver;
...@@ -122,13 +122,16 @@ class Package implements Constants { ...@@ -122,13 +122,16 @@ class Package implements Constants {
void choosePackageVersion() { void choosePackageVersion() {
assert(package_majver <= 0); // do not call this twice assert(package_majver <= 0); // do not call this twice
int classver = getHighestClassVersion(); int classver = getHighestClassVersion();
if (classver != 0 && if (classver == 0 || (classver >>> 16) < JAVA6_MAX_CLASS_MAJOR_VERSION) {
(classver >>> 16) < JAVA6_MAX_CLASS_MAJOR_VERSION) { // There are only old classfiles in this segment or resources
// There are only old classfiles in this segment.
package_majver = JAVA5_PACKAGE_MAJOR_VERSION; package_majver = JAVA5_PACKAGE_MAJOR_VERSION;
package_minver = JAVA5_PACKAGE_MINOR_VERSION; package_minver = JAVA5_PACKAGE_MINOR_VERSION;
} else if ((classver >>> 16) == JAVA6_MAX_CLASS_MAJOR_VERSION) {
package_majver = JAVA6_PACKAGE_MAJOR_VERSION;
package_minver = JAVA6_PACKAGE_MINOR_VERSION;
} else { } else {
// Normal case. Use the newest archive format. // Normal case. Use the newest archive format, when available
// TODO: replace the following with JAVA7* when the need arises
package_majver = JAVA6_PACKAGE_MAJOR_VERSION; package_majver = JAVA6_PACKAGE_MAJOR_VERSION;
package_minver = JAVA6_PACKAGE_MINOR_VERSION; package_minver = JAVA6_PACKAGE_MINOR_VERSION;
} }
......
/* /*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003,2010 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -90,8 +90,8 @@ class PropMap extends TreeMap { ...@@ -90,8 +90,8 @@ class PropMap extends TreeMap {
props.put(Utils.PACK_DEFAULT_TIMEZONE, props.put(Utils.PACK_DEFAULT_TIMEZONE,
String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))); String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)));
// Limit segment size to less than a megabyte. // The segment size is unlimited
props.put(Pack200.Packer.SEGMENT_LIMIT, ""+(1*1000*1000)); props.put(Pack200.Packer.SEGMENT_LIMIT, "");
// Preserve file ordering by default. // Preserve file ordering by default.
props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE); props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
......
...@@ -67,7 +67,6 @@ public class Registry { ...@@ -67,7 +67,6 @@ public class Registry {
// The stclient output has to be an exported interface // The stclient output has to be an exported interface
private static final String INSTANCE_URN_DESC = "Product instance URN="; private static final String INSTANCE_URN_DESC = "Product instance URN=";
private static boolean initialized = false; private static boolean initialized = false;
private static boolean supportsHelperClass = true; // default
private static File stclient = null; private static File stclient = null;
private static String stclientPath = null; private static String stclientPath = null;
private static Registry registry = new Registry(); private static Registry registry = new Registry();
...@@ -81,17 +80,6 @@ public class Registry { ...@@ -81,17 +80,6 @@ public class Registry {
private synchronized static String getSTclient() { private synchronized static String getSTclient() {
if (!initialized) { if (!initialized) {
// the system property always overrides the default setting
if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
}
// This is only used for testing
stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD);
if (stclientPath != null) {
return stclientPath;
}
// Initialization to determine the platform's stclient pathname // Initialization to determine the platform's stclient pathname
String os = System.getProperty("os.name"); String os = System.getProperty("os.name");
if (os.equals("SunOS")) { if (os.equals("SunOS")) {
...@@ -108,10 +96,26 @@ public class Registry { ...@@ -108,10 +96,26 @@ public class Registry {
initialized = true; initialized = true;
} }
boolean supportsHelperClass = true; // default
if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
// the system property always overrides the default setting
supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
}
if (!supportsHelperClass) {
// disable system registry
return null;
}
// This is only used for testing
String path = System.getProperty(SVCTAG_STCLIENT_CMD);
if (path != null) {
return path;
}
// com.sun.servicetag package has to be compiled with JDK 5 as well // com.sun.servicetag package has to be compiled with JDK 5 as well
// JDK 5 doesn't support the File.canExecute() method. // JDK 5 doesn't support the File.canExecute() method.
// Risk not checking isExecute() for the stclient command is very low. // Risk not checking isExecute() for the stclient command is very low.
if (stclientPath == null && stclient != null && stclient.exists()) { if (stclientPath == null && stclient != null && stclient.exists()) {
stclientPath = stclient.getAbsolutePath(); stclientPath = stclient.getAbsolutePath();
} }
...@@ -142,8 +146,8 @@ public class Registry { ...@@ -142,8 +146,8 @@ public class Registry {
* @return {@code true} if the {@code Registry} class is supported; * @return {@code true} if the {@code Registry} class is supported;
* otherwise, return {@code false}. * otherwise, return {@code false}.
*/ */
public static boolean isSupported() { public static synchronized boolean isSupported() {
return (getSTclient() != null && supportsHelperClass); return getSTclient() != null;
} }
private static List<String> getCommandList() { private static List<String> getCommandList() {
......
...@@ -53,13 +53,13 @@ a:visited,a:visited code{color:#917E9C} ...@@ -53,13 +53,13 @@ a:visited,a:visited code{color:#917E9C}
</tr> </tr>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><p class="style1">Thank you for installing the <td><p class="style1">Thank you for installing the
<strong> Java Development Kit @@JDK_VERSION@@ </strong> <strong> Java Development Kit @@JDK_VERSION@@ </strong>
from Sun Microsystems. </p> from Oracle Corporation. </p>
<p class="style1">Registering your product will give you the following benefits:</p> <p class="style1">Registering your product will give you the following benefits:</p>
<ul class="style1"> <ul class="style1">
<li> Notification of new versions, patches, and updates</li> <li> Notification of new versions, patches, and updates</li>
<li> Special offers on Sun developer products, services and training </li> <li> Special offers on Oracle developer products, services and training </li>
<li> Access to early releases and documentation </li> <li> Access to early releases and documentation </li>
</ul> </ul>
<p class="style1">Product registration is FREE, quick and easy!</p> <p class="style1">Product registration is FREE, quick and easy!</p>
...@@ -68,11 +68,11 @@ a:visited,a:visited code{color:#917E9C} ...@@ -68,11 +68,11 @@ a:visited,a:visited code{color:#917E9C}
<table width="708" border="0" cellspacing="0" cellpadding="3"> <table width="708" border="0" cellspacing="0" cellpadding="3">
<tr valign="top"> <tr valign="top">
<td width="126" height="35"> <td width="126" height="35">
<form name="form1" method="post" action="@@REGISTRATION_URL@@"> <form name="form1" method="post" action="@@REGISTRATION_URL@@" enctype="text/xml">
<input type="hidden" name="servicetag_payload" value="@@REGISTRATION_PAYLOAD@@"> <input type="hidden" name="servicetag_payload" value="@@REGISTRATION_PAYLOAD@@">
<input type="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="Register My JDK"> <input type="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="Register My JDK">
</form></td> </form></td>
<td width="570"><span class="style3">You need to be connected to the Internet to register this Sun product. </span></td> <td width="570"><span class="style3">You need to be connected to the Internet to register this Oracle product. </span></td>
</tr> </tr>
</table> </table>
</blockquote> </blockquote>
...@@ -81,16 +81,16 @@ a:visited,a:visited code{color:#917E9C} ...@@ -81,16 +81,16 @@ a:visited,a:visited code{color:#917E9C}
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td bgcolor="#f1f7df"> <td bgcolor="#f1f7df">
<p class="style3">Sun Microsystems, Inc. respects your privacy. <p class="style3">Oracle Corporation respects your privacy.
We will use your personal information for communications We will use your personal information for communications
and management of your Sun Online Account, the services and management of your Sun Online Account, the services
and applications you access using your Sun Online Account, and applications you access using your Sun Online Account,
and the products and systems you register with your Sun Online Account.</p> and the products and systems you register with your Sun Online Account.</p>
<p class="style3">For more information on the data that will be collected as <p class="style3">For more information on the data that will be collected as
part of the registration process and how it will be managed <br> part of the registration process and how it will be managed <br>
see <a href="http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html">http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html</a>. <br> see <a href="http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html">http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html</a>. <br>
<br> <br>
For more information on Sun's Privacy Policy see <a href="http://www.sun.com/privacy/">http://www.sun.com/privacy/</a> or contact <a class="moz-txt-link-rfc2396E" href="mailto:privacy@sun.com">privacy@sun.com.</a></p></td> For more information on Oracle's Privacy Policy see <a href="http://www.oracle.com/html/privacy.html">http://www.oracle.com/html/privacy.html</a> or contact <a class="moz-txt-link-rfc2396E" href="mailto:privacy_ww@oracle.com">privacy_ww@oracle.com.</a></p></td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
......
...@@ -50,11 +50,11 @@ a:visited,a:visited code{color:#917E9C} ...@@ -50,11 +50,11 @@ a:visited,a:visited code{color:#917E9C}
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><p class="style1">Sun Microsystems<strong> Java Development Kit @@JDK_VERSION@@ </strong>をインストールしていただき、ありがとうございます。 </p> <td><p class="style1">Oracle Corporation<strong> Java Development Kit @@JDK_VERSION@@ </strong>をインストールしていただき、ありがとうございます。 </p>
<p class="style1">製品登録をすると、次のような特典を受けることができます。</p> <p class="style1">製品登録をすると、次のような特典を受けることができます。</p>
<ul class="style1"> <ul class="style1">
<li> 最新のバージョン、パッチ、および更新についての通知</li> <li> 最新のバージョン、パッチ、および更新についての通知</li>
<li> Sun の開発者向け製品、サービス、およびトレーニングの特別販売 </li> <li> Oracle の開発者向け製品、サービス、およびトレーニングの特別販売 </li>
<li> アーリーリリースおよびドキュメントへのアクセス </li> <li> アーリーリリースおよびドキュメントへのアクセス </li>
</ul> </ul>
<p class="style1">製品登録は無料であり、迅速で簡単です。</p> <p class="style1">製品登録は無料であり、迅速で簡単です。</p>
...@@ -62,11 +62,11 @@ a:visited,a:visited code{color:#917E9C} ...@@ -62,11 +62,11 @@ a:visited,a:visited code{color:#917E9C}
<p class="style1">必要になるのは、Sun 開発者向けネットワークアカウントまたはその他の Sun オンラインアカウントだけです。 まだアカウントがない場合は、アカウントの作成が求められます。 </p> <p class="style1">必要になるのは、Sun 開発者向けネットワークアカウントまたはその他の Sun オンラインアカウントだけです。 まだアカウントがない場合は、アカウントの作成が求められます。 </p>
<table width="708" border="0" cellspacing="0" cellpadding="3"> <table width="708" border="0" cellspacing="0" cellpadding="3">
<tr valign="top"> <tr valign="top">
<td width="126" height="35"><form name="form1" method="post" action="@@REGISTRATION_URL@@"> <td width="126" height="35"><form name="form1" method="post" action="@@REGISTRATION_URL@@" enctype="text/xml">
<input type="hidden" name="servicetag_payload" value="@@REGISTRATION_PAYLOAD@@"> <input type="hidden" name="servicetag_payload" value="@@REGISTRATION_PAYLOAD@@">
<input type="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="JDK 製品登録"> <input type="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="JDK 製品登録">
</form></td> </form></td>
<td width="570"><span class="style3">この Sun 製品を登録するには、インターネットに接続している必要があります。 </span></td> <td width="570"><span class="style3">この Oracle 製品を登録するには、インターネットに接続している必要があります。 </span></td>
</tr> </tr>
</table> </table>
</blockquote> </blockquote>
...@@ -75,8 +75,8 @@ a:visited,a:visited code{color:#917E9C} ...@@ -75,8 +75,8 @@ a:visited,a:visited code{color:#917E9C}
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td bgcolor="#f1f7df"> <td bgcolor="#f1f7df">
<p class="style3">Sun Microsystems, Inc. は、お客様のプライバシーを尊重します。 お客様の個人情報は、お客様の Sun オンラインアカウント、お客様が Sun オンラインアカウントを使用してアクセスするサービスとアプリケーション、およびお客様が Sun オンラインアカウントで登録する製品とシステムの通信と管理に使用します。</p> <p class="style3">Oracle Corporation は、お客様のプライバシーを尊重します。 お客様の個人情報は、お客様の Sun オンラインアカウント、お客様が Sun オンラインアカウントを使用してアクセスするサービスとアプリケーション、およびお客様が Sun オンラインアカウントで登録する製品とシステムの通信と管理に使用します。</p>
<p class="style3">登録の際に収集されるデータや、それらがどのように管理されるかについての詳細は、<br><a href="http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html">http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html</a> を参照してください。 <br> <br> Sun のプライバシーポリシーについての詳細は、<a href="http://jp.sun.com/privacy/">http://jp.sun.com/privacy/</a> を参照するか、<a class="moz-txt-link-rfc2396E" href="http://jp.sun.com/cgi-bin/contact/comment.cgi?url=http://jp.sun.com/privacy/">お問い合わせフォーム</a>からお問い合わせください。</p></td> <p class="style3">登録の際に収集されるデータや、それらがどのように管理されるかについての詳細は、<br><a href="http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html">http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html</a> を参照してください。 <br> <br> Oracle のプライバシーポリシーについての詳細は、<a href="http://www.oracle.com/html/privacy.html">http://www.oracle.com/html/privacy.html</a> を参照するか、<a class="moz-txt-link-rfc2396E" href="mailto:privacy_ww@oracle.com">お問い合わせフォーム</a>からお問い合わせください。</p></td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
......
...@@ -51,11 +51,11 @@ a:visited,a:visited code{color:#917E9C} ...@@ -51,11 +51,11 @@ a:visited,a:visited code{color:#917E9C}
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><p class="style1">感谢您安装 Sun Microsystems<strong>Java Development Kit @@JDK_VERSION@@</strong></p> <td><p class="style1">感谢您安装 Oracle Corporation<strong>Java Development Kit @@JDK_VERSION@@</strong></p>
<p class="style1">注册产品后您将获得如下增值服务:</p> <p class="style1">注册产品后您将获得如下增值服务:</p>
<ul class="style1"> <ul class="style1">
<li> 获得新版本、修补程序和更新的通知服务</li> <li> 获得新版本、修补程序和更新的通知服务</li>
<li> 获得有关 Sun 开发者产品、服务和培训的优惠 </li> <li> 获得有关 Oracle 开发者产品、服务和培训的优惠 </li>
<li> 获得对早期版本和文档的访问权限 </li> <li> 获得对早期版本和文档的访问权限 </li>
</ul> </ul>
<p class="style1">产品注册是免费的,即快速又轻松!</p> <p class="style1">产品注册是免费的,即快速又轻松!</p>
...@@ -63,11 +63,11 @@ a:visited,a:visited code{color:#917E9C} ...@@ -63,11 +63,11 @@ a:visited,a:visited code{color:#917E9C}
<p class="style1">您需要具有 Sun 开发者网络或其他 Sun 联机帐户。如果您没有,系统将提示您创建一个。 </p> <p class="style1">您需要具有 Sun 开发者网络或其他 Sun 联机帐户。如果您没有,系统将提示您创建一个。 </p>
<table width="708" border="0" cellspacing="0" cellpadding="3"> <table width="708" border="0" cellspacing="0" cellpadding="3">
<tr valign="top"> <tr valign="top">
<td width="126" height="35"><form name="form1" method="post" action="@@REGISTRATION_URL@@"> <td width="126" height="35"><form name="form1" method="post" action="@@REGISTRATION_URL@@" enctype="text/xml">
<input type="hidden" name="servicetag_payload" value="@@REGISTRATION_PAYLOAD@@"> <input type="hidden" name="servicetag_payload" value="@@REGISTRATION_PAYLOAD@@">
<input type="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="注册我的 JDK"> <input type="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="注册我的 JDK">
</form></td> </form></td>
<td width="570"><span class="style3">您需要连接到 Internet 来注册此 Sun 产品。 </span></td> <td width="570"><span class="style3">您需要连接到 Internet 来注册此 Oracle 产品。 </span></td>
</tr> </tr>
</table> </table>
</blockquote> </blockquote>
...@@ -76,8 +76,8 @@ a:visited,a:visited code{color:#917E9C} ...@@ -76,8 +76,8 @@ a:visited,a:visited code{color:#917E9C}
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td bgcolor="#f1f7df"> <td bgcolor="#f1f7df">
<p class="style3">Sun Microsystems, Inc. 尊重您的隐私。我们会将您的个人信息用于通信和 Sun 联机帐户的管理、Sun 联机帐户访问的服务和应用程序以及用于使用 Sun 联机帐户注册的产品和系统。</p> <p class="style3">Oracle 尊重您的隐私。我们会将您的个人信息用于通信和 Sun 联机帐户的管理、Sun 联机帐户访问的服务和应用程序以及用于使用 Sun 联机帐户注册的产品和系统。</p>
<p class="style3">有关注册过程中收集的数据以及这些数据的管理方式的更多信息,<br>请访问 <a href="http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html">http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html</a><br> <br>有关 Sun 隐私政策的更多信息,请访问 <a href="http://www.sun.com/privacy/">http://www.sun.com/privacy/</a> 或与 <a class="moz-txt-link-rfc2396E" href="mailto:privacy@sun.com">privacy@sun.com</a> 联系。</p></td> <p class="style3">有关注册过程中收集的数据以及这些数据的管理方式的更多信息,<br>请访问 <a href="http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html">http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html</a><br> <br>有关 Oracle 隐私政策的更多信息,请访问 <a href="http://www.oracle.com/html/privacy.html">http://www.oracle.com/html/privacy.html</a> 或与 <a class="moz-txt-link-rfc2396E" href="mailto:privacy_ww@oracle.com">privacy_ww@oracle.com</a> 联系。</p></td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
......
/* /*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,25 +25,32 @@ ...@@ -25,25 +25,32 @@
package java.dyn; package java.dyn;
import sun.dyn.util.BytecodeName;
import sun.dyn.Access; import sun.dyn.Access;
import sun.dyn.MemberName;
import sun.dyn.CallSiteImpl; import sun.dyn.CallSiteImpl;
import sun.dyn.MethodHandleImpl;
/** /**
* An {@code invokedynamic} call site, as reified by the * A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode,
* containing class's bootstrap method. * and controls its linkage.
* Every call site object corresponds to a distinct instance * Every linked {@code CallSite} object corresponds to a distinct instance
* of the <code>invokedynamic</code> instruction, and vice versa. * of the {@code invokedynamic} instruction, and vice versa.
* Every call site has one state variable, called the {@code target}.
* It is typed as a {@link MethodHandle}. This state is never null, and
* it is the responsibility of the bootstrap method to produce call sites
* which have been pre-linked to an initial target method.
* <p> * <p>
* (Note: The bootstrap method may elect to produce call sites of a * Every linked {@code CallSite} object has one state variable,
* a {@link MethodHandle} reference called the {@code target}.
* This reference is never null. Though it can change its value
* successive values must always have exactly the {@link MethodType method type}
* called for by the bytecodes of the associated {@code invokedynamic} instruction
* <p>
* It is the responsibility of each class's
* {@link Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
* to produce call sites which have been pre-linked to an initial target method.
* The required {@link MethodType type} for the target method is a parameter
* to each bootstrap method call.
* <p>
* The bootstrap method may elect to produce call sites of a
* language-specific subclass of {@code CallSite}. In such a case, * language-specific subclass of {@code CallSite}. In such a case,
* the subclass may claim responsibility for initializing its target to * the subclass may claim responsibility for initializing its target to
* a non-null value, by overriding {@link #initialTarget}.) * a non-null value, by overriding {@link #initialTarget}.
* <p> * <p>
* An {@code invokedynamic} instruction which has not yet been executed * An {@code invokedynamic} instruction which has not yet been executed
* is said to be <em>unlinked</em>. When an unlinked call site is executed, * is said to be <em>unlinked</em>. When an unlinked call site is executed,
...@@ -52,54 +59,139 @@ import sun.dyn.MethodHandleImpl; ...@@ -52,54 +59,139 @@ import sun.dyn.MethodHandleImpl;
* value to the new call site's target variable, the method {@link #initialTarget} * value to the new call site's target variable, the method {@link #initialTarget}
* is called to produce the new call site's first target method. * is called to produce the new call site's first target method.
* <p> * <p>
* A freshly-created {@code CallSite} object is not yet in a linked state.
* An unlinked {@code CallSite} object reports null for its {@code callerClass}.
* When the JVM receives a {@code CallSite} object from a bootstrap method,
* it first ensures that its target is non-null and of the correct type.
* The JVM then links the {@code CallSite} object to the call site instruction,
* enabling the {@code callerClass} to return the class in which the instruction occurs.
* <p>
* Next, the JVM links the instruction to the {@code CallSite}, at which point
* any further execution of the {@code invokedynamic} instruction implicitly
* invokes the current target of the {@code CallSite} object.
* After this two-way linkage, both the instruction and the {@code CallSite}
* object are said to be linked.
* <p>
* This state of linkage continues until the method containing the
* dynamic call site is garbage collected, or the dynamic call site
* is invalidated by an explicit request.
* <p>
* Linkage happens once in the lifetime of any given {@code CallSite} object.
* Because of call site invalidation, this linkage can be repeated for
* a single {@code invokedynamic} instruction, with multiple {@code CallSite} objects.
* When a {@code CallSite} is unlinked from an {@code invokedynamic} instruction,
* the instruction is reset so that it is no longer associated with
* the {@code CallSite} object, but the {@code CallSite} does not change
* state.
* <p>
* Here is a sample use of call sites and bootstrap methods which links every
* dynamic call site to print its arguments:
<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
private static void printArgs(Object... args) {
System.out.println(java.util.Arrays.deepToString(args));
}
private static final MethodHandle printArgs;
static {
MethodHandles.Lookup lookup = MethodHandles.lookup();
Class thisClass = lookup.lookupClass(); // (who am I?)
printArgs = lookup.findStatic(thisClass,
"printArgs", MethodType.methodType(void.class, Object[].class));
Linkage.registerBootstrapMethod("bootstrapDynamic");
}
private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) {
// ignore caller and name, but match the type:
return new CallSite(MethodHandles.collectArguments(printArgs, type));
}
</pre></blockquote>
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle) * @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG * @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(); private static final Access IMPL_TOKEN = Access.getToken();
/*
// Fields used only by the JVM. Do not use or change. // Fields used only by the JVM. Do not use or change.
private Object vmmethod; private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
int callerMID, callerBCI; // supplied by the JVM private int vmindex; // supplied by the JVM (BCI within calling method)
// The actual payload of this call site:
private MethodHandle target; private MethodHandle target;
final Object caller; // usually a class // Remove this field for PFD and delete deprecated methods:
final String name; private MemberName calleeNameRemoveForPFD;
final MethodType type;
*/
/** /**
* Make a call site given the parameters from a call to the bootstrap method. * Make a blank call site object.
* The resulting call site is in an unlinked state, which means that before * Before it is returned from a bootstrap method, this {@code CallSite} object
* it is returned from a bootstrap method call it must be provided with * must be provided with
* a target method via a call to {@link CallSite#setTarget}. * a target method via a call to {@link CallSite#setTarget(MethodHandle) setTarget},
* @param caller the class in which the relevant {@code invokedynamic} instruction occurs * or by a subclass override of {@link CallSite#initialTarget(Class,String,MethodType) initialTarget}.
* @param name the name specified by the {@code invokedynamic} instruction
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
*/ */
public CallSite(Object caller, String name, MethodType type) { public CallSite() {
super(IMPL_TOKEN, caller, name, type);
} }
private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) { /**
site.callerMID = callerMID; * Make a blank call site object, possibly equipped with an initial target method handle.
site.callerBCI = callerBCI; * The initial target reference may be null, in which case the {@code CallSite} object
site.ensureTarget(); * must be provided with a target method via a call to {@link CallSite#setTarget},
* or by a subclass override of {@link CallSite#initialTarget}.
* @param target the method handle which will be the initial target of the call site, or null if there is none yet
*/
public CallSite(MethodHandle target) {
this.target = target;
} }
private void ensureTarget() {
// Note use of super, which accesses the field directly, /** @deprecated transitional form defined in EDR but removed in PFD */
// without deferring to possible subclass overrides. public CallSite(Class<?> caller, String name, MethodType type) {
if (super.getTarget() == null) { this.calleeNameRemoveForPFD = new MemberName(caller, name, type);
super.setTarget(this.initialTarget()); }
super.getTarget().type(); // provoke NPE if still null /** @deprecated transitional form defined in EDR but removed in PFD */
public Class<?> callerClass() {
MemberName callee = this.calleeNameRemoveForPFD;
return callee == null ? null : callee.getDeclaringClass();
}
/** @deprecated transitional form defined in EDR but removed in PFD */
public String name() {
MemberName callee = this.calleeNameRemoveForPFD;
return callee == null ? null : callee.getName();
}
/** @deprecated transitional form defined in EDR but removed in PFD */
public MethodType type() {
MemberName callee = this.calleeNameRemoveForPFD;
return callee == null ? (target == null ? null : target.type()) : callee.getMethodType();
}
/** @deprecated transitional form defined in EDR but removed in PFD */
protected MethodHandle initialTarget() {
return initialTarget(callerClass(), name(), type());
}
/** Report if the JVM has linked this {@code CallSite} object to a dynamic call site instruction.
* Once it is linked, it is never unlinked.
*/
private boolean isLinked() {
return vmmethod != null;
}
/** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
* The parameters are JVM-specific.
*/
void initializeFromJVM(String name,
MethodType type,
MemberName callerMethod,
int callerBCI) {
if (this.isLinked()) {
throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction");
}
MethodHandle target = this.target;
if (target == null) {
this.target = target = this.initialTarget(callerMethod.getDeclaringClass(), name, type);
}
if (!target.type().equals(type)) {
throw wrongTargetType(target, type);
} }
this.vmindex = callerBCI;
this.vmmethod = callerMethod;
assert(this.isLinked());
} }
/** /**
...@@ -108,14 +200,18 @@ public class CallSite ...@@ -108,14 +200,18 @@ public class CallSite
* the method {@code initialTarget} is called to produce an initial * the method {@code initialTarget} is called to produce an initial
* non-null target. (Live call sites must never have null targets.) * non-null target. (Live call sites must never have null targets.)
* <p> * <p>
* The arguments are the same as those passed to the bootstrap method.
* Thus, a bootstrap method is free to ignore the arguments and simply
* create a "blank" {@code CallSite} object of an appropriate subclass.
* <p>
* If the bootstrap method itself does not initialize the call site, * If the bootstrap method itself does not initialize the call site,
* this method must be overridden, because it just raises an * this method must be overridden, because it just raises an
* {@code InvokeDynamicBootstrapError}, which in turn causes the * {@code InvokeDynamicBootstrapError}, which in turn causes the
* linkage of the {@code invokedynamic} instruction to terminate * linkage of the {@code invokedynamic} instruction to terminate
* abnormally. * abnormally.
*/ */
protected MethodHandle initialTarget() { protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) {
throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+this); throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type);
} }
/** /**
...@@ -137,11 +233,11 @@ public class CallSite ...@@ -137,11 +233,11 @@ public class CallSite
* @see #setTarget * @see #setTarget
*/ */
public MethodHandle getTarget() { public MethodHandle getTarget() {
return super.getTarget(); return target;
} }
/** /**
* Link or relink the call site, by setting its target method. * Set the target method of this call site.
* <p> * <p>
* The interactions of {@code setTarget} with memory are the same * The interactions of {@code setTarget} with memory are the same
* as of a write to an ordinary variable, such as an array element or a * as of a write to an ordinary variable, such as an array element or a
...@@ -152,96 +248,46 @@ public class CallSite ...@@ -152,96 +248,46 @@ public class CallSite
* Stronger guarantees can be created by putting appropriate operations * Stronger guarantees can be created by putting appropriate operations
* into the bootstrap method and/or the target methods used * into the bootstrap method and/or the target methods used
* at any given call site. * at any given call site.
* @param target the new target, or null if it is to be unlinked * @param newTarget the new target
* @throws NullPointerException if the proposed new target is null * @throws NullPointerException if the proposed new target is null
* @throws WrongMethodTypeException if the proposed new target * @throws WrongMethodTypeException if the call site is linked and the proposed new target
* has a method type that differs from the call site's {@link #type()} * has a method type that differs from the previous target
*/
public void setTarget(MethodHandle target) {
checkTarget(target);
super.setTarget(target);
}
protected void checkTarget(MethodHandle target) {
target.type(); // provoke NPE
if (!canSetTarget(target))
throw new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type());
}
protected boolean canSetTarget(MethodHandle target) {
return (target != null && target.type() == type());
}
/**
* Report the class containing the call site.
* This is an immutable property of the call site, set from the first argument to the constructor.
* @return class containing the call site
*/
public Class<?> callerClass() {
return (Class) caller;
}
/**
* Report the method name specified in the {@code invokedynamic} instruction.
* This is an immutable property of the call site, set from the second argument to the constructor.
* <p>
* Note that the name is a JVM bytecode name, and as such can be any
* non-empty string, as long as it does not contain certain "dangerous"
* characters such as slash {@code '/'} and dot {@code '.'}.
* See the Java Virtual Machine specification for more details.
* <p>
* Application such as a language runtimes may need to encode
* arbitrary program element names and other configuration information
* into the name. A standard convention for doing this is
* <a href="http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm">specified here</a>.
* @return method name specified by the call site
*/ */
public String name() { public void setTarget(MethodHandle newTarget) {
return name; MethodType newType = newTarget.type(); // null check!
MethodHandle oldTarget = this.target;
if (oldTarget == null) {
// CallSite is not yet linked.
assert(!isLinked());
this.target = newTarget; // might be null!
return;
}
MethodType oldType = oldTarget.type();
if (!newTarget.type().equals(oldType))
throw wrongTargetType(newTarget, oldType);
if (oldTarget != newTarget)
CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
} }
/** private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
* Report the method name specified in the {@code invokedynamic} instruction, return new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type);
* as a series of components, individually demangled according to
* the standard convention
* <a href="http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm">specified here</a>.
* <p>
* Non-empty runs of characters between dangerous characters are demangled.
* Each component is either a completely arbitrary demangled string,
* or else a character constant for a punctuation character, typically ':'.
* (In principle, the character can be any dangerous character that the
* JVM lets through in a method name, such as '$' or ']'.
* Runtime implementors are encouraged to use colon ':' for building
* structured names.)
* <p>
* In the common case where the name contains no dangerous characters,
* the result is an array whose only element array is the demangled
* name at the call site. Such a demangled name can be any sequence
* of any number of any unicode characters.
* @return method name components specified by the call site
*/
public Object[] nameComponents() {
return BytecodeName.parseBytecodeName(name);
} }
/** /** Produce a printed representation that displays information about this call site
* Report the resolved result and parameter types of this call site, * that may be useful to the human reader.
* which are derived from its bytecode-level invocation descriptor.
* The types are packaged into a {@link MethodType}.
* Any linked target of this call site must be exactly this method type.
* This is an immutable property of the call site, set from the third argument to the constructor.
* @return method type specified by the call site
*/ */
public MethodType type() {
return type;
}
@Override @Override
public String toString() { public String toString() {
return "CallSite#"+hashCode()+"["+name+type+" => "+getTarget()+"]"; StringBuilder buf = new StringBuilder("CallSite#");
buf.append(hashCode());
if (!isLinked())
buf.append("[unlinked]");
else
buf.append("[")
.append("from ").append(vmmethod.getDeclaringClass().getName())
.append(" : ").append(getTarget().type())
.append(" => ").append(getTarget())
.append("]");
return buf.toString();
} }
// Package-local constant:
static final MethodHandle GET_TARGET = MethodHandleImpl.getLookup(IMPL_TOKEN).
findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
} }
...@@ -26,27 +26,25 @@ ...@@ -26,27 +26,25 @@
package java.dyn; package java.dyn;
/** /**
* Syntactic marker to request javac to emit an {@code invokedynamic} instruction. * {@code InvokeDynamic} is a class with neither methods nor instances,
* An {@code invokedynamic} instruction is a 5-byte bytecoded instruction * which serves only as a syntactic marker in Java source code for
* which begins with an opcode byte of value 186 ({@code 0xBA}), * an {@code invokedynamic} instruction.
* and is followed by a two-byte index of a {@code NameAndType} constant * (See <a href="package-summary.html#jvm_mods">the package information</a> for specifics on this instruction.)
* pool entry, then by two zero bytes. The constant pool reference gives
* the method name and argument and return types of the call site; there
* is no other information provided at the call site.
* <p> * <p>
* The {@code invokedynamic} instruction is incomplete without a target method. * The {@code invokedynamic} instruction is incomplete without a target method.
* The target method is a property of the reified call site object * The target method is a property of the reified {@linkplain CallSite call site object}
* (of type {@link CallSite}) which is in a one-to-one association with each * which is linked to each active {@code invokedynamic} instruction.
* corresponding {@code invokedynamic} instruction. The call site object * The call site object is initially produced by a
* is initially produced by a <em>bootstrap method</em> associated with * {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
* the call site, via the various overloadings of {@link Linkage#registerBootstrapMethod}. * associated with the class whose bytecodes include the dynamic call site.
* <p> * <p>
* The type {@code InvokeDynamic} has no particular meaning as a * The type {@code InvokeDynamic} has no particular meaning as a
* class or interface supertype, or an object type; it can never be instantiated. * class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods. * 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. * It may be viewed as a pure syntactic marker of static calls.
* It may be imported for ease of use.
* <p> * <p>
* Here are some examples of usage: * Here are some examples:
* <p><blockquote><pre> * <p><blockquote><pre>
* Object x; String s; int i; * Object x; String s; int i;
* x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object; * x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
...@@ -65,6 +63,7 @@ package java.dyn; ...@@ -65,6 +63,7 @@ package java.dyn;
* which must be registered by the static initializer of the enclosing class. * which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
@MethodHandle.PolymorphicSignature
public final class InvokeDynamic { public final class InvokeDynamic {
private InvokeDynamic() { throw new InternalError(); } // do not instantiate private InvokeDynamic() { throw new InternalError(); } // do not instantiate
......
/* /*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,24 +27,29 @@ package java.dyn; ...@@ -27,24 +27,29 @@ package java.dyn;
/** /**
* Thrown to indicate that an {@code invokedynamic} instruction has * Thrown to indicate that an {@code invokedynamic} instruction has
* failed to find its bootstrap method, or the bootstrap method has * failed to find its
* failed to provide a call site with a non-null target. * {@linkplain Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method},
* or the bootstrap method has
* failed to provide a
* {@linkplain CallSite} call site with a non-null {@linkplain MethodHandle target}
* of the correct {@linkplain MethodType method type}.
* <p> * <p>
* The boostrap method must have been declared during a class's initialization * The bootstrap method must have been declared during a class's initialization
* by a call to {@link Linkage#registerBootstrapMethod}. * by a call to one of the overloadings of
* {@link Linkage#registerBootstrapMethod registerBootstrapMethod}.
* *
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
public class InvokeDynamicBootstrapError extends LinkageError { public class InvokeDynamicBootstrapError extends LinkageError {
/** /**
* Constructs a {@code InvokeDynamicBootstrapError} with no detail message. * Constructs an {@code InvokeDynamicBootstrapError} with no detail message.
*/ */
public InvokeDynamicBootstrapError() { public InvokeDynamicBootstrapError() {
super(); super();
} }
/** /**
* Constructs a {@code InvokeDynamicBootstrapError} with the specified * Constructs an {@code InvokeDynamicBootstrapError} with the specified
* detail message. * detail message.
* *
* @param s the detail message. * @param s the detail message.
......
...@@ -28,7 +28,8 @@ package java.dyn; ...@@ -28,7 +28,8 @@ package java.dyn;
import sun.dyn.Access; import sun.dyn.Access;
/** /**
* A Java method handle extends the basic method handle type with additional * A Java method handle is a deprecated proposal for extending
* the basic method handle type with additional
* programmer defined methods and fields. * programmer defined methods and fields.
* Its behavior as a method handle is determined at instance creation time, * Its behavior as a method handle is determined at instance creation time,
* by providing the new instance with an "entry point" method handle * by providing the new instance with an "entry point" method handle
...@@ -62,11 +63,11 @@ import sun.dyn.Access; ...@@ -62,11 +63,11 @@ import sun.dyn.Access;
* greeter.run(); // prints "hello, world" * greeter.run(); // prints "hello, world"
* // Statically typed method handle invocation (most direct): * // Statically typed method handle invocation (most direct):
* MethodHandle mh = greeter; * MethodHandle mh = greeter;
* mh.&lt;void&gt;invoke(); // also prints "hello, world" * mh.&lt;void&gt;invokeExact(); // also prints "hello, world"
* // Dynamically typed method handle invocation: * // Dynamically typed method handle invocation:
* MethodHandles.invoke(greeter); // also prints "hello, world" * MethodHandles.invokeExact(greeter); // also prints "hello, world"
* greeter.setGreeting("howdy"); * greeter.setGreeting("howdy");
* mh.invoke(); // prints "howdy, world" (object-like mutable behavior) * mh.invokeExact(); // prints "howdy, world" (object-like mutable behavior)
* </pre></blockquote> * </pre></blockquote>
* <p> * <p>
* In the example of {@code Greeter}, the method {@code run} provides the entry point. * In the example of {@code Greeter}, the method {@code run} provides the entry point.
...@@ -81,7 +82,7 @@ import sun.dyn.Access; ...@@ -81,7 +82,7 @@ import sun.dyn.Access;
* inner class: * inner class:
* <p><blockquote><pre> * <p><blockquote><pre>
* // We can also do this with symbolic names and/or inner classes: * // We can also do this with symbolic names and/or inner classes:
* MethodHandles.invoke(new JavaMethodHandle("yow") { * MethodHandles.invokeExact(new JavaMethodHandle("yow") {
* void yow() { System.out.println("yow, world"); } * void yow() { System.out.println("yow, world"); }
* }); * });
* </pre></blockquote> * </pre></blockquote>
...@@ -101,7 +102,7 @@ import sun.dyn.Access; ...@@ -101,7 +102,7 @@ import sun.dyn.Access;
* Greeter greeter = new Greeter("world"); * Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world" * greeter.run(); // prints "hello, world"
* MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter); * MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
* mh.invoke(); // also prints "hello, world" * mh.invokeExact(); // also prints "hello, world"
* </pre></blockquote> * </pre></blockquote>
* Note that the method handle must be separately created as a view on the base object. * Note that the method handle must be separately created as a view on the base object.
* This increases footprint, complexity, and dynamic indirections. * This increases footprint, complexity, and dynamic indirections.
...@@ -113,7 +114,7 @@ import sun.dyn.Access; ...@@ -113,7 +114,7 @@ import sun.dyn.Access;
* MethodHandle greeter = new JavaMethodHandle("run") { * MethodHandle greeter = new JavaMethodHandle("run") {
* private void run() { System.out.println("hello, "+greetee); } * private void run() { System.out.println("hello, "+greetee); }
* } * }
* greeter.invoke(); // prints "hello, world" * greeter.invokeExact(); // prints "hello, world"
* </pre></blockquote> * </pre></blockquote>
* <p> * <p>
* Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle, * Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
...@@ -137,10 +138,12 @@ import sun.dyn.Access; ...@@ -137,10 +138,12 @@ import sun.dyn.Access;
* public Number get(long i) { return stuff[(int)i]; } * public Number get(long i) { return stuff[(int)i]; }
* public void set(long i, Object x) { stuff[(int)i] = x; } * public void set(long i, Object x) { stuff[(int)i] = x; }
* } * }
* int x = (Integer) stuffPtr.&lt;Number&gt;invoke(1L); // 456 * int x = (Integer) stuffPtr.&lt;Number&gt;invokeExact(1L); // 456
* stuffPtr.setter().&lt;void&gt;invoke(0L, (Number) 789); // replaces 123 with 789 * stuffPtr.setter().&lt;void&gt;invokeExact(0L, (Number) 789); // replaces 123 with 789
* </pre></blockquote> * </pre></blockquote>
* @see MethodHandle * @see MethodHandle
* @deprecated The JSR 292 EG intends to replace {@code JavaMethodHandle} with
* an interface-based API for mixing method handle behavior with other classes.
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
public abstract class JavaMethodHandle public abstract class JavaMethodHandle
......
...@@ -25,14 +25,19 @@ ...@@ -25,14 +25,19 @@
package java.dyn; package java.dyn;
import java.lang.annotation.Annotation;
import java.dyn.MethodHandles.Lookup; import java.dyn.MethodHandles.Lookup;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import sun.dyn.Access; import sun.dyn.Access;
import sun.dyn.MethodHandleImpl;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege; import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
import static sun.dyn.MemberName.newIllegalArgumentException;
/** /**
* Static methods which control the linkage of invokedynamic call sites. * This class consists exclusively of static methods that control
* the linkage of {@code invokedynamic} instructions, and specifically
* their reification as {@link CallSite} objects.
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
public class Linkage { public class Linkage {
...@@ -42,102 +47,137 @@ public class Linkage { ...@@ -42,102 +47,137 @@ public class Linkage {
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Register a <em>bootstrap method</em> to use when linking a given caller class. * Register a <em>bootstrap method</em> to use when linking dynamic call sites within
* It must be a method handle of a type equivalent to {@link CallSite#CallSite}. * a given caller class.
* In other words, it must act as a factory method which accepts the arguments * <p>
* to {@code CallSite}'s constructor (a class, a string, and a method type), * A bootstrap method must be a method handle with a return type of {@link CallSite}
* and the following arguments:
* <ul>
* <li>the class containing the {@code invokedynamic} instruction, for which the bootstrap method was registered
* <li>the name of the method being invoked (a {@link String})
* <li>the type of the method being invoked (a {@link MethodType})
* <li><em>TBD</em> optionally, an unordered array of {@link Annotation}s attached to the call site
* <em>(Until this feature is implemented, this will always receive an empty array.)</em>
* </ul>
* <em>(TBD: The final argument type may be missing from the method handle's type.
* Additional arguments may be added in the future.)</em>
* The bootstrap method acts as a factory method which accepts the given arguments
* and returns a {@code CallSite} object (possibly of a subclass of {@code CallSite}). * and returns a {@code CallSite} object (possibly of a subclass of {@code CallSite}).
* <p> * <p>
* The registration will fail with an {@code IllegalStateException} if any of the following conditions hold: * The registration must take place exactly once, either before the class has begun
* being initialized, or from within the class's static initializer.
* Registration will fail with an exception if any of the following conditions hold:
* <ul> * <ul>
* <li>The caller of this method is in a different package than the {@code callerClass}, * <li>The immediate caller of this method is in a different package than the given caller class,
* and there is a security manager, and its {@code checkPermission} call throws * and there is a security manager, and its {@code checkPermission} call throws
* when passed {@link LinkagePermission}("registerBootstrapMethod",callerClass). * when passed {@link LinkagePermission}("registerBootstrapMethod",callerClass).
* <li>The given class already has a bootstrap method from a previous * <li>The given caller class already has a bootstrap method registered.
* call to this method. * <li>The given caller class is already fully initialized.
* <li>The given class is already fully initialized. * <li>The given caller class is in the process of initialization, in another thread.
* <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> * </ul>
* Because of these rules, a class may install its own bootstrap method in * Because of these rules, a class may install its own bootstrap method in
* a static initializer. * a static initializer.
* @param callerClass a class that may have {@code invokedynamic} sites * @param callerClass a class that may have {@code invokedynamic} sites
* @param bootstrapMethod the method to use to bootstrap all such sites * @param bootstrapMethod the method to use to bootstrap all such sites
* @exception IllegalArgumentException if the class argument is null or
* a primitive class, or if the bootstrap method is the wrong type
* @exception IllegalStateException if the class already has a bootstrap
* method, or if the its static initializer has already run
* or is already running in another thread
* @exception SecurityException if there is a security manager installed,
* and a {@link LinkagePermission} check fails for "registerBootstrapMethod"
*/ */
public static public static
void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) { void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
Class callc = Reflection.getCallerClass(2); Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod"); checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
checkBSM(bootstrapMethod); checkBSM(bootstrapMethod);
synchronized (bootstrapMethods) { MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
if (bootstrapMethods.containsKey(callerClass))
throw new IllegalStateException("bootstrap method already declared in "+callerClass);
bootstrapMethods.put(callerClass, bootstrapMethod);
}
} }
static void checkBSM(MethodHandle mh) { static private void checkBSM(MethodHandle mh) {
if (mh == null) throw new IllegalArgumentException("null bootstrap method"); if (mh == null) throw newIllegalArgumentException("null bootstrap method");
if (mh.type() == OLD_BOOTSTRAP_METHOD_TYPE) // FIXME: delete at EDR/PFD if (mh.type() == BOOTSTRAP_METHOD_TYPE_2)
throw new WrongMethodTypeException("bootstrap method must be a CallSite factory"); // For now, always pass an empty array for the Annotations argument
if (mh.type() != BOOTSTRAP_METHOD_TYPE) mh = MethodHandles.insertArguments(mh, BOOTSTRAP_METHOD_TYPE_2.parameterCount()-1,
throw new WrongMethodTypeException(mh.toString()); (Object)NO_ANNOTATIONS);
if (mh.type() == BOOTSTRAP_METHOD_TYPE) return;
throw new WrongMethodTypeException(mh.toString());
} }
static private final Annotation[] NO_ANNOTATIONS = { };
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Simplified version of registerBootstrapMethod for self-registration, * Simplified version of {@code registerBootstrapMethod} for self-registration,
* to be called from a static initializer. * to be called from a static initializer.
* Finds a static method of the required type in the * Finds a static method of the required type in the
* given class, and installs it on the caller. * given runtime class, and installs it on the caller class.
* @throws IllegalArgumentException if there is no such method * @throws NoSuchMethodException if there is no such method
* @throws IllegalStateException if the caller class's static initializer
* has already run, or is already running in another thread
*/ */
public static public static
void registerBootstrapMethod(Class<?> runtime, String name) { void registerBootstrapMethod(Class<?> runtime, String name) {
Class callc = Reflection.getCallerClass(2); Class callerClass = Reflection.getCallerClass(2);
Lookup lookup = new Lookup(IMPL_TOKEN, callc); registerBootstrapMethodLookup(callerClass, runtime, name);
MethodHandle bootstrapMethod =
lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
} }
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Simplified version of registerBootstrapMethod for self-registration, * Simplified version of {@code registerBootstrapMethod} for self-registration,
* to be called from a static initializer. * to be called from a static initializer.
* Finds a static method of the required type in the * Finds a static method of the required type in the
* caller's class, and installs it on the caller. * caller class itself, and installs it on the caller class.
* @throws IllegalArgumentException if there is no such method * @throws IllegalArgumentException if there is no such method
* @throws IllegalStateException if the caller class's static initializer
* has already run, or is already running in another thread
*/ */
public static public static
void registerBootstrapMethod(String name) { void registerBootstrapMethod(String name) {
Class callc = Reflection.getCallerClass(2); Class callerClass = Reflection.getCallerClass(2);
Lookup lookup = new Lookup(IMPL_TOKEN, callc); registerBootstrapMethodLookup(callerClass, callerClass, name);
MethodHandle bootstrapMethod = }
lookup.findStatic(callc, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here private static
void registerBootstrapMethodLookup(Class<?> callerClass, Class<?> runtime, String name) {
Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
MethodHandle bootstrapMethod;
// Try both types. TBD
try {
bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE_2);
} catch (NoAccessException ex) {
bootstrapMethod = null;
}
if (bootstrapMethod == null) {
try {
bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
} catch (NoAccessException ex) {
throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
}
}
checkBSM(bootstrapMethod); checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod); MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
} }
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Report the bootstrap method registered for a given class. * Report the bootstrap method registered for a given caller class.
* Returns null if the class has never yet registered a bootstrap method. * Returns null if the class has never yet registered a bootstrap method.
* Only callers privileged to set the bootstrap method may inquire * Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry * about it, because a bootstrap method is potentially a back-door entry
* point into its class. * point into its class.
* @exception IllegalArgumentException if the argument is null or
* a primitive class
* @exception SecurityException if there is a security manager installed,
* and the immediate caller of this method is not in the same
* package as the caller class
* and a {@link LinkagePermission} check fails for "getBootstrapMethod"
*/ */
public static public static
MethodHandle getBootstrapMethod(Class callerClass) { MethodHandle getBootstrapMethod(Class callerClass) {
Class callc = Reflection.getCallerClass(2); Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod"); checkBootstrapPrivilege(callc, callerClass, "getBootstrapMethod");
synchronized (bootstrapMethods) { return MethodHandleImpl.getBootstrap(IMPL_TOKEN, callerClass);
return bootstrapMethods.get(callerClass);
}
} }
/** /**
...@@ -148,13 +188,10 @@ public class Linkage { ...@@ -148,13 +188,10 @@ public class Linkage {
public static final MethodType BOOTSTRAP_METHOD_TYPE public static final MethodType BOOTSTRAP_METHOD_TYPE
= MethodType.methodType(CallSite.class, = MethodType.methodType(CallSite.class,
Class.class, String.class, MethodType.class); Class.class, String.class, MethodType.class);
static final MethodType BOOTSTRAP_METHOD_TYPE_2
private static final MethodType OLD_BOOTSTRAP_METHOD_TYPE = MethodType.methodType(CallSite.class,
= MethodType.methodType(Object.class, Class.class, String.class, MethodType.class,
CallSite.class, Object[].class); Annotation[].class);
private static final WeakHashMap<Class, MethodHandle> bootstrapMethods =
new WeakHashMap<Class, MethodHandle>();
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
...@@ -182,10 +219,8 @@ public class Linkage { ...@@ -182,10 +219,8 @@ public class Linkage {
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Invalidate all <code>invokedynamic</code> call sites in the bytecodes * Invalidate all {@code invokedynamic} call sites in the bytecodes
* of any methods of the given class. * of any methods of the given class.
* (These are exactly those sites which report the given class
* via the {@link CallSite#callerClass()} method.)
* <p> * <p>
* When this method returns, every matching <code>invokedynamic</code> * When this method returns, every matching <code>invokedynamic</code>
* instruction will invoke its bootstrap method on next call. * instruction will invoke its bootstrap method on next call.
...@@ -201,18 +236,4 @@ public class Linkage { ...@@ -201,18 +236,4 @@ public class Linkage {
} }
throw new UnsupportedOperationException("NYI"); throw new UnsupportedOperationException("NYI");
} }
private static Object doNotBootstrap(CallSite site, Object... arguments) {
throw new UnsupportedOperationException("call site must not have null target: "+site);
}
private static final MethodHandle DO_NOT_BOOTSTRAP =
MethodHandles.Lookup.IMPL_LOOKUP.findStatic(Linkage.class, "doNotBootstrap",
OLD_BOOTSTRAP_METHOD_TYPE);
// Up-call from the JVM. Obsolete. FIXME: Delete from VM then from here.
static
MethodHandle findBootstrapMethod(Class callerClass, Class searchBootstrapClass) {
return DO_NOT_BOOTSTRAP;
}
} }
...@@ -31,23 +31,17 @@ import java.util.Hashtable; ...@@ -31,23 +31,17 @@ import java.util.Hashtable;
import java.util.StringTokenizer; import java.util.StringTokenizer;
/** /**
* This class is for runtime permissions. A RuntimePermission * This class is for managing runtime permission checking for
* contains a name (also referred to as a "target name") but * operations performed by methods in the {@link Linkage} class.
* Like a {@link RuntimePermission}, on which it is modeled,
* a {@code LinkagePermission} contains a target name but
* no actions list; you either have the named permission * no actions list; you either have the named permission
* or you don't. * or you don't.
* * <p>
* <P> * The following table lists all the possible {@code LinkagePermission} target names,
* The target name is the name of the runtime permission (see below). The
* naming convention follows the hierarchical property naming convention.
* Also, an asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match. For example: "loadLibrary.*" or "*" is valid,
* "*loadLibrary" or "a*b" is not valid.
* <P>
* The following table lists all the possible RuntimePermission target names,
* and for each provides a description of what the permission allows * and for each provides a description of what the permission allows
* and a discussion of the risks of granting code the permission. * and a discussion of the risks of granting code the permission.
* <P> * <p>
* *
* <table border=1 cellpadding=5 summary="permission target name, * <table border=1 cellpadding=5 summary="permission target name,
* what the target allows,and associated risks"> * what the target allows,and associated risks">
...@@ -59,15 +53,17 @@ import java.util.StringTokenizer; ...@@ -59,15 +53,17 @@ import java.util.StringTokenizer;
* *
* <tr> * <tr>
* <td>registerBootstrapMethod.{class name}</td> * <td>registerBootstrapMethod.{class name}</td>
* <td>Specifying a bootstrap method for invokedynamic, within a class of the given name</td> * <td>Specifying a bootstrap method for {@code invokedynamic} instructions within a class of the given name</td>
* <td>An attacker could attempt to attach a bootstrap method to a class which * <td>An attacker could attempt to attach a bootstrap method to a class which
* has just been loaded, thus gaining control of its invokedynamic calls.</td> * has just been loaded, thus gaining control of its {@code invokedynamic} calls.</td>
* </tr> * </tr>
* *
* <tr> * <tr>
* <td>invalidateAll</td> * <td>invalidateAll</td>
* <td>Force the relinking of invokedynamic call sites everywhere.</td> * <td>Force the relinking of invokedynamic call sites everywhere.</td>
* <td>This could allow an attacker to slow down the system, or perhaps surface timing bugs in a dynamic language implementations, by forcing redundant relinking operations.</td> * <td>This could allow an attacker to slow down the system,
* or perhaps expose timing bugs in a dynamic language implementations,
* by forcing redundant relinking operations.</td>
* </tr> * </tr>
* *
* *
...@@ -78,7 +74,7 @@ import java.util.StringTokenizer; ...@@ -78,7 +74,7 @@ import java.util.StringTokenizer;
* </tr> * </tr>
* </table> * </table>
* *
* @see java.security.BasicPermission * @see java.security.RuntimePermission
* @see java.lang.SecurityManager * @see java.lang.SecurityManager
* *
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
......
...@@ -34,32 +34,34 @@ import static java.dyn.MethodHandles.invokers; // package-private API ...@@ -34,32 +34,34 @@ import static java.dyn.MethodHandles.invokers; // package-private API
import static sun.dyn.MemberName.newIllegalArgumentException; // utility import static sun.dyn.MemberName.newIllegalArgumentException; // utility
/** /**
* A method handle is a typed reference to the entry point of a method. * A method handle is a typed, directly executable reference to a method,
* constructor, field, or similar low-level operation, with optional
* conversion or substitution of arguments or return values.
* <p> * <p>
* Method handles are strongly typed according to signature. * Method handles are strongly typed according to signature.
* They are not distinguished by method name or enclosing class. * They are not distinguished by method name or enclosing class.
* A method handle must be invoked under a signature which exactly matches * A method handle must be invoked under a signature which exactly matches
* the method handle's own type. * the method handle's own {@link MethodType method type}.
* <p> * <p>
* Every method handle confesses its type via the <code>type</code> accessor. * Every method handle confesses its type via the {@code type} accessor.
* The structure of this type is a series of classes, one of which is * The structure of this type is a series of classes, one of which is
* the return type of the method (or <code>void.class</code> if none). * the return type of the method (or {@code void.class} if none).
* <p> * <p>
* Every method handle appears as an object containing a method named * Every method handle appears as an object containing a method named
* <code>invoke</code>, whose signature exactly matches * {@code invoke}, whose signature exactly matches
* the method handle's type. * the method handle's type.
* A Java method call expression, which compiles to an * A Java method call expression, which compiles to an
* <code>invokevirtual</code> instruction, * {@code invokevirtual} instruction,
* can invoke this method from Java source code. * can invoke this method from Java source code.
* <p> * <p>
* Every call to a method handle specifies an intended method type, * Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle. * which must exactly match the type of the method handle.
* (The type is specified in the <code>invokevirtual</code> instruction, * (The type is specified in the {@code invokevirtual} instruction,
* via a {@code CONSTANT_NameAndType} constant pool entry.) * via a {@code CONSTANT_NameAndType} constant pool entry.)
* The call looks within the receiver object for a method * The call looks within the receiver object for a method
* named <code>invoke</code> of the intended method type. * named {@code invoke} of the intended method type.
* The call fails with a {@link WrongMethodTypeException} * The call fails with a {@link WrongMethodTypeException}
* if the method does not exist, even if there is an <code>invoke</code> * if the method does not exist, even if there is an {@code invoke}
* method of a closely similar signature. * method of a closely similar signature.
* As with other kinds * As with other kinds
* of methods in the JVM, signature matching during method linkage * of methods in the JVM, signature matching during method linkage
...@@ -76,13 +78,13 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility ...@@ -76,13 +78,13 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* They should not be passed to untrusted code. * They should not be passed to untrusted code.
* <p> * <p>
* Bytecode in an extended JVM can directly call a method handle's * Bytecode in an extended JVM can directly call a method handle's
* <code>invoke</code> from an <code>invokevirtual</code> instruction. * {@code invoke} from an {@code invokevirtual} instruction.
* The receiver class type must be <code>MethodHandle</code> and the method name * The receiver class type must be {@code MethodHandle} and the method name
* must be <code>invoke</code>. The signature of the invocation * must be {@code invoke}. The signature of the invocation
* (after resolving symbolic type names) must exactly match the method type * (after resolving symbolic type names) must exactly match the method type
* of the target method. * of the target method.
* <p> * <p>
* Every <code>invoke</code> method always throws {@link Exception}, * Every {@code invoke} method always throws {@link Exception},
* which is to say that there is no static restriction on what a method handle * 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 * can throw. Since the JVM does not distinguish between checked
* and unchecked exceptions (other than by their class, of course), * and unchecked exceptions (other than by their class, of course),
...@@ -92,11 +94,11 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility ...@@ -92,11 +94,11 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* throw {@code Exception}, or else must catch all checked exceptions locally. * throw {@code Exception}, or else must catch all checked exceptions locally.
* <p> * <p>
* Bytecode in an extended JVM can directly obtain a method handle * Bytecode in an extended JVM can directly obtain a method handle
* for any accessible method from a <code>ldc</code> instruction * for any accessible method from a {@code ldc} instruction
* which refers to a <code>CONSTANT_Methodref</code> or * which refers to a {@code CONSTANT_Methodref} or
* <code>CONSTANT_InterfaceMethodref</code> constant pool entry. * {@code CONSTANT_InterfaceMethodref} constant pool entry.
* <p> * <p>
* All JVMs can also use a reflective API called <code>MethodHandles</code> * All JVMs can also use a reflective API called {@code MethodHandles}
* for creating and calling method handles. * for creating and calling method handles.
* <p> * <p>
* A method reference may refer either to a static or non-static method. * A method reference may refer either to a static or non-static method.
...@@ -104,7 +106,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility ...@@ -104,7 +106,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* receiver argument, prepended before any other arguments. * receiver argument, prepended before any other arguments.
* In the method handle's type, the initial receiver argument is typed * In the method handle's type, the initial receiver argument is typed
* according to the class under which the method was initially requested. * according to the class under which the method was initially requested.
* (E.g., if a non-static method handle is obtained via <code>ldc</code>, * (E.g., if a non-static method handle is obtained via {@code ldc},
* the type of the receiver is the class named in the constant pool entry.) * the type of the receiver is the class named in the constant pool entry.)
* <p> * <p>
* When a method handle to a virtual method is invoked, the method is * When a method handle to a virtual method is invoked, the method is
...@@ -113,38 +115,38 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility ...@@ -113,38 +115,38 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* A non-virtual method handles to a specific virtual method implementation * A non-virtual method handles to a specific virtual method implementation
* can also be created. These do not perform virtual lookup based on * can also be created. These do not perform virtual lookup based on
* receiver type. Such a method handle simulates the effect of * receiver type. Such a method handle simulates the effect of
* an <code>invokespecial</code> instruction to the same method. * an {@code invokespecial} instruction to the same method.
* <p> * <p>
* Here are some examples of usage: * Here are some examples of usage:
* <p><blockquote><pre> * <p><blockquote><pre>
* Object x, y; String s; int i; Object x, y; String s; int i;
* MethodType mt; MethodHandle mh; MethodType mt; MethodHandle mh;
* MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandles.Lookup lookup = MethodHandles.lookup();
* // mt is {(char,char) =&gt; String} // mt is {(char,char) =&gt; String}
* mt = MethodType.make(String.class, char.class, char.class); mt = MethodType.methodType(String.class, char.class, char.class);
* mh = lookup.findVirtual(String.class, "replace", mt); mh = lookup.findVirtual(String.class, "replace", mt);
* // (Ljava/lang/String;CC)Ljava/lang/String; // (Ljava/lang/String;CC)Ljava/lang/String;
* s = mh.&lt;String&gt;invoke("daddy",'d','n'); s = mh.&lt;String&gt;invokeExact("daddy",'d','n');
* assert(s.equals("nanny")); assert(s.equals("nanny"));
* // weakly typed invocation (using MHs.invoke) // weakly typed invocation (using MHs.invoke)
* s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v'); s = (String) mh.invokeVarargs("sappy", 'p', 'v');
* assert(s.equals("savvy")); assert(s.equals("savvy"));
* // mt is {Object[] =&gt; List} // mt is {Object[] =&gt; List}
* mt = MethodType.make(java.util.List.class, Object[].class); mt = MethodType.methodType(java.util.List.class, Object[].class);
* mh = lookup.findStatic(java.util.Arrays.class, "asList", mt); mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
* // mt is {(Object,Object,Object) =&gt; Object} // mt is {(Object,Object,Object) =&gt; Object}
* mt = MethodType.makeGeneric(3); mt = MethodType.genericMethodType(3);
* mh = MethodHandles.collectArguments(mh, mt); mh = MethodHandles.collectArguments(mh, mt);
* // mt is {(Object,Object,Object) =&gt; Object} // mt is {(Object,Object,Object) =&gt; Object}
* // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
* x = mh.invoke((Object)1, (Object)2, (Object)3); x = mh.invokeExact((Object)1, (Object)2, (Object)3);
* assert(x.equals(java.util.Arrays.asList(1,2,3))); assert(x.equals(java.util.Arrays.asList(1,2,3)));
* // mt is { =&gt; int} // mt is { =&gt; int}
* mt = MethodType.make(int.class); mt = MethodType.methodType(int.class);
* mh = lookup.findVirtual(java.util.List.class, "size", mt); mh = lookup.findVirtual(java.util.List.class, "size", mt);
* // (Ljava/util/List;)I // (Ljava/util/List;)I
* i = mh.&lt;int&gt;invoke(java.util.Arrays.asList(1,2,3)); i = mh.&lt;int&gt;invokeExact(java.util.Arrays.asList(1,2,3));
* assert(i == 3); assert(i == 3);
* </pre></blockquote> * </pre></blockquote>
* Each of the above calls generates a single invokevirtual instruction * Each of the above calls generates a single invokevirtual instruction
* with the name {@code invoke} and the type descriptors indicated in the comments. * with the name {@code invoke} and the type descriptors indicated in the comments.
...@@ -167,6 +169,14 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility ...@@ -167,6 +169,14 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* those of multiple arities. It is impossible to represent such * those of multiple arities. It is impossible to represent such
* genericity with a Java type parameter.</li> * genericity with a Java type parameter.</li>
* </ol> * </ol>
* Signature polymorphic methods in this class appear to be documented
* as having type parameters for return types and a parameter, but that is
* merely a documentation convention. These type parameters do
* not play a role in type-checking method handle invocations.
* <p>
* Note: Like classes and strings, method handles that correspond directly
* to fields and methods can be represented directly as constants to be
* loaded by {@code ldc} bytecodes.
* *
* @see MethodType * @see MethodType
* @see MethodHandles * @see MethodHandles
...@@ -180,7 +190,15 @@ public abstract class MethodHandle ...@@ -180,7 +190,15 @@ public abstract class MethodHandle
private static Access IMPL_TOKEN = Access.getToken(); private static Access IMPL_TOKEN = Access.getToken();
// interface MethodHandle<R throws X extends Exception,A...> // interface MethodHandle<R throws X extends Exception,A...>
// { MethodType<R throws X,A...> type(); public R invoke(A...) throws X; } // { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }
/**
* Internal marker interface which distinguishes (to the Java compiler)
* those methods which are signature polymorphic.
*/
@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
@interface PolymorphicSignature { }
private MethodType type; private MethodType type;
...@@ -232,85 +250,38 @@ public abstract class MethodHandle ...@@ -232,85 +250,38 @@ public abstract class MethodHandle
return MethodHandleImpl.getNameString(IMPL_TOKEN, this); return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
} }
//// First draft of the "Method Handle Kernel API" discussed at the JVM Language Summit, 9/2009. //// This is 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 //// 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 //// will be deprecated. Others will be kept as "algorithms" to supply degrees of freedom
//// not present in the Kernel API. //// not present in the Kernel API.
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform an exact invocation. The signature at the call site of {@code invokeExact} must * Invoke the method handle, allowing any caller signature, but requiring an exact signature match.
* The signature at the call site of {@code invokeExact} must
* exactly match this method handle's {@code type}. * exactly match this method handle's {@code type}.
* No conversions are allowed on arguments or return values. * 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 { public final native @PolymorphicSignature <R,A> R invokeExact(A... args) throws Throwable;
// This is an approximate implementation, which discards the caller's signature and refuses the call.
throw new InternalError("not yet implemented"); // FIXME: remove this transitional form
} /** @deprecated transitional form defined in EDR but removed in PFD */
public final native @PolymorphicSignature <R,A> R invoke(A... args) throws Throwable;
/** /**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform a generic invocation. The signature at the call site of {@code invokeExact} must * Invoke the method handle, allowing any caller signature,
* and performing simple conversions for arguments and return types.
* The signature at the call site of {@code invokeGeneric} must
* have the same arity as this method handle's {@code type}. * 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 * The same conversions are allowed on arguments or return values as are supported by
* by {@link MethodHandles#convertArguments}. * by {@link MethodHandles#convertArguments}.
* If the call site signature exactly matches this method handle's {@code type}, * If the call site signature exactly matches this method handle's {@code type},
* the call proceeds as if by {@link #invokeExact}. * 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. public final native @PolymorphicSignature <R,A> R invokeGeneric(A... args) throws Throwable;
// When it is made signature polymorphic, the overloadings will disappear.
public final <T> T invokeGeneric() throws Throwable { // ?? public final native @PolymorphicSignature <R,A,V> R invokeVarargs(A args, V[] varargs) 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> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
...@@ -341,47 +312,47 @@ public abstract class MethodHandle ...@@ -341,47 +312,47 @@ public abstract class MethodHandle
* This call is equivalent to the following code: * This call is equivalent to the following code:
* <p><blockquote><pre> * <p><blockquote><pre>
* MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true); * MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
* Object result = invoker.invoke(this, arguments); * Object result = invoker.invokeExact(this, arguments);
* </pre></blockquote> * </pre></blockquote>
* @param arguments the arguments to pass to the target * @param arguments the arguments to pass to the target
* @return the result returned by the target * @return the result returned by the target
* @see MethodHandles#genericInvoker * @see MethodHandles#genericInvoker
*/ */
public final Object invokeVarargs(Object[] arguments) throws Throwable { public final Object invokeVarargs(Object... arguments) throws Throwable {
int argc = arguments == null ? 0 : arguments.length; int argc = arguments == null ? 0 : arguments.length;
MethodType type = type(); MethodType type = type();
if (argc <= 10) { if (argc <= 10) {
MethodHandle invoker = MethodHandles.invokers(type).genericInvoker(); MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
switch (argc) { switch (argc) {
case 0: return invoker.invoke(this); case 0: return invoker.invokeExact(this);
case 1: return invoker.invoke(this, case 1: return invoker.invokeExact(this,
arguments[0]); arguments[0]);
case 2: return invoker.invoke(this, case 2: return invoker.invokeExact(this,
arguments[0], arguments[1]); arguments[0], arguments[1]);
case 3: return invoker.invoke(this, case 3: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2]); arguments[0], arguments[1], arguments[2]);
case 4: return invoker.invoke(this, case 4: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3]); arguments[3]);
case 5: return invoker.invoke(this, case 5: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4]); arguments[3], arguments[4]);
case 6: return invoker.invoke(this, case 6: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5]); arguments[3], arguments[4], arguments[5]);
case 7: return invoker.invoke(this, case 7: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5], arguments[3], arguments[4], arguments[5],
arguments[6]); arguments[6]);
case 8: return invoker.invoke(this, case 8: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5], arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7]); arguments[6], arguments[7]);
case 9: return invoker.invoke(this, case 9: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5], arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8]); arguments[6], arguments[7], arguments[8]);
case 10: return invoker.invoke(this, case 10: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2], arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5], arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8], arguments[6], arguments[7], arguments[8],
...@@ -391,7 +362,7 @@ public abstract class MethodHandle ...@@ -391,7 +362,7 @@ public abstract class MethodHandle
// more than ten arguments get boxed in a varargs list: // more than ten arguments get boxed in a varargs list:
MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0); MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
return invoker.invoke(this, arguments); return invoker.invokeExact(this, arguments);
} }
/** Equivalent to {@code invokeVarargs(arguments.toArray())}. */ /** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable { public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
......
...@@ -36,15 +36,24 @@ import sun.dyn.util.BytecodeDescriptor; ...@@ -36,15 +36,24 @@ import sun.dyn.util.BytecodeDescriptor;
import static sun.dyn.MemberName.newIllegalArgumentException; import static sun.dyn.MemberName.newIllegalArgumentException;
/** /**
* Run-time token used to match call sites with method handles. * A method type represents the arguments and return type accepted and
* returned by a method handle, or the arguments and return type passed
* and expected by a method handle caller. Method types must be properly
* matched between a method handle and all its callers,
* and the JVM's operations enforce this matching at all times.
* <p>
* The structure is a return type accompanied by any number of parameter types. * The structure is a return type accompanied by any number of parameter types.
* The types (primitive, void, and reference) are represented by Class objects. * The types (primitive, void, and reference) are represented by Class objects.
* <p>
* All instances of <code>MethodType</code> are immutable. * All instances of <code>MethodType</code> are immutable.
* Two instances are completely interchangeable if they compare equal. * Two instances are completely interchangeable if they compare equal.
* Equality depends exactly on the return and parameter types. * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
* <p> * <p>
* This type can be created only by factory methods, which manage interning. * This type can be created only by factory methods.
* * All factory methods may cache values, though caching is not guaranteed.
* <p>
* Note: Like classes and strings, method types can be represented directly
* as constants to be loaded by {@code ldc} bytecodes.
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
public final public final
...@@ -109,7 +118,7 @@ class MethodType { ...@@ -109,7 +118,7 @@ class MethodType {
/** Find or create an instance of the given method type. /** Find or create an instance of the given method type.
* @param rtype the return type * @param rtype the return type
* @param ptypes the parameter types * @param ptypes the parameter types
* @return the interned method type with the given parts * @return a method type with the given parts
* @throws NullPointerException if rtype or any ptype is null * @throws NullPointerException if rtype or any ptype is null
* @throws IllegalArgumentException if any of the ptypes is void * @throws IllegalArgumentException if any of the ptypes is void
*/ */
...@@ -626,7 +635,7 @@ class MethodType { ...@@ -626,7 +635,7 @@ class MethodType {
} }
/** Convenience method for {@link #methodType(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. * Find or create an instance of the given method type.
* Any class or interface name embedded in the signature string * Any class or interface name embedded in the signature string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)} * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
* on the given loader (or if it is null, on the system class loader). * on the given loader (or if it is null, on the system class loader).
......
...@@ -27,11 +27,12 @@ package java.dyn; ...@@ -27,11 +27,12 @@ package java.dyn;
/** /**
* Thrown to indicate that a caller has attempted to create a method handle * Thrown to indicate that a caller has attempted to create a method handle
* which calls a method to which the caller does not have access. * which accesses a field, method, or class to which the caller does not have access.
* This unchecked exception is analogous to {@link IllegalAccessException}, * This unchecked exception is analogous to {@link IllegalAccessException},
* which is a checked exception thrown when reflective invocation fails * which is a checked exception thrown when reflective invocation fails
* because of an access check. With method handles, this same access * because of an access check. With method handles, this same access
* checking is performed on behalf of the method handle creator, * checking is performed by the {@link MethodHandles.Lookup lookup object}
* on behalf of the method handle creator,
* at the time of creation. * at the time of creation.
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
......
...@@ -27,6 +27,105 @@ ...@@ -27,6 +27,105 @@
* <em>PROVISIONAL API, WORK IN PROGRESS:</em> * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* This package contains dynamic language support provided directly by * This package contains dynamic language support provided directly by
* the Java core class libraries and virtual machine. * the Java core class libraries and virtual machine.
* <p>
* Certain types in this package have special relations to dynamic
* language support in the virtual machine:
* <ul>
* <li>In source code, a call to
* {@link java.dyn.MethodHandle#invokeExact MethodHandle.invokeExact} or
* {@link java.dyn.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
* will compile and link, regardless of the requested type signature.
* As usual, the Java compiler emits an {@code invokevirtual}
* instruction with the given signature against the named method.
* The JVM links any such call (regardless of signature) to a dynamically
* typed method handle invocation. In the case of {@code invokeGeneric},
* argument and return value conversions are applied.
*
* <li>In source code, the class {@link java.dyn.InvokeDynamic} appears to accept
* any static method invocation, of any name and any signature.
* But instead of emitting
* an {@code invokestatic} instruction for such a call, the Java compiler emits
* an {@code invokedynamic} instruction with the given name and signature.
*
* <li>When the JVM links an {@code invokedynamic} instruction, it calls the
* {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
* of the containing class to obtain a {@linkplain java.dyn.CallSite call site} object through which
* the call site will link its target {@linkplain java.dyn.MethodHandle method handle}.
*
* <li>The JVM bytecode format supports immediate constants of
* the classes {@link java.dyn.MethodHandle} and {@link java.dyn.MethodType}.
* </ul>
*
* <h2><a name="jvm_mods"></a>Corresponding JVM bytecode format changes</h2>
* <em>The following low-level information is presented here as a preview of
* changes being made to the Java Virtual Machine specification for JSR 292.</em>
*
* <h3>{@code invokedynamic} instruction format</h3>
* In bytecode, an {@code invokedynamic} instruction is formatted as five bytes.
* The first byte is the opcode 186 (hexadecimal {@code BA}).
* The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
* The final two bytes are reserved for future use and required to be zero.
* The constant pool reference is to a entry with tag {@code CONSTANT_NameAndType}
* (decimal 12). It is thus not a method reference of any sort, but merely
* the method name, argument types, and return type of the dynamic call site.
* <em>(TBD: The EG is discussing the possibility of a special constant pool entry type,
* so that other information may be added, such as a per-instruction bootstrap
* method and/or annotations.)</em>
*
* <h3>constant pool entries for {@code MethodType}s</h3>
* If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
* it must contain exactly two more bytes, which are an index to a {@code CONSTANT_Utf8}
* entry which represents a method type signature. The JVM will ensure that on first
* execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType}
* will be created which represents the signature.
* Any classes mentioned in the {@code MethodType} will be loaded if necessary,
* but not initialized.
* Access checking and error reporting is performed exactly as it is for
* references by {@code ldc} instructions to {@code CONSTANT_Class} constants.
*
* <h3>constant pool entries for {@code MethodHandle}s</h3>
* If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
* it must contain exactly three more bytes. The first byte after the tag is a subtag
* value in the range 1 through 9, and the last two are an index to a
* {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
* {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
* for which a method handle is to be created.
* The JVM will ensure that on first execution of an {@code ldc} instruction
* for this entry, a {@link java.dyn.MethodHandle} will be created which represents
* the field or method reference, according to the specific mode implied by the subtag.
* <p>
* As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
* the {@code Class} or {@code MethodType} object which reifies the field or method's
* type is created. Any classes mentioned in this reificaiton will be loaded if necessary,
* but not initialized, and access checking and error reporting performed as usual.
* <p>
* The method handle itself will have a type and behavior determined by the subtag as follows:
* <code>
* <table border=1 cellpadding=5 summary="CONSTANT_MethodHandle subtypes">
* <tr><th>N</th><th>subtag name</th><th>member</th><th>MH type</th><th>MH behavior</th></tr>
* <tr><td>1</td><td>REF_getField</td><td>C.f:T</td><td>(C)T</td><td>getfield C.f:T</td></tr>
* <tr><td>2</td><td>REF_getStatic</td><td>C.f:T</td><td>(&nbsp;)T</td><td>getstatic C.f:T</td></tr>
* <tr><td>3</td><td>REF_putField</td><td>C.f:T</td><td>(C,T)void</td><td>putfield C.f:T</td></tr>
* <tr><td>4</td><td>REF_putStatic</td><td>C.f:T</td><td>(T)void</td><td>putstatic C.f:T</td></tr>
* <tr><td>5</td><td>REF_invokeVirtual</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokevirtual C.m(A*)T</td></tr>
* <tr><td>6</td><td>REF_invokeStatic</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokestatic C.m(A*)T</td></tr>
* <tr><td>7</td><td>REF_invokeSpecial</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokespecial C.m(A*)T</td></tr>
* <tr><td>8</td><td>REF_newInvokeSpecial</td><td>C.&lt;init&gt;(A*)void</td><td>(A*)C</td><td>new C; dup; invokespecial C.&lt;init&gt;(A*)void</td></tr>
* <tr><td>9</td><td>REF_invokeInterface</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokeinterface C.m(A*)T</td></tr>
* </table>
* </code>
* <p>
* The special names {@code <init>} and {@code <clinit>} are not allowed except for subtag 8 as shown.
* <p>
* The verifier applies the same access checks and restrictions for these references as for the hypothetical
* bytecode instructions specified in the last column of the table. In particular, method handles to
* private and protected members can be created in exactly those classes for which the corresponding
* normal accesses are legal.
* <p>
* None of these constant types force class initialization.
* Method handles for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
* may force class initialization on their first invocation, just like the corresponding bytecodes.
*
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
......
...@@ -66,7 +66,7 @@ public class AssertionError extends Error { ...@@ -66,7 +66,7 @@ public class AssertionError extends Error {
* defined in <i>The Java Language Specification, Second * defined in <i>The Java Language Specification, Second
* Edition</i>, Section 15.18.1.1. * Edition</i>, Section 15.18.1.1.
*<p> *<p>
* If the specified object is an instance of <tt>Throwable</tt>, it * If the specified object is an instance of {@code Throwable}, it
* becomes the <i>cause</i> of the newly constructed assertion error. * becomes the <i>cause</i> of the newly constructed assertion error.
* *
* @param detailMessage value to be used in constructing detail message * @param detailMessage value to be used in constructing detail message
...@@ -149,4 +149,21 @@ public class AssertionError extends Error { ...@@ -149,4 +149,21 @@ public class AssertionError extends Error {
public AssertionError(double detailMessage) { public AssertionError(double detailMessage) {
this("" + detailMessage); this("" + detailMessage);
} }
/**
* Constructs a new {@code AssertionError} with the specified
* detail message and cause.
*
* <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this error's detail message.
*
* @param message the detail message, may be {@code null}
* @param cause the cause, may be {@code null}
*
* @since 1.7
*/
public AssertionError(String message, Throwable cause) {
super(message, cause);
}
} }
...@@ -681,9 +681,9 @@ public final class Math { ...@@ -681,9 +681,9 @@ public final class Math {
private static Random randomNumberGenerator; private static Random randomNumberGenerator;
private static synchronized void initRNG() { private static synchronized Random initRNG() {
if (randomNumberGenerator == null) Random rnd = randomNumberGenerator;
randomNumberGenerator = new Random(); return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
} }
/** /**
...@@ -694,9 +694,11 @@ public final class Math { ...@@ -694,9 +694,11 @@ public final class Math {
* *
* <p>When this method is first called, it creates a single new * <p>When this method is first called, it creates a single new
* pseudorandom-number generator, exactly as if by the expression * pseudorandom-number generator, exactly as if by the expression
* <blockquote>{@code new java.util.Random}</blockquote> This *
* new pseudorandom-number generator is used thereafter for all * <blockquote>{@code new java.util.Random()}</blockquote>
* calls to this method and is used nowhere else. *
* This new pseudorandom-number generator is used thereafter for
* all calls to this method and is used nowhere else.
* *
* <p>This method is properly synchronized to allow correct use by * <p>This method is properly synchronized to allow correct use by
* more than one thread. However, if many threads need to generate * more than one thread. However, if many threads need to generate
...@@ -705,11 +707,12 @@ public final class Math { ...@@ -705,11 +707,12 @@ public final class Math {
* *
* @return a pseudorandom {@code double} greater than or equal * @return a pseudorandom {@code double} greater than or equal
* to {@code 0.0} and less than {@code 1.0}. * to {@code 0.0} and less than {@code 1.0}.
* @see java.util.Random#nextDouble() * @see Random#nextDouble()
*/ */
public static double random() { public static double random() {
if (randomNumberGenerator == null) initRNG(); Random rnd = randomNumberGenerator;
return randomNumberGenerator.nextDouble(); if (rnd == null) rnd = initRNG();
return rnd.nextDouble();
} }
/** /**
......
...@@ -418,6 +418,8 @@ public final class ProcessBuilder ...@@ -418,6 +418,8 @@ public final class ProcessBuilder
* Implements a <a href="#redirect-output">null input stream</a>. * Implements a <a href="#redirect-output">null input stream</a>.
*/ */
static class NullInputStream extends InputStream { static class NullInputStream extends InputStream {
static final NullInputStream INSTANCE = new NullInputStream();
private NullInputStream() {}
public int read() { return -1; } public int read() { return -1; }
public int available() { return 0; } public int available() { return 0; }
} }
...@@ -426,6 +428,8 @@ public final class ProcessBuilder ...@@ -426,6 +428,8 @@ public final class ProcessBuilder
* Implements a <a href="#redirect-input">null output stream</a>. * Implements a <a href="#redirect-input">null output stream</a>.
*/ */
static class NullOutputStream extends OutputStream { static class NullOutputStream extends OutputStream {
static final NullOutputStream INSTANCE = new NullOutputStream();
private NullOutputStream() {}
public void write(int b) throws IOException { public void write(int b) throws IOException {
throw new IOException("Stream closed"); throw new IOException("Stream closed");
} }
......
...@@ -667,9 +667,9 @@ public final class StrictMath { ...@@ -667,9 +667,9 @@ public final class StrictMath {
private static Random randomNumberGenerator; private static Random randomNumberGenerator;
private static synchronized void initRNG() { private static synchronized Random initRNG() {
if (randomNumberGenerator == null) Random rnd = randomNumberGenerator;
randomNumberGenerator = new Random(); return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
} }
/** /**
...@@ -680,9 +680,11 @@ public final class StrictMath { ...@@ -680,9 +680,11 @@ public final class StrictMath {
* *
* <p>When this method is first called, it creates a single new * <p>When this method is first called, it creates a single new
* pseudorandom-number generator, exactly as if by the expression * pseudorandom-number generator, exactly as if by the expression
* <blockquote>{@code new java.util.Random}</blockquote> This *
* new pseudorandom-number generator is used thereafter for all * <blockquote>{@code new java.util.Random()}</blockquote>
* calls to this method and is used nowhere else. *
* This new pseudorandom-number generator is used thereafter for
* all calls to this method and is used nowhere else.
* *
* <p>This method is properly synchronized to allow correct use by * <p>This method is properly synchronized to allow correct use by
* more than one thread. However, if many threads need to generate * more than one thread. However, if many threads need to generate
...@@ -691,11 +693,12 @@ public final class StrictMath { ...@@ -691,11 +693,12 @@ public final class StrictMath {
* *
* @return a pseudorandom {@code double} greater than or equal * @return a pseudorandom {@code double} greater than or equal
* to {@code 0.0} and less than {@code 1.0}. * to {@code 0.0} and less than {@code 1.0}.
* @see java.util.Random#nextDouble() * @see Random#nextDouble()
*/ */
public static double random() { public static double random() {
if (randomNumberGenerator == null) initRNG(); Random rnd = randomNumberGenerator;
return randomNumberGenerator.nextDouble(); if (rnd == null) rnd = initRNG();
return rnd.nextDouble();
} }
/** /**
......
...@@ -678,7 +678,7 @@ public final class Security { ...@@ -678,7 +678,7 @@ public final class Security {
spiMap.put(type, clazz); spiMap.put(type, clazz);
return clazz; return clazz;
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw (Error)new AssertionError("Spi class not found").initCause(e); throw new AssertionError("Spi class not found", e);
} }
} }
......
...@@ -463,10 +463,10 @@ public class Collections { ...@@ -463,10 +463,10 @@ public class Collections {
* its list-iterator does not support the <tt>set</tt> operation. * its list-iterator does not support the <tt>set</tt> operation.
*/ */
public static void shuffle(List<?> list) { public static void shuffle(List<?> list) {
if (r == null) { Random rnd = r;
r = new Random(); if (rnd == null)
} r = rnd = new Random();
shuffle(list, r); shuffle(list, rnd);
} }
private static Random r; private static Random r;
......
...@@ -73,10 +73,10 @@ public class ThreadLocalRandom extends Random { ...@@ -73,10 +73,10 @@ public class ThreadLocalRandom extends Random {
private long rnd; private long rnd;
/** /**
* Initialization flag to permit the first and only allowed call * Initialization flag to permit calls to setSeed to succeed only
* to setSeed (inside Random constructor) to succeed. We can't * while executing the Random constructor. We can't allow others
* allow others since it would cause setting seed in one part of a * since it would cause setting seed in one part of a program to
* program to unintentionally impact other usages by the thread. * unintentionally impact other usages by the thread.
*/ */
boolean initialized; boolean initialized;
...@@ -98,11 +98,10 @@ public class ThreadLocalRandom extends Random { ...@@ -98,11 +98,10 @@ public class ThreadLocalRandom extends Random {
/** /**
* Constructor called only by localRandom.initialValue. * Constructor called only by localRandom.initialValue.
* We rely on the fact that the superclass no-arg constructor
* invokes setSeed exactly once to initialize.
*/ */
ThreadLocalRandom() { ThreadLocalRandom() {
super(); super();
initialized = true;
} }
/** /**
...@@ -123,7 +122,6 @@ public class ThreadLocalRandom extends Random { ...@@ -123,7 +122,6 @@ public class ThreadLocalRandom extends Random {
public void setSeed(long seed) { public void setSeed(long seed) {
if (initialized) if (initialized)
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
initialized = true;
rnd = (seed ^ multiplier) & mask; rnd = (seed ^ multiplier) & mask;
} }
......
/* /*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003,2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -212,10 +212,18 @@ public abstract class Pack200 { ...@@ -212,10 +212,18 @@ public abstract class Pack200 {
* to produce a specific bytewise image for any given transmission * to produce a specific bytewise image for any given transmission
* ordering of archive elements.) * ordering of archive elements.)
* <p> * <p>
* In order to maintain backward compatibility, if the input JAR-files are * In order to maintain backward compatibility, the pack file's version is
* solely comprised of 1.5 (or lesser) classfiles, a 1.5 compatible * set to accommodate the class files present in the input JAR file. In
* pack file is produced. Otherwise a 1.6 compatible pack200 file is * other words, the pack file version will be the latest, if the class files
* produced. * are the latest and conversely the pack file version will be the oldest
* if the class file versions are also the oldest. For intermediate class
* file versions the corresponding pack file version will be used.
* For example:
* If the input JAR-files are solely comprised of 1.5 (or lesser)
* class files, a 1.5 compatible pack file is produced. This will also be
* the case for archives that have no class files.
* If the input JAR-files contains a 1.6 class file, then the pack file
* version will be set to 1.6.
* <p> * <p>
* @since 1.5 * @since 1.5
*/ */
...@@ -236,9 +244,10 @@ public abstract class Pack200 { ...@@ -236,9 +244,10 @@ public abstract class Pack200 {
* input file to be transmitted in the segment, along with the size * input file to be transmitted in the segment, along with the size
* of its name and other transmitted properties. * of its name and other transmitted properties.
* <p> * <p>
* The default is 1000000 (a million bytes). This allows input JAR files * The default is -1, which means the packer will always create a single
* of moderate size to be transmitted in one segment. It also puts * segment output file. In cases where extremely large output files are
* a limit on memory requirements for packers and unpackers. * generated, users are strongly encouraged to use segmenting or break
* up the input file into smaller JARs.
* <p> * <p>
* A 10Mb JAR packed without this limit will * A 10Mb JAR packed without this limit will
* typically pack about 10% smaller, but the packer may require * typically pack about 10% smaller, but the packer may require
......
...@@ -366,7 +366,7 @@ public class AdapterMethodHandle extends BoundMethodHandle { ...@@ -366,7 +366,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
} }
private static boolean convOpSupported(int convOp) { private static boolean convOpSupported(int convOp) {
assert(convOp >= 0 && convOp <= CONV_OP_LIMIT); assert(convOp >= 0 && convOp <= CONV_OP_LIMIT);
return ((1<<convOp) & CONV_OP_IMPLEMENTED_MASK) != 0; return ((1<<convOp) & MethodHandleNatives.CONV_OP_IMPLEMENTED_MASK) != 0;
} }
/** One of OP_RETYPE_ONLY, etc. */ /** One of OP_RETYPE_ONLY, etc. */
......
...@@ -146,6 +146,8 @@ public class BoundMethodHandle extends MethodHandle { ...@@ -146,6 +146,8 @@ public class BoundMethodHandle extends MethodHandle {
MethodType foundType = null; MethodType foundType = null;
MemberName foundMethod = null; MemberName foundMethod = null;
for (MemberName method : methods) { for (MemberName method : methods) {
if (method.getDeclaringClass() == MethodHandle.class)
continue; // ignore methods inherited from MH class itself
MethodType mtype = method.getMethodType(); MethodType mtype = method.getMethodType();
if (type != null && type.parameterCount() != mtype.parameterCount()) if (type != null && type.parameterCount() != mtype.parameterCount())
continue; continue;
......
...@@ -26,77 +26,65 @@ ...@@ -26,77 +26,65 @@
package sun.dyn; package sun.dyn;
import java.dyn.*; import java.dyn.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Parts of CallSite known to the JVM. * Parts of CallSite known to the JVM.
* FIXME: Merge all this into CallSite proper.
* @author jrose * @author jrose
*/ */
public class CallSiteImpl { public class CallSiteImpl {
// Field used only by the JVM. Do not use or change. // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
private Object vmmethod; static CallSite makeSite(MethodHandle bootstrapMethod,
// Callee information:
// Values supplied by the JVM: String name, MethodType type,
protected int callerMID, callerBCI; // Call-site attributes, if any:
Object info,
private MethodHandle target; // Caller information:
protected final Object caller; // usually a class MemberName callerMethod, int callerBCI) {
protected final String name; Class<?> caller = callerMethod.getDeclaringClass();
protected final MethodType type; if (bootstrapMethod == null) {
// If there is no bootstrap method, throw IncompatibleClassChangeError.
/** called only directly from CallSite() */ // This is a valid generic error type for resolution (JLS 12.3.3).
protected CallSiteImpl(Access token, Object caller, String name, MethodType type) { throw new IncompatibleClassChangeError
Access.check(token); ("Class "+caller.getName()+" has not declared a bootstrap method for invokedynamic");
this.caller = caller;
this.name = name;
this.type = type;
}
/** 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.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,
int callerMID, int callerBCI) {
MethodHandle bsm = Linkage.getBootstrapMethod(caller);
if (bsm == null)
throw new InvokeDynamicBootstrapError("class has no bootstrap method: "+caller);
CallSite site;
try {
site = bsm.<CallSite>invoke(caller, name, type);
} catch (Throwable ex) {
throw new InvokeDynamicBootstrapError("exception thrown while linking", ex);
} }
if (site == null) CallSite site;
throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
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 { try {
PRIVATE_INITIALIZE_CALL_SITE.<void>invoke(site, callerMID, callerBCI); if (bootstrapMethod.type().parameterCount() == 3)
site = bootstrapMethod.<CallSite>invokeExact(caller, name, type);
else if (bootstrapMethod.type().parameterCount() == 4)
site = bootstrapMethod.<CallSite>invokeExact(caller, name, type,
!(info instanceof java.lang.annotation.Annotation[]) ? null
: (java.lang.annotation.Annotation[]) info);
else
throw new InternalError("bad BSM: "+bootstrapMethod);
if (!(site instanceof CallSite))
throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
PRIVATE_INITIALIZE_CALL_SITE.<void>invokeExact(site,
name, type,
callerMethod, callerBCI);
assert(site.getTarget() != null);
assert(site.getTarget().type().equals(type));
} catch (Throwable ex) { } catch (Throwable ex) {
throw new InvokeDynamicBootstrapError("call site initialization exception", ex); InvokeDynamicBootstrapError bex;
if (ex instanceof InvokeDynamicBootstrapError)
bex = (InvokeDynamicBootstrapError) ex;
else
bex = new InvokeDynamicBootstrapError("call site initialization exception", ex);
throw bex;
} }
return site; return site;
} }
// This method is private in CallSite because it touches private fields in CallSite.
// These private fields (vmmethod, vmindex) are specific to the JVM.
private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM",
MethodType.methodType(void.class,
String.class, MethodType.class,
MemberName.class, int.class));
public static void setCallSiteTarget(Access token, CallSite site, MethodHandle target) {
Access.check(token);
MethodHandleNatives.setCallSiteTarget(site, target);
}
} }
...@@ -47,8 +47,8 @@ public class FilterOneArgument extends JavaMethodHandle { ...@@ -47,8 +47,8 @@ public class FilterOneArgument extends JavaMethodHandle {
} }
protected Object invoke(Object argument) throws Throwable { protected Object invoke(Object argument) throws Throwable {
Object filteredArgument = filter.invoke(argument); Object filteredArgument = filter.invokeExact(argument);
return target.invoke(filteredArgument); return target.invokeExact(filteredArgument);
} }
private static final MethodHandle INVOKE = private static final MethodHandle INVOKE =
......
/* /*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,12 +28,16 @@ package sun.dyn; ...@@ -28,12 +28,16 @@ package sun.dyn;
import java.dyn.CallSite; import java.dyn.CallSite;
import java.dyn.MethodHandle; import java.dyn.MethodHandle;
import java.dyn.MethodType; import java.dyn.MethodType;
import java.dyn.MethodHandles.Lookup;
import java.lang.reflect.AccessibleObject; import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import static sun.dyn.MethodHandleNatives.Constants.*; import static sun.dyn.MethodHandleNatives.Constants.*;
import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP;
/** /**
* The JVM interface for the method handles package is all here. * The JVM interface for the method handles package is all here.
* This is an interface internal and private to an implemetantion of JSR 292.
* <em>This class is not part of the JSR 292 standard.</em>
* @author jrose * @author jrose
*/ */
class MethodHandleNatives { class MethodHandleNatives {
...@@ -60,8 +64,14 @@ class MethodHandleNatives { ...@@ -60,8 +64,14 @@ class MethodHandleNatives {
/** Initialize a method type, once per form. */ /** Initialize a method type, once per form. */
static native void init(MethodType self); static native void init(MethodType self);
/** Tell the JVM about a class's bootstrap method. */
static native void registerBootstrap(Class<?> caller, MethodHandle bootstrapMethod);
/** Ask the JVM about a class's bootstrap method. */
static native MethodHandle getBootstrap(Class<?> caller);
/** Tell the JVM that we need to change the target of an invokedynamic. */ /** Tell the JVM that we need to change the target of an invokedynamic. */
static native void linkCallSite(CallSite site, MethodHandle target); static native void setCallSiteTarget(CallSite site, MethodHandle target);
/** Fetch the vmtarget field. /** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references. * It will be sanitized as necessary to avoid exposing non-Java references.
...@@ -114,22 +124,28 @@ class MethodHandleNatives { ...@@ -114,22 +124,28 @@ class MethodHandleNatives {
*/ */
static final int JVM_STACK_MOVE_UNIT; static final int JVM_STACK_MOVE_UNIT;
/** Which conv-ops are implemented by the JVM? */
static final int CONV_OP_IMPLEMENTED_MASK;
private static native void registerNatives(); private static native void registerNatives();
static { static {
boolean JVM_SUPPORT_; boolean JVM_SUPPORT_;
int JVM_PUSH_LIMIT_; int JVM_PUSH_LIMIT_;
int JVM_STACK_MOVE_UNIT_; int JVM_STACK_MOVE_UNIT_;
int CONV_OP_IMPLEMENTED_MASK_;
try { try {
registerNatives(); registerNatives();
JVM_SUPPORT_ = true; JVM_SUPPORT_ = true;
JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT); JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT); JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
CONV_OP_IMPLEMENTED_MASK_ = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK);
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init"); //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
} catch (UnsatisfiedLinkError ee) { } catch (UnsatisfiedLinkError ee) {
// ignore; if we use init() methods later we'll see linkage errors // ignore; if we use init() methods later we'll see linkage errors
JVM_SUPPORT_ = false; JVM_SUPPORT_ = false;
JVM_PUSH_LIMIT_ = 3; // arbitrary JVM_PUSH_LIMIT_ = 3; // arbitrary
JVM_STACK_MOVE_UNIT_ = -1; // arbitrary JVM_STACK_MOVE_UNIT_ = -1; // arbitrary
CONV_OP_IMPLEMENTED_MASK_ = 0;
//System.out.println("Warning: Running with JVM_SUPPORT=false"); //System.out.println("Warning: Running with JVM_SUPPORT=false");
//System.out.println(ee); //System.out.println(ee);
JVM_SUPPORT = JVM_SUPPORT_; JVM_SUPPORT = JVM_SUPPORT_;
...@@ -140,6 +156,9 @@ class MethodHandleNatives { ...@@ -140,6 +156,9 @@ class MethodHandleNatives {
JVM_SUPPORT = JVM_SUPPORT_; JVM_SUPPORT = JVM_SUPPORT_;
JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_;
JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_;
if (CONV_OP_IMPLEMENTED_MASK_ == 0)
CONV_OP_IMPLEMENTED_MASK_ = DEFAULT_CONV_OP_IMPLEMENTED_MASK;
CONV_OP_IMPLEMENTED_MASK = CONV_OP_IMPLEMENTED_MASK_;
} }
// All compile-time constants go here. // All compile-time constants go here.
...@@ -149,7 +168,8 @@ class MethodHandleNatives { ...@@ -149,7 +168,8 @@ class MethodHandleNatives {
// MethodHandleImpl // MethodHandleImpl
static final int // for getConstant static final int // for getConstant
GC_JVM_PUSH_LIMIT = 0, GC_JVM_PUSH_LIMIT = 0,
GC_JVM_STACK_MOVE_UNIT = 1; GC_JVM_STACK_MOVE_UNIT = 1,
GC_CONV_OP_IMPLEMENTED_MASK = 2;
static final int static final int
ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) 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) ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
...@@ -206,9 +226,8 @@ class MethodHandleNatives { ...@@ -206,9 +226,8 @@ class MethodHandleNatives {
CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1; CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1;
/** Which conv-ops are implemented by the JVM? */ /** Which conv-ops are implemented by the JVM? */
static final int CONV_OP_IMPLEMENTED_MASK = static final int DEFAULT_CONV_OP_IMPLEMENTED_MASK =
// TODO: The following expression should be replaced by // Value to use if the corresponding JVM query fails.
// a JVM query.
((1<<OP_RETYPE_ONLY) ((1<<OP_RETYPE_ONLY)
|(1<<OP_RETYPE_RAW) |(1<<OP_RETYPE_RAW)
|(1<<OP_CHECK_CAST) |(1<<OP_CHECK_CAST)
...@@ -218,7 +237,7 @@ class MethodHandleNatives { ...@@ -218,7 +237,7 @@ class MethodHandleNatives {
|(1<<OP_ROT_ARGS) |(1<<OP_ROT_ARGS)
|(1<<OP_DUP_ARGS) |(1<<OP_DUP_ARGS)
|(1<<OP_DROP_ARGS) |(1<<OP_DROP_ARGS)
//|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code. //|(1<<OP_SPREAD_ARGS)
); );
/** /**
...@@ -239,6 +258,20 @@ class MethodHandleNatives { ...@@ -239,6 +258,20 @@ class MethodHandleNatives {
//T_ARRAY = 13 //T_ARRAY = 13
T_VOID = 14; T_VOID = 14;
//T_ADDRESS = 15 //T_ADDRESS = 15
/**
* Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
*/
static final int
REF_getField = 1,
REF_getStatic = 2,
REF_putField = 3,
REF_putStatic = 4,
REF_invokeVirtual = 5,
REF_invokeStatic = 6,
REF_invokeSpecial = 7,
REF_newInvokeSpecial = 8,
REF_invokeInterface = 9;
} }
private static native int getNamedCon(int which, Object[] name); private static native int getNamedCon(int which, Object[] name);
...@@ -263,4 +296,46 @@ class MethodHandleNatives { ...@@ -263,4 +296,46 @@ class MethodHandleNatives {
static { static {
if (JVM_SUPPORT) verifyConstants(); if (JVM_SUPPORT) verifyConstants();
} }
// Up-calls from the JVM.
// These must NOT be public.
/**
* The JVM is linking an invokedynamic instruction. Create a reified call site for it.
*/
static CallSite makeDynamicCallSite(MethodHandle bootstrapMethod,
String name, MethodType type,
Object info,
MemberName callerMethod, int callerBCI) {
return CallSiteImpl.makeSite(bootstrapMethod, name, type, info, callerMethod, callerBCI);
}
/**
* The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
*/
static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
MethodType.genericMethodType(0); // trigger initialization
return MethodTypeImpl.makeImpl(Access.TOKEN, rtype, ptypes, true);
}
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
* It will make an up-call to this method. (Do not change the name or signature.)
*/
static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
Class<?> defc, String name, Object type) {
Lookup lookup = IMPL_LOOKUP.in(callerClass);
switch (refKind) {
case REF_getField: return lookup.findGetter( defc, name, (Class<?>) type );
case REF_getStatic: return lookup.findStaticGetter( defc, name, (Class<?>) type );
case REF_putField: return lookup.findSetter( defc, name, (Class<?>) type );
case REF_putStatic: return lookup.findStaticSetter( defc, name, (Class<?>) type );
case REF_invokeVirtual: return lookup.findVirtual( defc, name, (MethodType) type );
case REF_invokeStatic: return lookup.findStatic( defc, name, (MethodType) type );
case REF_invokeSpecial: return lookup.findSpecial( defc, name, (MethodType) type, callerClass );
case REF_newInvokeSpecial: return lookup.findConstructor( defc, (MethodType) type );
case REF_invokeInterface: return lookup.findVirtual( defc, name, (MethodType) type );
}
throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
}
} }
...@@ -88,6 +88,11 @@ public class MethodTypeImpl { ...@@ -88,6 +88,11 @@ public class MethodTypeImpl {
} }
static private MethodTypeFriend METHOD_TYPE_FRIEND; static private MethodTypeFriend METHOD_TYPE_FRIEND;
static MethodType makeImpl(Access token, Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
Access.check(token);
return METHOD_TYPE_FRIEND.makeImpl(rtype, ptypes, trusted);
}
protected MethodTypeImpl(MethodType erasedType) { protected MethodTypeImpl(MethodType erasedType) {
this.erasedType = erasedType; this.erasedType = erasedType;
...@@ -233,8 +238,10 @@ public class MethodTypeImpl { ...@@ -233,8 +238,10 @@ public class MethodTypeImpl {
return primsAtEnd = t; return primsAtEnd = t;
// known to have a mix of 2 or 3 of ref, int, long // known to have a mix of 2 or 3 of ref, int, long
return primsAtEnd = reorderParameters(t, primsAtEndOrder(t), null); int[] reorder = primsAtEndOrder(t);
ct = reorderParameters(t, reorder, null);
//System.out.println("t="+t+" / reorder="+java.util.Arrays.toString(reorder)+" => "+ct);
return primsAtEnd = ct;
} }
/** Compute a new ordering of parameters so that all references /** Compute a new ordering of parameters so that all references
...@@ -273,7 +280,8 @@ public class MethodTypeImpl { ...@@ -273,7 +280,8 @@ public class MethodTypeImpl {
else if (!hasTwoArgSlots(pt)) ord = ifill++; else if (!hasTwoArgSlots(pt)) ord = ifill++;
else ord = lfill++; else ord = lfill++;
if (ord != i) changed = true; if (ord != i) changed = true;
paramOrder[i] = ord; assert(paramOrder[ord] == 0);
paramOrder[ord] = i;
} }
assert(rfill == argc - pac && ifill == argc - lac && lfill == argc); assert(rfill == argc - pac && ifill == argc - lac && lfill == argc);
if (!changed) { if (!changed) {
...@@ -292,15 +300,15 @@ public class MethodTypeImpl { ...@@ -292,15 +300,15 @@ public class MethodTypeImpl {
if (newParamOrder == null) return mt; // no-op reordering if (newParamOrder == null) return mt; // no-op reordering
Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(mt); Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(mt);
Class<?>[] ntypes = new Class<?>[newParamOrder.length]; Class<?>[] ntypes = new Class<?>[newParamOrder.length];
int ordMax = ptypes.length + (moreParams == null ? 0 : moreParams.length); int maxParam = ptypes.length + (moreParams == null ? 0 : moreParams.length);
boolean changed = (ntypes.length != ptypes.length); boolean changed = (ntypes.length != ptypes.length);
for (int i = 0; i < newParamOrder.length; i++) { for (int i = 0; i < newParamOrder.length; i++) {
int ord = newParamOrder[i]; int param = newParamOrder[i];
if (ord != i) changed = true; if (param != i) changed = true;
Class<?> nt; Class<?> nt;
if (ord < ptypes.length) nt = ptypes[ord]; if (param < ptypes.length) nt = ptypes[param];
else if (ord == ordMax) nt = mt.returnType(); else if (param == maxParam) nt = mt.returnType();
else nt = moreParams[ord - ptypes.length]; else nt = moreParams[param - ptypes.length];
ntypes[i] = nt; ntypes[i] = nt;
} }
if (!changed) return mt; if (!changed) return mt;
......
...@@ -99,12 +99,12 @@ class ToGeneric { ...@@ -99,12 +99,12 @@ class ToGeneric {
// reordering is required; build on top of a simpler ToGeneric // reordering is required; build on top of a simpler ToGeneric
ToGeneric va2 = ToGeneric.of(primsAtEnd); ToGeneric va2 = ToGeneric.of(primsAtEnd);
this.adapter = va2.adapter; this.adapter = va2.adapter;
if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType);
this.entryPoint = MethodHandleImpl.convertArguments(Access.TOKEN, this.entryPoint = MethodHandleImpl.convertArguments(Access.TOKEN,
va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder); va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder);
// example: for entryType of (int,Object,Object), the reordered // example: for entryType of (int,Object,Object), the reordered
// type is (Object,Object,int) and the order is {1,2,0}, // type is (Object,Object,int) and the order is {1,2,0},
// and putPAE is (mh,int0,obj1,obj2) => mh.invoke(obj1,obj2,int0) // and putPAE is (mh,int0,obj1,obj2) => mh.invokeExact(obj1,obj2,int0)
if (true) throw new UnsupportedOperationException("NYI");
return; return;
} }
...@@ -341,7 +341,7 @@ class ToGeneric { ...@@ -341,7 +341,7 @@ class ToGeneric {
@Override @Override
public String toString() { public String toString() {
return target.toString(); return target == null ? "prototype:"+convert : target.toString();
} }
protected boolean isPrototype() { return target == null; } protected boolean isPrototype() { return target == null; }
...@@ -371,33 +371,33 @@ class ToGeneric { ...@@ -371,33 +371,33 @@ class ToGeneric {
// { return new ThisType(entryPoint, convert, target); } // { return new ThisType(entryPoint, convert, target); }
// Code to run when the arguments (<= 4) have all been boxed. // Code to run when the arguments (<= 4) have all been boxed.
protected Object target() throws Throwable { return invoker.<Object>invoke(target); } protected Object target() throws Throwable { return invoker.<Object>invokeExact(target); }
protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); } protected Object target(Object a0) throws Throwable { return invoker.<Object>invokeExact(target, a0); }
protected Object target(Object a0, Object a1) protected Object target(Object a0, Object a1)
throws Throwable { return invoker.<Object>invoke(target, a0, a1); } throws Throwable { return invoker.<Object>invokeExact(target, a0, a1); }
protected Object target(Object a0, Object a1, Object a2) protected Object target(Object a0, Object a1, Object a2)
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2); } throws Throwable { return invoker.<Object>invokeExact(target, a0, a1, a2); }
protected Object target(Object a0, Object a1, Object a2, Object a3) protected Object target(Object a0, Object a1, Object a2, Object a3)
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3); } throws Throwable { return invoker.<Object>invokeExact(target, a0, a1, a2, a3); }
/* /*
protected Object target_0(Object... av) throws Throwable { return invoker.<Object>invoke(target, av); } protected Object target_0(Object... av) throws Throwable { return invoker.<Object>invokeExact(target, av); }
protected Object target_1(Object a0, Object... av) protected Object target_1(Object a0, Object... av)
throws Throwable { return invoker.<Object>invoke(target, a0, (Object)av); } throws Throwable { return invoker.<Object>invokeExact(target, a0, (Object)av); }
protected Object target_2(Object a0, Object a1, Object... av) protected Object target_2(Object a0, Object a1, Object... av)
throws Throwable { return invoker.<Object>invoke(target, a0, a1, (Object)av); } throws Throwable { return invoker.<Object>invokeExact(target, a0, a1, (Object)av); }
protected Object target_3(Object a0, Object a1, Object a2, Object... av) protected Object target_3(Object a0, Object a1, Object a2, Object... av)
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); } throws Throwable { return invoker.<Object>invokeExact(target, a0, a1, a2, (Object)av); }
protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av) protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, (Object)av); } throws Throwable { return invoker.<Object>invokeExact(target, a0, a1, a2, a3, (Object)av); }
// */ // */
// (For more than 4 arguments, generate the code in the adapter itself.) // (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. // Code to run when the generic target has finished and produced a value.
protected Object return_L(Object res) throws Throwable { return convert.<Object>invoke(res); } protected Object return_L(Object res) throws Throwable { return convert.<Object>invokeExact(res); }
protected int return_I(Object res) throws Throwable { return convert.<int >invoke(res); } protected int return_I(Object res) throws Throwable { return convert.<int >invokeExact(res); }
protected long return_J(Object res) throws Throwable { return convert.<long >invoke(res); } protected long return_J(Object res) throws Throwable { return convert.<long >invokeExact(res); }
protected float return_F(Object res) throws Throwable { return convert.<float >invoke(res); } protected float return_F(Object res) throws Throwable { return convert.<float >invokeExact(res); }
protected double return_D(Object res) throws Throwable { return convert.<double>invoke(res); } protected double return_D(Object res) throws Throwable { return convert.<double>invokeExact(res); }
static private final String CLASS_PREFIX; // "sun.dyn.ToGeneric$" static private final String CLASS_PREFIX; // "sun.dyn.ToGeneric$"
static { static {
...@@ -424,7 +424,7 @@ class ToGeneric { ...@@ -424,7 +424,7 @@ class ToGeneric {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); } protected Object target(Object a0) throws Throwable { return invoker.<Object>invokeExact(target, a0); }
protected Object targetA1(Object a0) throws Throwable { return 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(int a0) throws Throwable { return target(a0); }
protected Object targetA1(long a0) throws Throwable { return target(a0); } protected Object targetA1(long a0) throws Throwable { return target(a0); }
...@@ -462,7 +462,7 @@ class genclasses { ...@@ -462,7 +462,7 @@ class genclasses {
" protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype", " 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@(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 @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
" protected Object target(@Ovav@) throws Throwable { return invoker.<Object>invoke(target, @av@); }", " protected Object target(@Ovav@) throws Throwable { return invoker.<Object>invokeExact(target, @av@); }",
" //@each-Tv@", " //@each-Tv@",
" protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }", " protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }",
" //@end-Tv@", " //@end-Tv@",
...@@ -622,7 +622,7 @@ class genclasses { ...@@ -622,7 +622,7 @@ class genclasses {
protected A0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A0(e, i, c, t); }
protected Object target() throws Throwable { return invoker.<Object>invoke(target); } protected Object target() throws Throwable { return invoker.<Object>invokeExact(target); }
protected Object targetA0() throws Throwable { return target(); } protected Object targetA0() throws Throwable { return target(); }
protected Object invoke_L() throws Throwable { return return_L(targetA0()); } protected Object invoke_L() throws Throwable { return return_L(targetA0()); }
protected int invoke_I() throws Throwable { return return_I(targetA0()); } protected int invoke_I() throws Throwable { return return_I(targetA0()); }
...@@ -634,7 +634,7 @@ class genclasses { ...@@ -634,7 +634,7 @@ class genclasses {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); } protected Object target(Object a0) throws Throwable { return invoker.<Object>invokeExact(target, a0); }
protected Object targetA1(Object a0) throws Throwable { return 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(int a0) throws Throwable { return target(a0); }
protected Object targetA1(long a0) throws Throwable { return target(a0); } protected Object targetA1(long a0) throws Throwable { return target(a0); }
...@@ -658,7 +658,7 @@ class genclasses { ...@@ -658,7 +658,7 @@ class genclasses {
protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A2(e, i, c, t); }
protected Object target(Object a0, Object a1) throws Throwable { return invoker.<Object>invoke(target, a0, a1); } protected Object target(Object a0, Object a1) throws Throwable { return invoker.<Object>invokeExact(target, a0, a1); }
protected Object targetA2(Object a0, Object a1) throws Throwable { return 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(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(int a0, int a1) throws Throwable { return target(a0, a1); }
...@@ -694,7 +694,7 @@ class genclasses { ...@@ -694,7 +694,7 @@ class genclasses {
protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2); } protected Object target(Object a0, Object a1, Object a2) throws Throwable { return invoker.<Object>invokeExact(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, 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, 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(Object a0, int a1, int a2) throws Throwable { return target(a0, a1, a2); }
...@@ -743,7 +743,7 @@ class genclasses { ...@@ -743,7 +743,7 @@ class genclasses {
protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3); } protected Object target(Object a0, Object a1, Object a2, Object a3) throws Throwable { return invoker.<Object>invokeExact(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, 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, 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, Object a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
...@@ -785,7 +785,7 @@ class genclasses { ...@@ -785,7 +785,7 @@ class genclasses {
protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4); } protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return invoker.<Object>invokeExact(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, 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, 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, Object a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
...@@ -836,7 +836,7 @@ class genclasses { ...@@ -836,7 +836,7 @@ class genclasses {
protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, 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>invokeExact(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, 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, 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, Object a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
...@@ -870,7 +870,7 @@ class genclasses { ...@@ -870,7 +870,7 @@ class genclasses {
protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, 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>invokeExact(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, 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, 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, Object a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
...@@ -908,7 +908,7 @@ class genclasses { ...@@ -908,7 +908,7 @@ class genclasses {
protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, 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>invokeExact(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, 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, 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, Object a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
...@@ -950,7 +950,7 @@ class genclasses { ...@@ -950,7 +950,7 @@ class genclasses {
protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, 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>invokeExact(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, 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, 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, Object a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
...@@ -996,7 +996,7 @@ class genclasses { ...@@ -996,7 +996,7 @@ class genclasses {
protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype 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(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 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) throws Throwable { return invoker.<Object>invoke(target, 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>invokeExact(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, 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, 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, Object a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
......
...@@ -25,10 +25,6 @@ ...@@ -25,10 +25,6 @@
/** /**
* Implementation details for JSR 292 RI, package java.dyn. * Implementation details for JSR 292 RI, package java.dyn.
* This particular version is specific to Hotspot.
* There is also a backport version of this sub-package which uses reflection,
* and can therefore run (slowly) on older versions of Java.
* Other JVM vendors may create their own versions of this sub-package.
* @author jrose * @author jrose
*/ */
......
...@@ -655,7 +655,7 @@ public class ValueConversions { ...@@ -655,7 +655,7 @@ public class ValueConversions {
if (nargs < ARRAYS.length) if (nargs < ARRAYS.length)
return ARRAYS[nargs]; return ARRAYS[nargs];
// else need to spin bytecode or do something else fancy // else need to spin bytecode or do something else fancy
throw new UnsupportedOperationException("NYI"); throw new UnsupportedOperationException("NYI: cannot form a varargs array of length "+nargs);
} }
private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY); private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
......
...@@ -124,15 +124,15 @@ public abstract class ByteToCharISO2022 extends ByteToCharConverter ...@@ -124,15 +124,15 @@ public abstract class ByteToCharISO2022 extends ByteToCharConverter
switch(shiftFlag) { switch(shiftFlag) {
case SOFlag: case SOFlag:
tmpIndex = curSODes; tmpIndex = curSODes;
tmpConverter = (ByteToCharConverter [])SOConverter; tmpConverter = SOConverter;
break; break;
case SS2Flag: case SS2Flag:
tmpIndex = curSS2Des; tmpIndex = curSS2Des;
tmpConverter = (ByteToCharConverter [])SS2Converter; tmpConverter = SS2Converter;
break; break;
case SS3Flag: case SS3Flag:
tmpIndex = curSS3Des; tmpIndex = curSS3Des;
tmpConverter = (ByteToCharConverter [])SS3Converter; tmpConverter = SS3Converter;
break; break;
} }
......
...@@ -141,7 +141,7 @@ public class ByteToCharISO2022JP extends ByteToCharJIS0208 { ...@@ -141,7 +141,7 @@ public class ByteToCharISO2022JP extends ByteToCharJIS0208 {
} else { } else {
savedSize = 2; savedSize = 2;
savedBytes[0] = (byte)byte1; savedBytes[0] = (byte)byte1;
savedBytes[1] = (byte)input[readOff + inputSize]; savedBytes[1] = input[readOff + inputSize];
inputSize++; inputSize++;
} }
break; break;
......
...@@ -66,7 +66,7 @@ public class CharToBytePCK extends CharToByteSJIS { ...@@ -66,7 +66,7 @@ public class CharToBytePCK extends CharToByteSJIS {
switch (ch) { switch (ch) {
case '\u2015': case '\u2015':
return (int)0x815C; return 0x815C;
case '\u2014': case '\u2014':
return 0; return 0;
default: default:
......
# Jules Rendering Engine module
sun.java2d.jules.JulesRenderingEngine
# Pisces Rendering Engine module # Pisces Rendering Engine module
sun.java2d.pisces.PiscesRenderingEngine sun.java2d.pisces.PiscesRenderingEngine
\ No newline at end of file
# Jules Rendering Engine module
sun.java2d.jules.JulesRenderingEngine
# Pisces Rendering Engine module
sun.java2d.pisces.PiscesRenderingEngine
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册