提交 39bad903 编写于 作者: L lana

Merge

......@@ -71,3 +71,6 @@ f2dce7210cc00453c23e53edeec7156f112ca382 jdk7-b92
cf44386c8fe3fbdb9da14346be25d19fd1092f71 jdk7-b94
db951e984ccf50756160fee3078c791300b0917e jdk7-b95
51b9e5dbc2da0631414484b934ac3fb62e48a2c6 jdk7-b96
b1903d7528d33b521df42bc9291bdcdd2f444a29 jdk7-b97
82593186fa54ab12f17af31f86a7bf364efaf4df jdk7-b98
2587c9f0b60dc3146b4247b8674ada456a643d6f jdk7-b99
......@@ -320,6 +320,7 @@ override LIBCXX = -lstdc++
endif
override LIBPOSIX4 =
override LIBSOCKET =
override LIBNSL =
override LIBTHREAD =
override MOOT_PRIORITIES = true
override NO_INTERRUPTIBLE_IO = true
......
......@@ -645,6 +645,9 @@ LIBM = /usr/lib$(ISA_DIR)/libm.so.2
# Socket library
LIBSOCKET = -lsocket
# Network Services library
LIBNSL = -lnsl
# GLOBAL_KPIC: If set means all libraries are PIC, position independent code
# EXCEPT for select compiles
# 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 \
# This is a stopgap until 6839872 is fixed.
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
# SOLARIS64 for use in this Makefile to easily test those cases
ifeq ($(PLATFORM), solaris)
......@@ -982,7 +989,7 @@ initial-image-jdk:: initial-image-jdk-setup \
-processor com.sun.tools.javac.sym.CreateSymbols \
-Acom.sun.tools.javac.sym.Jar=$(RT_JAR) \
-Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \
$(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS)
$(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) $(EXPORTED_PRIVATE_PKGS)
$(BOOT_JAR_CMD) c0f $(LIBDIR)/ct.sym \
-C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup)
......
......@@ -35,9 +35,6 @@ ifndef JDK_MAKE_SHARED_DIR
JDK_MAKE_SHARED_DIR = $(JDK_TOPDIR)/make/common/shared
endif
ifndef CONTROL_TOPDIR
CONTROL_TOPDIR=$(TOPDIR)
endif
ifndef HOTSPOT_TOPDIR
HOTSPOT_TOPDIR=$(TOPDIR)/hotspot
endif
......
......@@ -331,23 +331,50 @@ ifeq ($(_ms_sdk),)
endif
endif
# Compilers for 64bit may be from SDK. For VS 2010 we use those.
# The Express compilers don't contain 64 bit compilers, so in
# that case, you additionally need the SDK. At this time,
# there's no 64 bit SDK available that has VS 2010.
# Presumably SDK v7.1 will provide that and we may want to update
# the logic here to work with that.
# However official builds will use the Professional version.
# Compilers for 64bit may be from the free SDK, or Visual Studio Professional
# The free Express compilers don't contain 64 bit compilers, which is why
# you instead need the SDK.
# So for VS2010 based builds, either VS2010 Pro with the 7.0a SDK, or
# the Windows 7.1 standalone SDK with compilers may be used.
# Release enginering will use VS2010 Pro, so the frequency of testing of
# SDK based builds will depend entirely on individual usage.
ifeq ($(ARCH_DATA_MODEL), 64)
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))"
_vs100tools :=$(call FullPath,$(xVS100COMNTOOLS))
endif
ifneq ($(_vs100tools),)
_compiler_bin :=$(_vs100tools)/../../Vc/bin/amd64
_redist_sdk :=$(_vs100tools)/../../Vc/redist/x64/Microsoft.VC100.CRT
xMSSDK70 :="$(_program_files32)/Microsoft SDKs/Windows/v7.0a/"
MSSDK70 :=$(call FullPath,$(xMSSDK70))
x_redist_sdk :=$(_vs100tools)/../../Vc/redist/x64/Microsoft.VC100.CRT
_redist_sdk :=$(call FullPath,$(x_redist_sdk))
# 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
xVS2008 :="$(_program_files32)/Microsoft Visual Studio 9.0/"
VS2008 :=$(call FullPath,$(xVS2008))
......@@ -355,7 +382,7 @@ ifeq ($(ARCH_DATA_MODEL), 64)
_compiler_bin :=$(VS2008)/VC/Bin/$(ARCH)
xMSSDK61 :="$(_program_files)/Microsoft SDKs/Windows/v6.1/"
MSSDK61 :=$(call FullPath,$(xMSSDK61))
_redist_sdk :=$(VS2008)/VC/redist/x86/Microsoft.VC90.CRT
_redist_sdk :=$(VS2008)/VC/redist/x64/Microsoft.VC90.CRT
else
ifneq ($(_ms_sdk),)
ifeq ($(ARCH), ia64)
......
......@@ -234,6 +234,7 @@ CORE_PKGS = \
javax.xml.ws.http \
javax.xml.ws.soap \
javax.xml.ws.spi \
javax.xml.ws.spi.http \
javax.xml.ws.wsaddressing \
javax.xml.transform \
javax.xml.transform.sax \
......
......@@ -86,5 +86,5 @@ endif
# Things that must be linked in.
#
ifneq ($(PLATFORM), windows)
OTHER_LDLIBS += $(LIBSOCKET) -lnsl $(LIBM) -ldl
OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) $(LIBM) -ldl
endif
......@@ -204,7 +204,7 @@ ifeq ($(PLATFORM),windows)
OTHER_LDLIBS += $(JVMLIB) -libpath:$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) fdlibm.lib \
-libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib
else
OTHER_LDLIBS += $(JVMLIB) -lverify $(LIBSOCKET) -lnsl -ldl \
OTHER_LDLIBS += $(JVMLIB) -lverify $(LIBSOCKET) $(LIBNSL) -ldl \
-L$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) -lfdlibm.$(ARCH)
endif
......
......@@ -84,7 +84,7 @@ OTHER_INCLUDES = -I$(SRCDIR) \
ifeq ($(PLATFORM), windows)
OTHER_LDLIBS += wsock32.lib winmm.lib
else
OTHER_LDLIBS += $(LIBSOCKET) -lnsl -ldl
OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) -ldl
endif
#
......
......@@ -96,7 +96,7 @@ include $(BUILDDIR)/common/Library.gmk
ifeq ($(PLATFORM), windows)
OTHER_LDLIBS = ws2_32.lib $(JVMLIB)
else
OTHER_LDLIBS = $(LIBSOCKET) -lnsl -ldl $(JVMLIB)
OTHER_LDLIBS = $(LIBSOCKET) $(LIBNSL) -ldl $(JVMLIB)
endif
ifeq ($(PLATFORM), linux)
OTHER_LDLIBS += -lpthread
......
......@@ -38,11 +38,11 @@ FILES_m = mapfile-vers
include $(BUILDDIR)/common/Defs.gmk
ifeq ($(PLATFORM), linux)
OTHER_LDLIBS += -lnsl $(LIBSOCKET) -lpthread
OTHER_LDLIBS += $(LIBNSL) $(LIBSOCKET) -lpthread
endif
ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS += -lnsl $(LIBSOCKET)
OTHER_LDLIBS += $(LIBNSL) $(LIBSOCKET)
endif
ifeq ($(PLATFORM), windows)
......
......@@ -39,10 +39,10 @@ ifeq ($(PLATFORM), windows)
EXTRA_LIBS += wsock32.lib winmm.lib
endif
ifeq ($(PLATFORM), solaris)
OTHER_LDLIBS += $(LIBSOCKET) -lnsl -ldl
OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) -ldl
endif
ifeq ($(PLATFORM), linux)
OTHER_LDLIBS += $(LIBSOCKET) -lnsl -ldl -lpthread
OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) -ldl -lpthread
endif
#
......
......@@ -204,8 +204,8 @@ Provided NetBeans projects
note that pretty much regardless of your hardware, this *will* take
a long time, and use *lots* of disk space (more than 3GB). The
results of the build are in
*install-dir*/control/build/*platform*-*arch* and
*install-dir*/control/build/*platform*-*arch*-fastdebug.
*install-dir*/build/*platform*-*arch* and
*install-dir*/build/*platform*-*arch*-fastdebug.
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.
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
<install-dir>/control/build/<platform>-<arch>
<install-dir>/build/<platform>-<arch>
and
<install-dir>/control/build/<platform>-<arch>-fastdebug
<install-dir>/build/<platform>-<arch>-fastdebug
......@@ -34,11 +34,11 @@
<import file="../common/shared.xml"/>
<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 name="-clean-make" depends="-make.init" if="use.make">
<make-run target="clean" dir="${root}/../control/make"/>
<make-run target="clean" dir="${root}/.."/>
</target>
</project>
......@@ -37,7 +37,7 @@ PRODUCT = sun
# This re-directs all the class files to a separate location
CLASSDESTDIR = $(TEMPDIR)/classes
OTHER_JAVACFLAGS += -Xlint:serial -Werror
OTHER_JAVACFLAGS += -Xlint:serial,-deprecation -Werror
include $(BUILDDIR)/common/Defs.gmk
#
......
......@@ -49,7 +49,8 @@ AUTO_FILES_JAVA_DIRS = \
# Extra jstat files
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
JHAT_RESOURCEDIR = $(CLASSDESTDIR)/com/sun/tools/hat/resources
......
......@@ -33,7 +33,7 @@
#include FT_FREETYPE_H
#ifdef _MSC_VER
#if _MSC_VER > 1400
#if _MSC_VER > 1400 && _MSC_VER < 1600
/*
* When building for Microsoft Windows, your program has a dependency
......@@ -68,7 +68,7 @@
"publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif /* _M_AMD64 */
#endif /* _MSC_VER > 1400 */
#endif /* _MSC_VER > 1400 && _MSC_VER < 1600 */
#endif /* _MSC_VER */
#define QUOTEMACRO(x) QUOTEME(x)
......
......@@ -424,7 +424,7 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
State rv;
rv = super.getState();
if (rv != State.DISABLED
&& ! comboBox.isEditable()
&& comboBox != null && ! comboBox.isEditable()
&& XPStyle.getXP().isSkinDefined(comboBox,
Part.CP_DROPDOWNBUTTONRIGHT)) {
/*
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -47,10 +47,13 @@ interface Constants {
public final static short JAVA5_MAX_CLASS_MAJOR_VERSION = 49;
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_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 JAVA5_PACKAGE_MAJOR_VERSION = 150;
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -57,8 +57,8 @@ class Package implements Constants {
// These fields can be adjusted by driver properties.
short min_class_majver = JAVA_MIN_CLASS_MAJOR_VERSION;
short min_class_minver = JAVA_MIN_CLASS_MINOR_VERSION;
short max_class_majver = JAVA6_MAX_CLASS_MAJOR_VERSION;
short max_class_minver = JAVA6_MAX_CLASS_MINOR_VERSION;
short max_class_majver = JAVA7_MAX_CLASS_MAJOR_VERSION;
short max_class_minver = JAVA7_MAX_CLASS_MINOR_VERSION;
short observed_max_class_majver = min_class_majver;
short observed_max_class_minver = min_class_minver;
......@@ -122,13 +122,16 @@ class Package implements Constants {
void choosePackageVersion() {
assert(package_majver <= 0); // do not call this twice
int classver = getHighestClassVersion();
if (classver != 0 &&
(classver >>> 16) < JAVA6_MAX_CLASS_MAJOR_VERSION) {
// There are only old classfiles in this segment.
if (classver == 0 || (classver >>> 16) < JAVA6_MAX_CLASS_MAJOR_VERSION) {
// There are only old classfiles in this segment or resources
package_majver = JAVA5_PACKAGE_MAJOR_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 {
// 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_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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -90,8 +90,8 @@ class PropMap extends TreeMap {
props.put(Utils.PACK_DEFAULT_TIMEZONE,
String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)));
// Limit segment size to less than a megabyte.
props.put(Pack200.Packer.SEGMENT_LIMIT, ""+(1*1000*1000));
// The segment size is unlimited
props.put(Pack200.Packer.SEGMENT_LIMIT, "");
// Preserve file ordering by default.
props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
......
......@@ -67,7 +67,6 @@ public class Registry {
// The stclient output has to be an exported interface
private static final String INSTANCE_URN_DESC = "Product instance URN=";
private static boolean initialized = false;
private static boolean supportsHelperClass = true; // default
private static File stclient = null;
private static String stclientPath = null;
private static Registry registry = new Registry();
......@@ -81,17 +80,6 @@ public class Registry {
private synchronized static String getSTclient() {
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
String os = System.getProperty("os.name");
if (os.equals("SunOS")) {
......@@ -108,10 +96,26 @@ public class Registry {
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
// JDK 5 doesn't support the File.canExecute() method.
// Risk not checking isExecute() for the stclient command is very low.
if (stclientPath == null && stclient != null && stclient.exists()) {
stclientPath = stclient.getAbsolutePath();
}
......@@ -142,8 +146,8 @@ public class Registry {
* @return {@code true} if the {@code Registry} class is supported;
* otherwise, return {@code false}.
*/
public static boolean isSupported() {
return (getSTclient() != null && supportsHelperClass);
public static synchronized boolean isSupported() {
return getSTclient() != null;
}
private static List<String> getCommandList() {
......
......@@ -53,13 +53,13 @@ a:visited,a:visited code{color:#917E9C}
</tr>
<tr>
<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>
from Sun Microsystems. </p>
from Oracle Corporation. </p>
<p class="style1">Registering your product will give you the following benefits:</p>
<ul class="style1">
<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>
</ul>
<p class="style1">Product registration is FREE, quick and easy!</p>
......@@ -68,11 +68,11 @@ a:visited,a:visited code{color:#917E9C}
<table width="708" border="0" cellspacing="0" cellpadding="3">
<tr valign="top">
<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="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="Register My JDK">
</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>
</table>
</blockquote>
......@@ -81,16 +81,16 @@ a:visited,a:visited code{color:#917E9C}
<tr>
<td>&nbsp;</td>
<td bgcolor="#f1f7df">
<p class="style3">Sun Microsystems, Inc. respects your privacy.
We will use your personal information for communications
and management of your Sun Online Account, the services
and applications you access using your Sun Online Account,
<p class="style3">Oracle Corporation respects your privacy.
We will use your personal information for communications
and management of your Sun Online Account, the services
and applications you access using your Sun Online Account,
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>
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>
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>
<td>&nbsp;</td>
......
......@@ -50,11 +50,11 @@ a:visited,a:visited code{color:#917E9C}
<tr>
<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>
<ul class="style1">
<li> 最新のバージョン、パッチ、および更新についての通知</li>
<li> Sun の開発者向け製品、サービス、およびトレーニングの特別販売 </li>
<li> Oracle の開発者向け製品、サービス、およびトレーニングの特別販売 </li>
<li> アーリーリリースおよびドキュメントへのアクセス </li>
</ul>
<p class="style1">製品登録は無料であり、迅速で簡単です。</p>
......@@ -62,11 +62,11 @@ a:visited,a:visited code{color:#917E9C}
<p class="style1">必要になるのは、Sun 開発者向けネットワークアカウントまたはその他の Sun オンラインアカウントだけです。 まだアカウントがない場合は、アカウントの作成が求められます。 </p>
<table width="708" border="0" cellspacing="0" cellpadding="3">
<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="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="JDK 製品登録">
</form></td>
<td width="570"><span class="style3">この Sun 製品を登録するには、インターネットに接続している必要があります。 </span></td>
<td width="570"><span class="style3">この Oracle 製品を登録するには、インターネットに接続している必要があります。 </span></td>
</tr>
</table>
</blockquote>
......@@ -75,8 +75,8 @@ a:visited,a:visited code{color:#917E9C}
<tr>
<td>&nbsp;</td>
<td bgcolor="#f1f7df">
<p class="style3">Sun Microsystems, Inc. は、お客様のプライバシーを尊重します。 お客様の個人情報は、お客様の 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">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> 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>
<td>&nbsp;</td>
......
......@@ -51,11 +51,11 @@ a:visited,a:visited code{color:#917E9C}
<tr>
<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>
<ul class="style1">
<li> 获得新版本、修补程序和更新的通知服务</li>
<li> 获得有关 Sun 开发者产品、服务和培训的优惠 </li>
<li> 获得有关 Oracle 开发者产品、服务和培训的优惠 </li>
<li> 获得对早期版本和文档的访问权限 </li>
</ul>
<p class="style1">产品注册是免费的,即快速又轻松!</p>
......@@ -63,11 +63,11 @@ a:visited,a:visited code{color:#917E9C}
<p class="style1">您需要具有 Sun 开发者网络或其他 Sun 联机帐户。如果您没有,系统将提示您创建一个。 </p>
<table width="708" border="0" cellspacing="0" cellpadding="3">
<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="submit" name="Submit"border="0" class="buttonblue" onmouseover="this.style.color='#fbe249';" onmouseout="this.style.color='#FFF';" value="注册我的 JDK">
</form></td>
<td width="570"><span class="style3">您需要连接到 Internet 来注册此 Sun 产品。 </span></td>
<td width="570"><span class="style3">您需要连接到 Internet 来注册此 Oracle 产品。 </span></td>
</tr>
</table>
</blockquote>
......@@ -76,8 +76,8 @@ a:visited,a:visited code{color:#917E9C}
<tr>
<td>&nbsp;</td>
<td bgcolor="#f1f7df">
<p class="style3">Sun Microsystems, Inc. 尊重您的隐私。我们会将您的个人信息用于通信和 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">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>有关 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>
<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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,25 +25,32 @@
package java.dyn;
import sun.dyn.util.BytecodeName;
import sun.dyn.Access;
import sun.dyn.MemberName;
import sun.dyn.CallSiteImpl;
import sun.dyn.MethodHandleImpl;
/**
* An {@code invokedynamic} call site, as reified by the
* containing class's bootstrap method.
* Every call site object corresponds to a distinct instance
* of the <code>invokedynamic</code> 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.
* A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode,
* and controls its linkage.
* Every linked {@code CallSite} object corresponds to a distinct instance
* of the {@code invokedynamic} instruction, and vice versa.
* <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,
* 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>
* An {@code invokedynamic} instruction which has not yet been executed
* is said to be <em>unlinked</em>. When an unlinked call site is executed,
......@@ -52,54 +59,139 @@ import sun.dyn.MethodHandleImpl;
* 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.
* <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)
* @author John Rose, JSR 292 EG
*/
public class CallSite
// Note: This is an implementation inheritance hack, and will be removed
// with a JVM change which moves the required hidden state onto this class.
extends CallSiteImpl
{
private static final Access IMPL_TOKEN = Access.getToken();
/*
// Fields used only by the JVM. Do not use or change.
private Object vmmethod;
int callerMID, callerBCI; // supplied by the JVM
private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
private int vmindex; // supplied by the JVM (BCI within calling method)
// The actual payload of this call site:
private MethodHandle target;
final Object caller; // usually a class
final String name;
final MethodType type;
*/
// Remove this field for PFD and delete deprecated methods:
private MemberName calleeNameRemoveForPFD;
/**
* Make a call site given the parameters from a call to the bootstrap method.
* The resulting call site is in an unlinked state, which means that before
* it is returned from a bootstrap method call it must be provided with
* a target method via a call to {@link CallSite#setTarget}.
* @param caller the class in which the relevant {@code invokedynamic} instruction occurs
* @param name the name specified by the {@code invokedynamic} instruction
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
* Make a blank call site object.
* Before it is returned from a bootstrap method, this {@code CallSite} object
* must be provided with
* a target method via a call to {@link CallSite#setTarget(MethodHandle) setTarget},
* or by a subclass override of {@link CallSite#initialTarget(Class,String,MethodType) initialTarget}.
*/
public CallSite(Object caller, String name, MethodType type) {
super(IMPL_TOKEN, caller, name, type);
public CallSite() {
}
private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) {
site.callerMID = callerMID;
site.callerBCI = callerBCI;
site.ensureTarget();
/**
* Make a blank call site object, possibly equipped with an initial target method handle.
* The initial target reference may be null, in which case the {@code CallSite} object
* 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,
// without deferring to possible subclass overrides.
if (super.getTarget() == null) {
super.setTarget(this.initialTarget());
super.getTarget().type(); // provoke NPE if still null
/** @deprecated transitional form defined in EDR but removed in PFD */
public CallSite(Class<?> caller, String name, MethodType type) {
this.calleeNameRemoveForPFD = new MemberName(caller, name, type);
}
/** @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
* the method {@code initialTarget} is called to produce an initial
* non-null target. (Live call sites must never have null targets.)
* <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,
* this method must be overridden, because it just raises an
* {@code InvokeDynamicBootstrapError}, which in turn causes the
* linkage of the {@code invokedynamic} instruction to terminate
* abnormally.
*/
protected MethodHandle initialTarget() {
throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+this);
protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) {
throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type);
}
/**
......@@ -137,11 +233,11 @@ public class CallSite
* @see #setTarget
*/
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>
* 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
......@@ -152,96 +248,46 @@ public class CallSite
* Stronger guarantees can be created by putting appropriate operations
* into the bootstrap method and/or the target methods used
* 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 WrongMethodTypeException if the proposed new target
* has a method type that differs from the call site's {@link #type()}
*/
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
* @throws WrongMethodTypeException if the call site is linked and the proposed new target
* has a method type that differs from the previous target
*/
public String name() {
return name;
public void setTarget(MethodHandle newTarget) {
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);
}
/**
* Report the method name specified in the {@code invokedynamic} instruction,
* 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);
private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
return new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type);
}
/**
* Report the resolved result and parameter types of this call site,
* 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
/** Produce a printed representation that displays information about this call site
* that may be useful to the human reader.
*/
public MethodType type() {
return type;
}
@Override
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 @@
package java.dyn;
/**
* Syntactic marker to request javac to emit an {@code invokedynamic} instruction.
* An {@code invokedynamic} instruction is a 5-byte bytecoded instruction
* which begins with an opcode byte of value 186 ({@code 0xBA}),
* and is followed by a two-byte index of a {@code NameAndType} constant
* 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.
* {@code InvokeDynamic} is a class with neither methods nor instances,
* which serves only as a syntactic marker in Java source code for
* an {@code invokedynamic} instruction.
* (See <a href="package-summary.html#jvm_mods">the package information</a> for specifics on this instruction.)
* <p>
* The {@code invokedynamic} instruction is incomplete without a target method.
* The target method is a property of the reified call site object
* (of type {@link CallSite}) which is in a one-to-one association with each
* corresponding {@code invokedynamic} instruction. The call site object
* is initially produced by a <em>bootstrap method</em> associated with
* the call site, via the various overloadings of {@link Linkage#registerBootstrapMethod}.
* The target method is a property of the reified {@linkplain CallSite call site object}
* which is linked to each active {@code invokedynamic} instruction.
* The call site object is initially produced by a
* {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
* associated with the class whose bytecodes include the dynamic call site.
* <p>
* The type {@code InvokeDynamic} has no particular meaning as a
* class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods.
* It may be viewed as a pure syntactic marker (an importable one) of static calls.
* It may be viewed as a pure syntactic marker of static calls.
* It may be imported for ease of use.
* <p>
* Here are some examples of usage:
* Here are some examples:
* <p><blockquote><pre>
* Object x; String s; int i;
* x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
......@@ -65,6 +63,7 @@ package java.dyn;
* which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG
*/
@MethodHandle.PolymorphicSignature
public final class InvokeDynamic {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -27,24 +27,29 @@ package java.dyn;
/**
* Thrown to indicate that an {@code invokedynamic} instruction has
* failed to find its bootstrap method, or the bootstrap method has
* failed to provide a call site with a non-null target.
* failed to find its
* {@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>
* The boostrap method must have been declared during a class's initialization
* by a call to {@link Linkage#registerBootstrapMethod}.
* The bootstrap method must have been declared during a class's initialization
* by a call to one of the overloadings of
* {@link Linkage#registerBootstrapMethod registerBootstrapMethod}.
*
* @author John Rose, JSR 292 EG
*/
public class InvokeDynamicBootstrapError extends LinkageError {
/**
* Constructs a {@code InvokeDynamicBootstrapError} with no detail message.
* Constructs an {@code InvokeDynamicBootstrapError} with no detail message.
*/
public InvokeDynamicBootstrapError() {
super();
}
/**
* Constructs a {@code InvokeDynamicBootstrapError} with the specified
* Constructs an {@code InvokeDynamicBootstrapError} with the specified
* detail message.
*
* @param s the detail message.
......
......@@ -28,7 +28,8 @@ package java.dyn;
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.
* Its behavior as a method handle is determined at instance creation time,
* by providing the new instance with an "entry point" method handle
......@@ -62,11 +63,11 @@ import sun.dyn.Access;
* greeter.run(); // prints "hello, world"
* // Statically typed method handle invocation (most direct):
* 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:
* MethodHandles.invoke(greeter); // also prints "hello, world"
* MethodHandles.invokeExact(greeter); // also prints "hello, world"
* greeter.setGreeting("howdy");
* mh.invoke(); // prints "howdy, world" (object-like mutable behavior)
* mh.invokeExact(); // prints "howdy, world" (object-like mutable behavior)
* </pre></blockquote>
* <p>
* In the example of {@code Greeter}, the method {@code run} provides the entry point.
......@@ -81,7 +82,7 @@ import sun.dyn.Access;
* inner class:
* <p><blockquote><pre>
* // 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"); }
* });
* </pre></blockquote>
......@@ -101,7 +102,7 @@ import sun.dyn.Access;
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
* mh.invoke(); // also prints "hello, world"
* mh.invokeExact(); // also prints "hello, world"
* </pre></blockquote>
* Note that the method handle must be separately created as a view on the base object.
* This increases footprint, complexity, and dynamic indirections.
......@@ -113,7 +114,7 @@ import sun.dyn.Access;
* MethodHandle greeter = new JavaMethodHandle("run") {
* private void run() { System.out.println("hello, "+greetee); }
* }
* greeter.invoke(); // prints "hello, world"
* greeter.invokeExact(); // prints "hello, world"
* </pre></blockquote>
* <p>
* Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
......@@ -137,10 +138,12 @@ import sun.dyn.Access;
* public Number get(long i) { return stuff[(int)i]; }
* public void set(long i, Object x) { stuff[(int)i] = x; }
* }
* int x = (Integer) stuffPtr.&lt;Number&gt;invoke(1L); // 456
* stuffPtr.setter().&lt;void&gt;invoke(0L, (Number) 789); // replaces 123 with 789
* int x = (Integer) stuffPtr.&lt;Number&gt;invokeExact(1L); // 456
* stuffPtr.setter().&lt;void&gt;invokeExact(0L, (Number) 789); // replaces 123 with 789
* </pre></blockquote>
* @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
*/
public abstract class JavaMethodHandle
......
......@@ -25,14 +25,19 @@
package java.dyn;
import java.lang.annotation.Annotation;
import java.dyn.MethodHandles.Lookup;
import java.util.WeakHashMap;
import sun.dyn.Access;
import sun.dyn.MethodHandleImpl;
import sun.reflect.Reflection;
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
*/
public class Linkage {
......@@ -42,102 +47,137 @@ public class Linkage {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Register a <em>bootstrap method</em> to use when linking a given caller class.
* It must be a method handle of a type equivalent to {@link CallSite#CallSite}.
* In other words, it must act as a factory method which accepts the arguments
* to {@code CallSite}'s constructor (a class, a string, and a method type),
* Register a <em>bootstrap method</em> to use when linking dynamic call sites within
* a given caller class.
* <p>
* 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}).
* <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>
* <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
* when passed {@link LinkagePermission}("registerBootstrapMethod",callerClass).
* <li>The given class already has a bootstrap method from a previous
* call to this method.
* <li>The given class is already fully initialized.
* <li>The given class is in the process of initialization, in another thread.
* <li>The same {@code CallSite} object has already been returned from
* a bootstrap method call to another {@code invokedynamic} call site.
* <li>The given caller class already has a bootstrap method registered.
* <li>The given caller class is already fully initialized.
* <li>The given caller class is in the process of initialization, in another thread.
* </ul>
* Because of these rules, a class may install its own bootstrap method in
* a static initializer.
* @param callerClass a class that may have {@code invokedynamic} sites
* @param bootstrapMethod the method to use to bootstrap all such sites
* @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
void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
checkBSM(bootstrapMethod);
synchronized (bootstrapMethods) {
if (bootstrapMethods.containsKey(callerClass))
throw new IllegalStateException("bootstrap method already declared in "+callerClass);
bootstrapMethods.put(callerClass, bootstrapMethod);
}
MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
}
static void checkBSM(MethodHandle mh) {
if (mh == null) throw new IllegalArgumentException("null bootstrap method");
if (mh.type() == OLD_BOOTSTRAP_METHOD_TYPE) // FIXME: delete at EDR/PFD
throw new WrongMethodTypeException("bootstrap method must be a CallSite factory");
if (mh.type() != BOOTSTRAP_METHOD_TYPE)
throw new WrongMethodTypeException(mh.toString());
static private void checkBSM(MethodHandle mh) {
if (mh == null) throw newIllegalArgumentException("null bootstrap method");
if (mh.type() == BOOTSTRAP_METHOD_TYPE_2)
// For now, always pass an empty array for the Annotations argument
mh = MethodHandles.insertArguments(mh, BOOTSTRAP_METHOD_TYPE_2.parameterCount()-1,
(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>
* Simplified version of registerBootstrapMethod for self-registration,
* Simplified version of {@code registerBootstrapMethod} for self-registration,
* to be called from a static initializer.
* Finds a static method of the required type in the
* given class, and installs it on the caller.
* @throws IllegalArgumentException if there is no such method
* given runtime class, and installs it on the caller class.
* @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
void registerBootstrapMethod(Class<?> runtime, String name) {
Class callc = Reflection.getCallerClass(2);
Lookup lookup = new Lookup(IMPL_TOKEN, callc);
MethodHandle bootstrapMethod =
lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
Class callerClass = Reflection.getCallerClass(2);
registerBootstrapMethodLookup(callerClass, runtime, name);
}
/**
* <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.
* 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 IllegalStateException if the caller class's static initializer
* has already run, or is already running in another thread
*/
public static
void registerBootstrapMethod(String name) {
Class callc = Reflection.getCallerClass(2);
Lookup lookup = new Lookup(IMPL_TOKEN, callc);
MethodHandle bootstrapMethod =
lookup.findStatic(callc, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
Class callerClass = Reflection.getCallerClass(2);
registerBootstrapMethodLookup(callerClass, callerClass, name);
}
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);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
}
/**
* <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.
* Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry
* point into its class.
* @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
MethodHandle getBootstrapMethod(Class callerClass) {
Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
synchronized (bootstrapMethods) {
return bootstrapMethods.get(callerClass);
}
checkBootstrapPrivilege(callc, callerClass, "getBootstrapMethod");
return MethodHandleImpl.getBootstrap(IMPL_TOKEN, callerClass);
}
/**
......@@ -148,13 +188,10 @@ public class Linkage {
public static final MethodType BOOTSTRAP_METHOD_TYPE
= MethodType.methodType(CallSite.class,
Class.class, String.class, MethodType.class);
private static final MethodType OLD_BOOTSTRAP_METHOD_TYPE
= MethodType.methodType(Object.class,
CallSite.class, Object[].class);
private static final WeakHashMap<Class, MethodHandle> bootstrapMethods =
new WeakHashMap<Class, MethodHandle>();
static final MethodType BOOTSTRAP_METHOD_TYPE_2
= MethodType.methodType(CallSite.class,
Class.class, String.class, MethodType.class,
Annotation[].class);
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
......@@ -182,10 +219,8 @@ public class Linkage {
/**
* <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.
* (These are exactly those sites which report the given class
* via the {@link CallSite#callerClass()} method.)
* <p>
* When this method returns, every matching <code>invokedynamic</code>
* instruction will invoke its bootstrap method on next call.
......@@ -201,18 +236,4 @@ public class Linkage {
}
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;
import java.util.StringTokenizer;
/**
* This class is for runtime permissions. A RuntimePermission
* contains a name (also referred to as a "target name") but
* This class is for managing runtime permission checking for
* 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
* or you don't.
*
* <P>
* 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,
* <p>
* The following table lists all the possible {@code LinkagePermission} target names,
* and for each provides a description of what the permission allows
* and a discussion of the risks of granting code the permission.
* <P>
* <p>
*
* <table border=1 cellpadding=5 summary="permission target name,
* what the target allows,and associated risks">
......@@ -59,15 +53,17 @@ import java.util.StringTokenizer;
*
* <tr>
* <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
* 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>
* <td>invalidateAll</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>
*
*
......@@ -78,7 +74,7 @@ import java.util.StringTokenizer;
* </tr>
* </table>
*
* @see java.security.BasicPermission
* @see java.security.RuntimePermission
* @see java.lang.SecurityManager
*
* @author John Rose, JSR 292 EG
......
......@@ -34,32 +34,34 @@ import static java.dyn.MethodHandles.invokers; // package-private API
import static sun.dyn.MemberName.newIllegalArgumentException; // utility
/**
* A method handle is a typed reference to the entry point of a method.
* 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>
* Method handles are strongly typed according to signature.
* They are not distinguished by method name or enclosing class.
* 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>
* 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 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>
* 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.
* A Java method call expression, which compiles to an
* <code>invokevirtual</code> instruction,
* {@code invokevirtual} instruction,
* can invoke this method from Java source code.
* <p>
* Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle.
* (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.)
* 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}
* 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.
* As with other kinds
* of methods in the JVM, signature matching during method linkage
......@@ -76,13 +78,13 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* They should not be passed to untrusted code.
* <p>
* Bytecode in an extended JVM can directly call a method handle's
* <code>invoke</code> from an <code>invokevirtual</code> instruction.
* The receiver class type must be <code>MethodHandle</code> and the method name
* must be <code>invoke</code>. The signature of the invocation
* {@code invoke} from an {@code invokevirtual} instruction.
* The receiver class type must be {@code MethodHandle} and the method name
* must be {@code invoke}. The signature of the invocation
* (after resolving symbolic type names) must exactly match the method type
* of the target method.
* <p>
* Every <code>invoke</code> method always throws {@link Exception},
* Every {@code invoke} method always throws {@link Exception},
* which is to say that there is no static restriction on what a method handle
* can throw. Since the JVM does not distinguish between checked
* and unchecked exceptions (other than by their class, of course),
......@@ -92,11 +94,11 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* throw {@code Exception}, or else must catch all checked exceptions locally.
* <p>
* Bytecode in an extended JVM can directly obtain a method handle
* for any accessible method from a <code>ldc</code> instruction
* which refers to a <code>CONSTANT_Methodref</code> or
* <code>CONSTANT_InterfaceMethodref</code> constant pool entry.
* for any accessible method from a {@code ldc} instruction
* which refers to a {@code CONSTANT_Methodref} or
* {@code CONSTANT_InterfaceMethodref} constant pool entry.
* <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.
* <p>
* A method reference may refer either to a static or non-static method.
......@@ -104,7 +106,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* receiver argument, prepended before any other arguments.
* In the method handle's type, the initial receiver argument is typed
* 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.)
* <p>
* When a method handle to a virtual method is invoked, the method is
......@@ -113,38 +115,38 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* A non-virtual method handles to a specific virtual method implementation
* can also be created. These do not perform virtual lookup based on
* receiver type. Such a method handle simulates the effect of
* an <code>invokespecial</code> instruction to the same method.
* an {@code invokespecial} instruction to the same method.
* <p>
* Here are some examples of usage:
* <p><blockquote><pre>
* Object x, y; String s; int i;
* MethodType mt; MethodHandle mh;
* MethodHandles.Lookup lookup = MethodHandles.lookup();
* // mt is {(char,char) =&gt; String}
* mt = MethodType.make(String.class, char.class, char.class);
* mh = lookup.findVirtual(String.class, "replace", mt);
* // (Ljava/lang/String;CC)Ljava/lang/String;
* s = mh.&lt;String&gt;invoke("daddy",'d','n');
* assert(s.equals("nanny"));
* // weakly typed invocation (using MHs.invoke)
* s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v');
* assert(s.equals("savvy"));
* // mt is {Object[] =&gt; List}
* mt = MethodType.make(java.util.List.class, Object[].class);
* mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
* // mt is {(Object,Object,Object) =&gt; Object}
* mt = MethodType.makeGeneric(3);
* mh = MethodHandles.collectArguments(mh, mt);
* // mt is {(Object,Object,Object) =&gt; Object}
* // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
* x = mh.invoke((Object)1, (Object)2, (Object)3);
* assert(x.equals(java.util.Arrays.asList(1,2,3)));
* // mt is { =&gt; int}
* mt = MethodType.make(int.class);
* mh = lookup.findVirtual(java.util.List.class, "size", mt);
* // (Ljava/util/List;)I
* i = mh.&lt;int&gt;invoke(java.util.Arrays.asList(1,2,3));
* assert(i == 3);
Object x, y; String s; int i;
MethodType mt; MethodHandle mh;
MethodHandles.Lookup lookup = MethodHandles.lookup();
// mt is {(char,char) =&gt; String}
mt = MethodType.methodType(String.class, char.class, char.class);
mh = lookup.findVirtual(String.class, "replace", mt);
// (Ljava/lang/String;CC)Ljava/lang/String;
s = mh.&lt;String&gt;invokeExact("daddy",'d','n');
assert(s.equals("nanny"));
// weakly typed invocation (using MHs.invoke)
s = (String) mh.invokeVarargs("sappy", 'p', 'v');
assert(s.equals("savvy"));
// mt is {Object[] =&gt; List}
mt = MethodType.methodType(java.util.List.class, Object[].class);
mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
// mt is {(Object,Object,Object) =&gt; Object}
mt = MethodType.genericMethodType(3);
mh = MethodHandles.collectArguments(mh, mt);
// mt is {(Object,Object,Object) =&gt; Object}
// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
x = mh.invokeExact((Object)1, (Object)2, (Object)3);
assert(x.equals(java.util.Arrays.asList(1,2,3)));
// mt is { =&gt; int}
mt = MethodType.methodType(int.class);
mh = lookup.findVirtual(java.util.List.class, "size", mt);
// (Ljava/util/List;)I
i = mh.&lt;int&gt;invokeExact(java.util.Arrays.asList(1,2,3));
assert(i == 3);
* </pre></blockquote>
* Each of the above calls generates a single invokevirtual instruction
* with the name {@code invoke} and the type descriptors indicated in the comments.
......@@ -167,6 +169,14 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* those of multiple arities. It is impossible to represent such
* genericity with a Java type parameter.</li>
* </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 MethodHandles
......@@ -180,7 +190,15 @@ public abstract class MethodHandle
private static Access IMPL_TOKEN = Access.getToken();
// 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;
......@@ -232,85 +250,38 @@ public abstract class MethodHandle
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
//// will be deprecated. Others will be kept as "algorithms" to supply degrees of freedom
//// not present in the Kernel API.
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform an exact invocation. The signature at the call site of {@code invokeExact} must
* 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}.
* No conversions are allowed on arguments or return values.
* <em>This is not yet implemented, pending required compiler and JVM support.</em>
*/
public final <T> T invokeExact(Object... arguments) throws Throwable {
// This is an approximate implementation, which discards the caller's signature and refuses the call.
throw new InternalError("not yet implemented");
}
public final native @PolymorphicSignature <R,A> R invokeExact(A... args) throws Throwable;
// 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>
* 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}.
* The same conversions are allowed on arguments or return values as are supported by
* by {@link MethodHandles#convertArguments}.
* If the call site signature exactly matches this method handle's {@code type},
* the call proceeds as if by {@link #invokeExact}.
* <em>This is not fully implemented, pending required compiler and JVM support.</em>
*/
// This is an approximate implementation, which discards the caller's signature.
// When it is made signature polymorphic, the overloadings will disappear.
public final <T> T invokeGeneric() throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this);
}
public final <T> T invokeGeneric(Object a0) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0);
}
public final <T> T invokeGeneric(Object a0, Object a1) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7, a8);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
public final native @PolymorphicSignature <R,A> R invokeGeneric(A... args) throws Throwable;
// ?? public final native @PolymorphicSignature <R,A,V> R invokeVarargs(A args, V[] varargs) throws Throwable;
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
......@@ -341,47 +312,47 @@ public abstract class MethodHandle
* This call is equivalent to the following code:
* <p><blockquote><pre>
* MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
* Object result = invoker.invoke(this, arguments);
* Object result = invoker.invokeExact(this, arguments);
* </pre></blockquote>
* @param arguments the arguments to pass to the target
* @return the result returned by the target
* @see MethodHandles#genericInvoker
*/
public final Object invokeVarargs(Object[] arguments) throws Throwable {
public final Object invokeVarargs(Object... arguments) throws Throwable {
int argc = arguments == null ? 0 : arguments.length;
MethodType type = type();
if (argc <= 10) {
MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
switch (argc) {
case 0: return invoker.invoke(this);
case 1: return invoker.invoke(this,
case 0: return invoker.invokeExact(this);
case 1: return invoker.invokeExact(this,
arguments[0]);
case 2: return invoker.invoke(this,
case 2: return invoker.invokeExact(this,
arguments[0], arguments[1]);
case 3: return invoker.invoke(this,
case 3: return invoker.invokeExact(this,
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[3]);
case 5: return invoker.invoke(this,
case 5: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4]);
case 6: return invoker.invoke(this,
case 6: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
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[3], arguments[4], arguments[5],
arguments[6]);
case 8: return invoker.invoke(this,
case 8: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7]);
case 9: return invoker.invoke(this,
case 9: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8]);
case 10: return invoker.invoke(this,
case 10: return invoker.invokeExact(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8],
......@@ -391,7 +362,7 @@ public abstract class MethodHandle
// more than ten arguments get boxed in a varargs list:
MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
return invoker.invoke(this, arguments);
return invoker.invokeExact(this, arguments);
}
/** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
......
......@@ -36,15 +36,24 @@ import sun.dyn.util.BytecodeDescriptor;
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 types (primitive, void, and reference) are represented by Class objects.
* <p>
* All instances of <code>MethodType</code> are immutable.
* 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>
* 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
*/
public final
......@@ -109,7 +118,7 @@ class MethodType {
/** Find or create an instance of the given method type.
* @param rtype the return type
* @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 IllegalArgumentException if any of the ptypes is void
*/
......@@ -626,7 +635,7 @@ class MethodType {
}
/** 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
* 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).
......
......@@ -27,11 +27,12 @@ package java.dyn;
/**
* 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},
* which is a checked exception thrown when reflective invocation fails
* 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.
* @author John Rose, JSR 292 EG
*/
......
......@@ -27,6 +27,105 @@
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* This package contains dynamic language support provided directly by
* 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
*/
......
......@@ -66,7 +66,7 @@ public class AssertionError extends Error {
* defined in <i>The Java Language Specification, Second
* Edition</i>, Section 15.18.1.1.
*<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.
*
* @param detailMessage value to be used in constructing detail message
......@@ -149,4 +149,21 @@ public class AssertionError extends Error {
public AssertionError(double 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 {
private static Random randomNumberGenerator;
private static synchronized void initRNG() {
if (randomNumberGenerator == null)
randomNumberGenerator = new Random();
private static synchronized Random initRNG() {
Random rnd = randomNumberGenerator;
return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
}
/**
......@@ -694,9 +694,11 @@ public final class Math {
*
* <p>When this method is first called, it creates a single new
* 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
* calls to this method and is used nowhere else.
*
* <blockquote>{@code new java.util.Random()}</blockquote>
*
* 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
* more than one thread. However, if many threads need to generate
......@@ -705,11 +707,12 @@ public final class Math {
*
* @return a pseudorandom {@code double} greater than or equal
* to {@code 0.0} and less than {@code 1.0}.
* @see java.util.Random#nextDouble()
* @see Random#nextDouble()
*/
public static double random() {
if (randomNumberGenerator == null) initRNG();
return randomNumberGenerator.nextDouble();
Random rnd = randomNumberGenerator;
if (rnd == null) rnd = initRNG();
return rnd.nextDouble();
}
/**
......
......@@ -418,6 +418,8 @@ public final class ProcessBuilder
* Implements a <a href="#redirect-output">null input stream</a>.
*/
static class NullInputStream extends InputStream {
static final NullInputStream INSTANCE = new NullInputStream();
private NullInputStream() {}
public int read() { return -1; }
public int available() { return 0; }
}
......@@ -426,6 +428,8 @@ public final class ProcessBuilder
* Implements a <a href="#redirect-input">null output stream</a>.
*/
static class NullOutputStream extends OutputStream {
static final NullOutputStream INSTANCE = new NullOutputStream();
private NullOutputStream() {}
public void write(int b) throws IOException {
throw new IOException("Stream closed");
}
......
......@@ -667,9 +667,9 @@ public final class StrictMath {
private static Random randomNumberGenerator;
private static synchronized void initRNG() {
if (randomNumberGenerator == null)
randomNumberGenerator = new Random();
private static synchronized Random initRNG() {
Random rnd = randomNumberGenerator;
return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
}
/**
......@@ -680,9 +680,11 @@ public final class StrictMath {
*
* <p>When this method is first called, it creates a single new
* 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
* calls to this method and is used nowhere else.
*
* <blockquote>{@code new java.util.Random()}</blockquote>
*
* 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
* more than one thread. However, if many threads need to generate
......@@ -691,11 +693,12 @@ public final class StrictMath {
*
* @return a pseudorandom {@code double} greater than or equal
* to {@code 0.0} and less than {@code 1.0}.
* @see java.util.Random#nextDouble()
* @see Random#nextDouble()
*/
public static double random() {
if (randomNumberGenerator == null) initRNG();
return randomNumberGenerator.nextDouble();
Random rnd = randomNumberGenerator;
if (rnd == null) rnd = initRNG();
return rnd.nextDouble();
}
/**
......
......@@ -678,7 +678,7 @@ public final class Security {
spiMap.put(type, clazz);
return clazz;
} 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 {
* its list-iterator does not support the <tt>set</tt> operation.
*/
public static void shuffle(List<?> list) {
if (r == null) {
r = new Random();
}
shuffle(list, r);
Random rnd = r;
if (rnd == null)
r = rnd = new Random();
shuffle(list, rnd);
}
private static Random r;
......
......@@ -73,10 +73,10 @@ public class ThreadLocalRandom extends Random {
private long rnd;
/**
* Initialization flag to permit the first and only allowed call
* to setSeed (inside Random constructor) to succeed. We can't
* allow others since it would cause setting seed in one part of a
* program to unintentionally impact other usages by the thread.
* Initialization flag to permit calls to setSeed to succeed only
* while executing the Random constructor. We can't allow others
* since it would cause setting seed in one part of a program to
* unintentionally impact other usages by the thread.
*/
boolean initialized;
......@@ -98,11 +98,10 @@ public class ThreadLocalRandom extends Random {
/**
* Constructor called only by localRandom.initialValue.
* We rely on the fact that the superclass no-arg constructor
* invokes setSeed exactly once to initialize.
*/
ThreadLocalRandom() {
super();
initialized = true;
}
/**
......@@ -123,7 +122,6 @@ public class ThreadLocalRandom extends Random {
public void setSeed(long seed) {
if (initialized)
throw new UnsupportedOperationException();
initialized = true;
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -212,10 +212,18 @@ public abstract class Pack200 {
* to produce a specific bytewise image for any given transmission
* ordering of archive elements.)
* <p>
* In order to maintain backward compatibility, if the input JAR-files are
* solely comprised of 1.5 (or lesser) classfiles, a 1.5 compatible
* pack file is produced. Otherwise a 1.6 compatible pack200 file is
* produced.
* In order to maintain backward compatibility, the pack file's version is
* set to accommodate the class files present in the input JAR file. In
* other words, the pack file version will be the latest, if the class files
* 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>
* @since 1.5
*/
......@@ -236,9 +244,10 @@ public abstract class Pack200 {
* input file to be transmitted in the segment, along with the size
* of its name and other transmitted properties.
* <p>
* The default is 1000000 (a million bytes). This allows input JAR files
* of moderate size to be transmitted in one segment. It also puts
* a limit on memory requirements for packers and unpackers.
* The default is -1, which means the packer will always create a single
* segment output file. In cases where extremely large output files are
* generated, users are strongly encouraged to use segmenting or break
* up the input file into smaller JARs.
* <p>
* A 10Mb JAR packed without this limit will
* typically pack about 10% smaller, but the packer may require
......
/*
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,7 +26,6 @@ package javax.swing;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JComponent;
import javax.swing.border.*;
/**
......@@ -74,10 +73,20 @@ public class BorderFactory
return new LineBorder(color, thickness);
}
// public static Border createLineBorder(Color color, int thickness,
// boolean drawRounded) {
// return new JLineBorder(color, thickness, drawRounded);
// }
/**
* Creates a line border with the specified color, thickness, and corner shape.
*
* @param color the color of the border
* @param thickness the thickness of the border
* @param rounded whether or not border corners should be round
* @return the {@code Border} object
*
* @see LineBorder#LineBorder(Color, int, boolean)
* @since 1.7
*/
public static Border createLineBorder(Color color, int thickness, boolean rounded) {
return new LineBorder(color, thickness, rounded);
}
//// BevelBorder /////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
......@@ -180,7 +189,115 @@ public class BorderFactory
}
return null;
}
//// SoftBevelBorder ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
private static Border sharedSoftRaisedBevel;
private static Border sharedSoftLoweredBevel;
/**
* Creates a beveled border with a raised edge and softened corners,
* using brighter shades of the component's current background color
* for highlighting, and darker shading for shadows.
* In a raised border, highlights are on top and shadows are underneath.
*
* @return the {@code Border} object
*
* @since 1.7
*/
public static Border createRaisedSoftBevelBorder() {
if (sharedSoftRaisedBevel == null) {
sharedSoftRaisedBevel = new SoftBevelBorder(BevelBorder.RAISED);
}
return sharedSoftRaisedBevel;
}
/**
* Creates a beveled border with a lowered edge and softened corners,
* using brighter shades of the component's current background color
* for highlighting, and darker shading for shadows.
* In a lowered border, shadows are on top and highlights are underneath.
*
* @return the {@code Border} object
*
* @since 1.7
*/
public static Border createLoweredSoftBevelBorder() {
if (sharedSoftLoweredBevel == null) {
sharedSoftLoweredBevel = new SoftBevelBorder(BevelBorder.LOWERED);
}
return sharedSoftLoweredBevel;
}
/**
* Creates a beveled border of the specified type with softened corners,
* using brighter shades of the component's current background color
* for highlighting, and darker shading for shadows.
* The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
*
* @param type a type of a bevel
* @return the {@code Border} object or {@code null}
* if the specified type is not valid
*
* @see BevelBorder#BevelBorder(int)
* @since 1.7
*/
public static Border createSoftBevelBorder(int type) {
if (type == BevelBorder.RAISED) {
return createRaisedSoftBevelBorder();
}
if (type == BevelBorder.LOWERED) {
return createLoweredSoftBevelBorder();
}
return null;
}
/**
* Creates a beveled border of the specified type with softened corners,
* using the specified highlighting and shadowing.
* The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
* The outer edge of the highlight area uses
* a brighter shade of the {@code highlight} color.
* The inner edge of the shadow area uses
* a brighter shade of the {@code shadow} color.
*
* @param type a type of a bevel
* @param highlight a basic color of the highlight area
* @param shadow a basic color of the shadow area
* @return the {@code Border} object
*
* @see BevelBorder#BevelBorder(int, Color, Color)
* @since 1.7
*/
public static Border createSoftBevelBorder(int type, Color highlight, Color shadow) {
return new BevelBorder(type, highlight, shadow);
}
/**
* Creates a beveled border of the specified type with softened corners,
* using the specified colors for the inner and outer edges
* of the highlight and the shadow areas.
* The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
* Note: The shadow inner and outer colors are switched
* for a lowered bevel border.
*
* @param type a type of a bevel
* @param highlightOuter a color of the outer edge of the highlight area
* @param highlightInner a color of the inner edge of the highlight area
* @param shadowOuter a color of the outer edge of the shadow area
* @param shadowInner a color of the inner edge of the shadow area
* @return the {@code Border} object
*
* @see BevelBorder#BevelBorder(int, Color, Color, Color, Color)
* @since 1.7
*/
public static Border createSoftBevelBorder(int type, Color highlightOuter, Color highlightInner, Color shadowOuter, Color shadowInner) {
return new BevelBorder(type, highlightOuter, highlightInner, shadowOuter, shadowInner);
}
//// EtchedBorder ///////////////////////////////////////////////////////////
static final Border sharedEtchedBorder = new EtchedBorder();
private static Border sharedRaisedEtchedBorder;
......
......@@ -658,8 +658,7 @@ class SynthParser extends DefaultHandler {
}
try {
_colorTypes.add((ColorType)checkCast(typeClass.
getField(typeName.substring(classIndex,
typeName.length() - classIndex)).
getField(typeName.substring(classIndex)).
get(typeClass), ColorType.class));
} catch (NoSuchFieldException nsfe) {
throw new SAXException("Unable to find color type: " +
......
......@@ -363,18 +363,24 @@ public class SynthToolBarUI extends BasicToolBarUI
SynthIcon.getIconWidth(handleIcon, context) : 0;
Dimension compDim;
for (int i = 0; i < tb.getComponentCount(); i++) {
compDim = tb.getComponent(i).getMinimumSize();
dim.width += compDim.width;
dim.height = Math.max(dim.height, compDim.height);
Component component = tb.getComponent(i);
if (component.isVisible()) {
compDim = component.getMinimumSize();
dim.width += compDim.width;
dim.height = Math.max(dim.height, compDim.height);
}
}
} else {
dim.height = tb.isFloatable() ?
SynthIcon.getIconHeight(handleIcon, context) : 0;
Dimension compDim;
for (int i = 0; i < tb.getComponentCount(); i++) {
compDim = tb.getComponent(i).getMinimumSize();
dim.width = Math.max(dim.width, compDim.width);
dim.height += compDim.height;
Component component = tb.getComponent(i);
if (component.isVisible()) {
compDim = component.getMinimumSize();
dim.width = Math.max(dim.width, compDim.width);
dim.height += compDim.height;
}
}
}
dim.width += insets.left + insets.right;
......@@ -395,18 +401,24 @@ public class SynthToolBarUI extends BasicToolBarUI
SynthIcon.getIconWidth(handleIcon, context) : 0;
Dimension compDim;
for (int i = 0; i < tb.getComponentCount(); i++) {
compDim = tb.getComponent(i).getPreferredSize();
dim.width += compDim.width;
dim.height = Math.max(dim.height, compDim.height);
Component component = tb.getComponent(i);
if (component.isVisible()) {
compDim = component.getPreferredSize();
dim.width += compDim.width;
dim.height = Math.max(dim.height, compDim.height);
}
}
} else {
dim.height = tb.isFloatable() ?
SynthIcon.getIconHeight(handleIcon, context) : 0;
Dimension compDim;
for (int i = 0; i < tb.getComponentCount(); i++) {
compDim = tb.getComponent(i).getPreferredSize();
dim.width = Math.max(dim.width, compDim.width);
dim.height += compDim.height;
Component component = tb.getComponent(i);
if (component.isVisible()) {
compDim = component.getPreferredSize();
dim.width = Math.max(dim.width, compDim.width);
dim.height += compDim.height;
}
}
}
dim.width += insets.left + insets.right;
......@@ -469,22 +481,24 @@ public class SynthToolBarUI extends BasicToolBarUI
for (int i = 0; i < tb.getComponentCount(); i++) {
c = tb.getComponent(i);
d = c.getPreferredSize();
int y, h;
if (d.height >= baseH || c instanceof JSeparator) {
// Fill available height
y = baseY;
h = baseH;
} else {
// Center component vertically in the available space
y = baseY + (baseH / 2) - (d.height / 2);
h = d.height;
if (c.isVisible()) {
d = c.getPreferredSize();
int y, h;
if (d.height >= baseH || c instanceof JSeparator) {
// Fill available height
y = baseY;
h = baseH;
} else {
// Center component vertically in the available space
y = baseY + (baseH / 2) - (d.height / 2);
h = d.height;
}
//if the component is a "glue" component then add to its
//width the extraSpacePerGlue it is due
if (isGlue(c)) d.width += extraSpacePerGlue;
c.setBounds(ltr ? x : x - d.width, y, d.width, h);
x = ltr ? x + d.width : x - d.width;
}
//if the component is a "glue" component then add to its
//width the extraSpacePerGlue it is due
if (isGlue(c)) d.width += extraSpacePerGlue;
c.setBounds(ltr ? x : x - d.width, y, d.width, h);
x = ltr ? x + d.width : x - d.width;
}
} else {
int handleHeight = tb.isFloatable() ?
......@@ -512,29 +526,31 @@ public class SynthToolBarUI extends BasicToolBarUI
for (int i = 0; i < tb.getComponentCount(); i++) {
c = tb.getComponent(i);
d = c.getPreferredSize();
int x, w;
if (d.width >= baseW || c instanceof JSeparator) {
// Fill available width
x = baseX;
w = baseW;
} else {
// Center component horizontally in the available space
x = baseX + (baseW / 2) - (d.width / 2);
w = d.width;
if (c.isVisible()) {
d = c.getPreferredSize();
int x, w;
if (d.width >= baseW || c instanceof JSeparator) {
// Fill available width
x = baseX;
w = baseW;
} else {
// Center component horizontally in the available space
x = baseX + (baseW / 2) - (d.width / 2);
w = d.width;
}
//if the component is a "glue" component then add to its
//height the extraSpacePerGlue it is due
if (isGlue(c)) d.height += extraSpacePerGlue;
c.setBounds(x, y, w, d.height);
y += d.height;
}
//if the component is a "glue" component then add to its
//height the extraSpacePerGlue it is due
if (isGlue(c)) d.height += extraSpacePerGlue;
c.setBounds(x, y, w, d.height);
y += d.height;
}
}
context.dispose();
}
private boolean isGlue(Component c) {
if (c instanceof Box.Filler) {
if (c.isVisible() && c instanceof Box.Filler) {
Box.Filler f = (Box.Filler)c;
Dimension min = f.getMinimumSize();
Dimension pref = f.getPreferredSize();
......
......@@ -25,15 +25,12 @@
package javax.swing.text;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.font.TextAttribute;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Stack;
......@@ -41,15 +38,14 @@ import java.util.Vector;
import java.util.ArrayList;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.swing.Icon;
import javax.swing.event.*;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoableEdit;
import javax.swing.SwingUtilities;
import static sun.swing.SwingUtilities2.IMPLIED_CR;
/**
* A document that can be marked up with character and paragraph
......@@ -782,9 +778,18 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc
// Check for the composed text element. If it is, merge the character attributes
// into this element as well.
if (Utilities.isComposedTextAttributeDefined(attr)) {
((MutableAttributeSet)attr).addAttributes(cattr);
((MutableAttributeSet)attr).addAttribute(AbstractDocument.ElementNameAttribute,
AbstractDocument.ContentElementName);
MutableAttributeSet mattr = (MutableAttributeSet) attr;
mattr.addAttributes(cattr);
mattr.addAttribute(AbstractDocument.ElementNameAttribute,
AbstractDocument.ContentElementName);
// Assure that the composed text element is named properly
// and doesn't have the CR attribute defined.
mattr.addAttribute(StyleConstants.NameAttribute,
AbstractDocument.ContentElementName);
if (mattr.isDefined(IMPLIED_CR)) {
mattr.removeAttribute(IMPLIED_CR);
}
}
ElementSpec[] spec = new ElementSpec[parseBuffer.size()];
......
......@@ -32,6 +32,7 @@ import java.util.Locale;
import javax.swing.UIManager;
import sun.swing.SwingUtilities2;
import static sun.swing.SwingUtilities2.IMPLIED_CR;
/**
* A GlyphView is a styled chunk of text that represents a view
......@@ -1061,7 +1062,6 @@ public class GlyphView extends View implements TabableView, Cloneable {
int length;
// if it is an implied newline character
boolean impliedCR;
private static final String IMPLIED_CR = "CR";
boolean skipWidth;
/**
......
......@@ -403,6 +403,24 @@ public class Utilities {
return txtCount;
}
/**
* Adjust text offset so that the length of a resulting string as a whole
* fits into the specified width.
*/
static int adjustOffsetForFractionalMetrics(
Segment s, FontMetrics fm, int offset, int width) {
// Sometimes the offset returned by getTabbedTextOffset is beyond the
// available area, when fractional metrics are enabled. We should
// guard against this.
if (offset < s.count) {
while (offset > 0 &&
fm.charsWidth(s.array, s.offset, offset + 1) > width) {
offset--;
}
}
return offset;
}
/**
* Determine where to break the given text to fit
* within the given span. This tries to find a word boundary.
......@@ -425,7 +443,7 @@ public class Utilities {
int txtCount = s.count;
int index = Utilities.getTabbedTextOffset(s, metrics, x0, x,
e, startOffset, false);
index = adjustOffsetForFractionalMetrics(s, metrics, index, x - x0);
if (index >= txtCount - 1) {
return txtCount;
......
......@@ -108,7 +108,7 @@ public class WrappedPlainView extends BoxView implements TabExpander {
try {
if (line.isLeaf()) {
drawText(line, p0, p1, g, x, y);
drawText(line, p0, p1, g, x, y);
} else {
// this line contains the composed text.
int idx = line.getElementIndex(p0);
......@@ -239,9 +239,11 @@ public class WrappedPlainView extends BoxView implements TabExpander {
tabBase, tabBase + currentWidth,
this, p0);
} else {
p = p0 + Utilities.getTabbedTextOffset(segment, metrics,
tabBase, tabBase + currentWidth,
this, p0, false);
int offset = Utilities.getTabbedTextOffset(segment, metrics,
tabBase, tabBase + currentWidth, this, p0, false);
offset = Utilities.adjustOffsetForFractionalMetrics(
segment, metrics, offset, currentWidth);
p = p0 + offset;
}
SegmentCache.releaseSharedSegment(segment);
return p;
......
......@@ -24,20 +24,17 @@
*/
package javax.swing.text.html;
import java.awt.Color;
import java.awt.Component;
import java.awt.font.TextAttribute;
import java.util.*;
import java.net.URL;
import java.net.URLEncoder;
import java.net.MalformedURLException;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.undo.*;
import java.text.Bidi;
import sun.swing.SwingUtilities2;
import static sun.swing.SwingUtilities2.IMPLIED_CR;
/**
* A document that models HTML. The purpose of this model is to
......@@ -1819,7 +1816,6 @@ public class HTMLDocument extends DefaultStyledDocument {
static String MAP_PROPERTY = "__MAP__";
private static char[] NEWLINE;
private static final String IMPLIED_CR = "CR";
/**
* I18N property key.
......
......@@ -366,7 +366,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
}
private static boolean convOpSupported(int convOp) {
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. */
......
......@@ -146,6 +146,8 @@ public class BoundMethodHandle extends MethodHandle {
MethodType foundType = null;
MemberName foundMethod = null;
for (MemberName method : methods) {
if (method.getDeclaringClass() == MethodHandle.class)
continue; // ignore methods inherited from MH class itself
MethodType mtype = method.getMethodType();
if (type != null && type.parameterCount() != mtype.parameterCount())
continue;
......
......@@ -26,77 +26,65 @@
package sun.dyn;
import java.dyn.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Parts of CallSite known to the JVM.
* FIXME: Merge all this into CallSite proper.
* @author jrose
*/
public class CallSiteImpl {
// Field used only by the JVM. Do not use or change.
private Object vmmethod;
// Values supplied by the JVM:
protected int callerMID, callerBCI;
private MethodHandle target;
protected final Object caller; // usually a class
protected final String name;
protected final MethodType type;
/** called only directly from CallSite() */
protected CallSiteImpl(Access token, Object caller, String name, MethodType type) {
Access.check(token);
this.caller = caller;
this.name = name;
this.type = type;
}
/** 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);
// this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
static CallSite makeSite(MethodHandle bootstrapMethod,
// Callee information:
String name, MethodType type,
// Call-site attributes, if any:
Object info,
// Caller information:
MemberName callerMethod, int callerBCI) {
Class<?> caller = callerMethod.getDeclaringClass();
if (bootstrapMethod == null) {
// If there is no bootstrap method, throw IncompatibleClassChangeError.
// This is a valid generic error type for resolution (JLS 12.3.3).
throw new IncompatibleClassChangeError
("Class "+caller.getName()+" has not declared a bootstrap method for invokedynamic");
}
if (site == null)
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);
CallSite site;
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) {
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;
}
// 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 {
}
protected Object invoke(Object argument) throws Throwable {
Object filteredArgument = filter.invoke(argument);
return target.invoke(filteredArgument);
Object filteredArgument = filter.invokeExact(argument);
return target.invokeExact(filteredArgument);
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,12 +28,16 @@ package sun.dyn;
import java.dyn.CallSite;
import java.dyn.MethodHandle;
import java.dyn.MethodType;
import java.dyn.MethodHandles.Lookup;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import static sun.dyn.MethodHandleNatives.Constants.*;
import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP;
/**
* 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
*/
class MethodHandleNatives {
......@@ -60,8 +64,14 @@ class MethodHandleNatives {
/** Initialize a method type, once per form. */
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. */
static native void linkCallSite(CallSite site, MethodHandle target);
static native void setCallSiteTarget(CallSite site, MethodHandle target);
/** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references.
......@@ -114,22 +124,28 @@ class MethodHandleNatives {
*/
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();
static {
boolean JVM_SUPPORT_;
int JVM_PUSH_LIMIT_;
int JVM_STACK_MOVE_UNIT_;
int CONV_OP_IMPLEMENTED_MASK_;
try {
registerNatives();
JVM_SUPPORT_ = true;
JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
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");
} catch (UnsatisfiedLinkError ee) {
// ignore; if we use init() methods later we'll see linkage errors
JVM_SUPPORT_ = false;
JVM_PUSH_LIMIT_ = 3; // arbitrary
JVM_STACK_MOVE_UNIT_ = -1; // arbitrary
CONV_OP_IMPLEMENTED_MASK_ = 0;
//System.out.println("Warning: Running with JVM_SUPPORT=false");
//System.out.println(ee);
JVM_SUPPORT = JVM_SUPPORT_;
......@@ -140,6 +156,9 @@ class MethodHandleNatives {
JVM_SUPPORT = JVM_SUPPORT_;
JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_;
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.
......@@ -149,7 +168,8 @@ class MethodHandleNatives {
// MethodHandleImpl
static final int // for getConstant
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
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)
......@@ -206,9 +226,8 @@ class MethodHandleNatives {
CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1;
/** Which conv-ops are implemented by the JVM? */
static final int CONV_OP_IMPLEMENTED_MASK =
// TODO: The following expression should be replaced by
// a JVM query.
static final int DEFAULT_CONV_OP_IMPLEMENTED_MASK =
// Value to use if the corresponding JVM query fails.
((1<<OP_RETYPE_ONLY)
|(1<<OP_RETYPE_RAW)
|(1<<OP_CHECK_CAST)
......@@ -218,7 +237,7 @@ class MethodHandleNatives {
|(1<<OP_ROT_ARGS)
|(1<<OP_DUP_ARGS)
|(1<<OP_DROP_ARGS)
//|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code.
//|(1<<OP_SPREAD_ARGS)
);
/**
......@@ -239,6 +258,20 @@ class MethodHandleNatives {
//T_ARRAY = 13
T_VOID = 14;
//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);
......@@ -263,4 +296,46 @@ class MethodHandleNatives {
static {
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 {
}
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) {
this.erasedType = erasedType;
......@@ -233,8 +238,10 @@ public class MethodTypeImpl {
return primsAtEnd = t;
// 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
......@@ -273,7 +280,8 @@ public class MethodTypeImpl {
else if (!hasTwoArgSlots(pt)) ord = ifill++;
else ord = lfill++;
if (ord != i) changed = true;
paramOrder[i] = ord;
assert(paramOrder[ord] == 0);
paramOrder[ord] = i;
}
assert(rfill == argc - pac && ifill == argc - lac && lfill == argc);
if (!changed) {
......@@ -292,15 +300,15 @@ public class MethodTypeImpl {
if (newParamOrder == null) return mt; // no-op reordering
Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(mt);
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);
for (int i = 0; i < newParamOrder.length; i++) {
int ord = newParamOrder[i];
if (ord != i) changed = true;
int param = newParamOrder[i];
if (param != i) changed = true;
Class<?> nt;
if (ord < ptypes.length) nt = ptypes[ord];
else if (ord == ordMax) nt = mt.returnType();
else nt = moreParams[ord - ptypes.length];
if (param < ptypes.length) nt = ptypes[param];
else if (param == maxParam) nt = mt.returnType();
else nt = moreParams[param - ptypes.length];
ntypes[i] = nt;
}
if (!changed) return mt;
......
......@@ -25,10 +25,6 @@
/**
* 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
*/
......
......@@ -655,7 +655,7 @@ public class ValueConversions {
if (nargs < ARRAYS.length)
return ARRAYS[nargs];
// 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);
......
......@@ -124,15 +124,15 @@ public abstract class ByteToCharISO2022 extends ByteToCharConverter
switch(shiftFlag) {
case SOFlag:
tmpIndex = curSODes;
tmpConverter = (ByteToCharConverter [])SOConverter;
tmpConverter = SOConverter;
break;
case SS2Flag:
tmpIndex = curSS2Des;
tmpConverter = (ByteToCharConverter [])SS2Converter;
tmpConverter = SS2Converter;
break;
case SS3Flag:
tmpIndex = curSS3Des;
tmpConverter = (ByteToCharConverter [])SS3Converter;
tmpConverter = SS3Converter;
break;
}
......
......@@ -141,7 +141,7 @@ public class ByteToCharISO2022JP extends ByteToCharJIS0208 {
} else {
savedSize = 2;
savedBytes[0] = (byte)byte1;
savedBytes[1] = (byte)input[readOff + inputSize];
savedBytes[1] = input[readOff + inputSize];
inputSize++;
}
break;
......
......@@ -34,14 +34,12 @@ public class ByteToCharJISAutoDetect extends ByteToCharConverter {
private final static int SJIS1B_MASK = 0x04;
private final static int EUCJP_KANA1_MASK = 0x08;
private final static int EUCJP_KANA2_MASK = 0x10;
private static byte[] maskTable1;
private static byte[] maskTable2;
private final static byte[] maskTable1 = JISAutoDetect.getByteMask1();
private final static byte[] maskTable2 = JISAutoDetect.getByteMask2();
private final static int SS2 = 0x8e;
private final static int SS3 = 0x8f;
private final static JISAutoDetect nioCoder = new JISAutoDetect();
// SJISName is set to either "SJIS" or "MS932"
private String SJISName;
private String EUCJPName;
......@@ -57,8 +55,6 @@ public class ByteToCharJISAutoDetect extends ByteToCharConverter {
defaultConv = new ByteToCharISO8859_1();
defaultConv.subChars = subChars;
defaultConv.subMode = subMode;
maskTable1 = nioCoder.getByteMask1();
maskTable2 = nioCoder.getByteMask2();
}
public int flush(char [] output, int outStart, int outEnd)
......@@ -133,7 +129,7 @@ public class ByteToCharJISAutoDetect extends ByteToCharConverter {
break;
}
if ((mask == SJIS2B_MASK) || (mask == SJIS1B_MASK)
|| (nioCoder.canBeSJIS1B(firstmask) && secondmask == 0)) {
|| (JISAutoDetect.canBeSJIS1B(firstmask) && secondmask == 0)) {
convName = SJISName;
break;
}
......@@ -145,15 +141,15 @@ public class ByteToCharJISAutoDetect extends ByteToCharConverter {
// character boundary. If we tried both
// possibilities here, it might be able to be
// determined correctly.
if ((byte1 == SS3) && nioCoder.canBeEUCJP(secondmask)) {
if ((byte1 == SS3) && JISAutoDetect.canBeEUCJP(secondmask)) {
if (cnt+1 < inEnd) {
int nextbyte = input[cnt+1] & 0xff;
if (! nioCoder.canBeEUCJP(maskTable2[nextbyte]))
if (! JISAutoDetect.canBeEUCJP(maskTable2[nextbyte]))
convName = SJISName;
} else
convName = SJISName;
}
if (nioCoder.canBeEUCKana(firstmask, secondmask))
if (JISAutoDetect.canBeEUCKana(firstmask, secondmask))
euckana++;
} else {
if ((firstmask & SJIS1B_MASK) != 0) {
......
......@@ -66,7 +66,7 @@ public class CharToBytePCK extends CharToByteSJIS {
switch (ch) {
case '\u2015':
return (int)0x815C;
return 0x815C;
case '\u2014':
return 0;
default:
......
......@@ -144,11 +144,7 @@ public class ServerSocketAdaptor // package-private
}
public void close() throws IOException {
try {
ssc.close();
} catch (Exception x) {
Net.translateException(x);
}
ssc.close();
}
public ServerSocketChannel getChannel() {
......
......@@ -404,11 +404,7 @@ public class SocketAdaptor
}
public void close() throws IOException {
try {
sc.close();
} catch (Exception x) {
Net.translateToSocketException(x);
}
sc.close();
}
public void shutdownInput() throws IOException {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册