diff --git a/.hgtags b/.hgtags index 36ba8ab267f..3e4fe714491 100644 --- a/.hgtags +++ b/.hgtags @@ -256,3 +256,6 @@ efe7dbc6088691757404e0c8745f894e3ca9c022 jdk9-b09 0809c9a4d36e6291f1c4384604c4bbf29e975722 jdk9-b11 0d1f816217dce5e72187f167cc1816080cbeb453 jdk9-b12 1a30593dcb9802faec3b6edb24d86ca088594e4e jdk9-b13 +97932f6ad950ae5a73a9da5c96e6e58503ff646b jdk9-b14 +74eb0778e4f2dbff6628e718378449fba27c4265 jdk9-b15 +4a09f5d30be844ac6f714bdb0f63d8c3c08b9a98 jdk9-b16 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 3a93d7b6efe..210ff9faef9 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -256,3 +256,6 @@ fa13f2b926f8426876ec03e7903f3ee0ee150f2e jdk9-b10 ab55a18a95e1990a588929d5d29db3eb9985fea0 jdk9-b11 59f6350295f9681fe5956d8bc889bf341914c6cb jdk9-b12 5800456add07e1a68170a229fb5e27376f8875e5 jdk9-b13 +4e3aa9723e9972623e3dafc321b368e7db7e9b3b jdk9-b14 +b114474fb25af4e73cb7219f7c04bd8994da03a5 jdk9-b15 +cf22a728521f91a4692b433d39d730a0a1b23155 jdk9-b16 diff --git a/README b/README index 40c9fbc6a77..e1fdec5d4ab 100644 --- a/README +++ b/README @@ -1,15 +1,15 @@ README: This file should be located at the top of the OpenJDK Mercurial root repository. A full OpenJDK repository set (forest) should also include - the following 6 nested repositories: - "jdk", "hotspot", "langtools", "corba", "jaxws" and "jaxp". + the following 7 nested repositories: + "jdk", "hotspot", "langtools", "nashorn", "corba", "jaxws" and "jaxp". The root repository can be obtained with something like: - hg clone http://hg.openjdk.java.net/jdk8/jdk8 openjdk8 + hg clone http://hg.openjdk.java.net/jdk9/jdk9 openjdk9 You can run the get_source.sh script located in the root repository to get the other needed repositories: - cd openjdk8 && sh ./get_source.sh + cd openjdk9 && sh ./get_source.sh People unfamiliar with Mercurial should read the first few chapters of the Mercurial book: http://hgbook.red-bean.com/read/ @@ -19,9 +19,9 @@ README: Simple Build Instructions: 0. Get the necessary system software/packages installed on your system, see - http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html + http://hg.openjdk.java.net/jdk9/jdk9/raw-file/tip/README-builds.html - 1. If you don't have a jdk7u7 or newer jdk, download and install it from + 1. If you don't have a jdk8 or newer jdk, download and install it from http://java.sun.com/javase/downloads/index.jsp Add the /bin directory of this installation to your PATH environment variable. @@ -37,4 +37,4 @@ where make is GNU make 3.81 or newer, /usr/bin/make on Linux usually is 3.81 or newer. Note that on Solaris, GNU make is called "gmake". Complete details are available in the file: - http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html + http://hg.openjdk.java.net/jdk9/jdk9/raw-file/tip/README-builds.html diff --git a/common/autoconf/configure b/common/autoconf/configure index 636f6e8efdd..b49e03e7fad 100644 --- a/common/autoconf/configure +++ b/common/autoconf/configure @@ -49,7 +49,7 @@ fi ### run_autogen_or_fail() { - if test "x`which autoconf 2> /dev/null`" = x; then + if test "x`which autoconf 2> /dev/null | grep -v '^no autoconf in'`" = x; then echo "Cannot locate autoconf, unable to correct situation." echo "Please install autoconf and run 'bash autogen.sh' to update the generated files." echo "Error: Cannot continue" 1>&2 @@ -80,7 +80,7 @@ check_autoconf_timestamps() { } check_hg_updates() { - if test "x`which hg 2> /dev/null`" != x; then + if test "x`which hg 2> /dev/null | grep -v '^no hg in'`" != x; then conf_updated_autoconf_files=`cd $conf_script_dir && hg status -mard 2> /dev/null | grep autoconf` if test "x$conf_updated_autoconf_files" != x; then echo "Configure source code has been updated, checking time stamps" diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index d36e2e5b486..86905690fb7 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -656,6 +656,9 @@ USE_EXTERNAL_LIBZ USE_EXTERNAL_LIBPNG PNG_LIBS PNG_CFLAGS +USE_EXTERNAL_LCMS +LCMS_LIBS +LCMS_CFLAGS USE_EXTERNAL_LIBGIF USE_EXTERNAL_LIBJPEG ALSA_LIBS @@ -1079,6 +1082,7 @@ with_alsa with_alsa_include with_alsa_lib with_giflib +with_lcms with_libpng with_zlib with_stdc__lib @@ -1192,6 +1196,8 @@ FREETYPE_CFLAGS FREETYPE_LIBS ALSA_CFLAGS ALSA_LIBS +LCMS_CFLAGS +LCMS_LIBS PNG_CFLAGS PNG_LIBS LIBFFI_CFLAGS @@ -1934,6 +1940,8 @@ Optional Packages: --with-alsa-lib specify directory for the alsa library --with-giflib use giflib from build system or OpenJDK source (system, bundled) [bundled] + --with-lcms use lcms2 from build system or OpenJDK source + (system, bundled) [bundled] --with-libpng use libpng from build system or OpenJDK source (system, bundled) [bundled] --with-zlib use zlib from build system or OpenJDK source @@ -2060,6 +2068,8 @@ Some influential environment variables: linker flags for FREETYPE, overriding pkg-config ALSA_CFLAGS C compiler flags for ALSA, overriding pkg-config ALSA_LIBS linker flags for ALSA, overriding pkg-config + LCMS_CFLAGS C compiler flags for LCMS, overriding pkg-config + LCMS_LIBS linker flags for LCMS, overriding pkg-config PNG_CFLAGS C compiler flags for PNG, overriding pkg-config PNG_LIBS linker flags for PNG, overriding pkg-config LIBFFI_CFLAGS @@ -47307,6 +47317,115 @@ fi fi + ############################################################################### + # + # Check for the lcms2 library + # + + +# Check whether --with-lcms was given. +if test "${with_lcms+set}" = set; then : + withval=$with_lcms; +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which lcms to use" >&5 +$as_echo_n "checking for which lcms to use... " >&6; } + + DEFAULT_LCMS=bundled + + # + # If user didn't specify, use DEFAULT_LCMS + # + if test "x${with_lcms}" = "x"; then + with_lcms=${DEFAULT_LCMS} + fi + + if test "x${with_lcms}" = "xbundled"; then + USE_EXTERNAL_LCMS=false + { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5 +$as_echo "bundled" >&6; } + elif test "x${with_lcms}" = "xsystem"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5 +$as_echo "system" >&6; } + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LCMS" >&5 +$as_echo_n "checking for LCMS... " >&6; } + +if test -n "$LCMS_CFLAGS"; then + pkg_cv_LCMS_CFLAGS="$LCMS_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lcms2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lcms2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LCMS_CFLAGS=`$PKG_CONFIG --cflags "lcms2" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LCMS_LIBS"; then + pkg_cv_LCMS_LIBS="$LCMS_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lcms2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lcms2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LCMS_LIBS=`$PKG_CONFIG --libs "lcms2" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LCMS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "lcms2" 2>&1` + else + LCMS_PKG_ERRORS=`$PKG_CONFIG --print-errors "lcms2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LCMS_PKG_ERRORS" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LCMS_FOUND=no +elif test $pkg_failed = untried; then + LCMS_FOUND=no +else + LCMS_CFLAGS=$pkg_cv_LCMS_CFLAGS + LCMS_LIBS=$pkg_cv_LCMS_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LCMS_FOUND=yes +fi + if test "x${LCMS_FOUND}" = "xyes"; then + USE_EXTERNAL_LCMS=true + else + as_fn_error $? "--with-lcms=system specified, but no lcms found!" "$LINENO" 5 + fi + else + as_fn_error $? "Invalid value for --with-lcms: ${with_lcms}, use 'system' or 'bundled'" "$LINENO" 5 + fi + + + ############################################################################### # # Check for the png library diff --git a/common/autoconf/libraries.m4 b/common/autoconf/libraries.m4 index 88bdfe30de3..6ee3221ad96 100644 --- a/common/autoconf/libraries.m4 +++ b/common/autoconf/libraries.m4 @@ -664,6 +664,42 @@ AC_DEFUN_ONCE([LIB_SETUP_MISC_LIBS], fi AC_SUBST(USE_EXTERNAL_LIBGIF) + ############################################################################### + # + # Check for the lcms2 library + # + + AC_ARG_WITH(lcms, [AS_HELP_STRING([--with-lcms], + [use lcms2 from build system or OpenJDK source (system, bundled) @<:@bundled@:>@])]) + + AC_MSG_CHECKING([for which lcms to use]) + + DEFAULT_LCMS=bundled + + # + # If user didn't specify, use DEFAULT_LCMS + # + if test "x${with_lcms}" = "x"; then + with_lcms=${DEFAULT_LCMS} + fi + + if test "x${with_lcms}" = "xbundled"; then + USE_EXTERNAL_LCMS=false + AC_MSG_RESULT([bundled]) + elif test "x${with_lcms}" = "xsystem"; then + AC_MSG_RESULT([system]) + PKG_CHECK_MODULES([LCMS], [lcms2], [LCMS_FOUND=yes], [LCMS_FOUND=no]) + if test "x${LCMS_FOUND}" = "xyes"; then + USE_EXTERNAL_LCMS=true + else + AC_MSG_ERROR([--with-lcms=system specified, but no lcms found!]) + fi + else + AC_MSG_ERROR([Invalid value for --with-lcms: ${with_lcms}, use 'system' or 'bundled']) + fi + + AC_SUBST(USE_EXTERNAL_LCMS) + ############################################################################### # # Check for the png library diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index 47861fcf2b8..2f6d7bd3746 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -652,6 +652,10 @@ INSTALL_SYSCONFDIR=@sysconfdir@ # Libraries # +USE_EXTERNAL_LCMS:=@USE_EXTERNAL_LCMS@ +LCMS_CFLAGS:=@LCMS_CFLAGS@ +LCMS_LIBS:=@LCMS_LIBS@ + USE_EXTERNAL_LIBPNG:=@USE_EXTERNAL_LIBPNG@ PNG_LIBS:=@PNG_LIBS@ PNG_CFLAGS:=@PNG_CFLAGS@ diff --git a/corba/.hgtags b/corba/.hgtags index 18cf4e05c86..a021d932579 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -256,3 +256,6 @@ a4bf701ac316946c2e5e83138ad8e687da6a4b30 jdk9-b06 77ea0a2503582a28e4e66be7239a49a0d1dd313f jdk9-b11 e212cdcc8c11f0ba5acf6f5ddb596c4c545a93f9 jdk9-b12 088eec4c36f4d7f250fcd19c4969bf698e3d2cdc jdk9-b13 +a2b82f863ba95a596da555a4c1b871c404863e7e jdk9-b14 +e54022d0dd92106fff7f7fe670010cd7e6517ee3 jdk9-b15 +422ef9d29d84f571453f015c4cb8713c3af70ee4 jdk9-b16 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 97ea5ccc8bc..43e10fc2ccd 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -416,3 +416,6 @@ ebc44d040cd149d2120d69fe183a3dae7840f4b4 jdk9-b10 783309c3a1a629a452673399dcfa83ef7eca94d8 jdk9-b11 1c383bb39e2849ca62cb763f4e182a29b421d60a jdk9-b12 456ad9c99133803d4e1433124c85a6fd141b9ac9 jdk9-b13 +bd333491bb6c012d7b606939406d0fa9a5ac7ffd jdk9-b14 +170f6d733d7aec062f743a6b8c1cce940a7a984a jdk9-b15 +b14e7c0b7d3ec04127f565cda1d84122e205680c jdk9-b16 diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java index c0db13d1365..ca4b2f5aa34 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java @@ -64,7 +64,11 @@ public class ciEnv extends VMObject { } public Compile compilerData() { - return new Compile(compilerDataField.getValue(this.getAddress())); + Address addr = compilerDataField.getValue(this.getAddress()); + if (addr == null) { + return null; + } + return new Compile(addr); } public ciObjectFactory factory() { @@ -94,10 +98,7 @@ public class ciEnv extends VMObject { Method method = task.method(); int entryBci = task.osrBci(); int compLevel = task.compLevel(); - Klass holder = method.getMethodHolder(); - out.print("compile " + holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + + out.print("compile " + method.nameAsAscii() + " " + entryBci + " " + compLevel); Compile compiler = compilerData(); if (compiler != null) { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java index aba64a5015e..2e03c5481aa 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java @@ -55,4 +55,9 @@ public class ciKlass extends ciType { public ciKlass(Address addr) { super(addr); } + + public void printValueOn(PrintStream tty) { + Klass k = (Klass)getMetadata(); + k.printValueOn(tty); + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java index cdf21c946ac..ac972e97ce6 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java @@ -90,17 +90,23 @@ public class ciMethod extends ciMetadata { } public void dumpReplayData(PrintStream out) { - Method method = (Method)getMetadata(); - NMethod nm = method.getNativeMethod(); - Klass holder = method.getMethodHolder(); - out.println("ciMethod " + - holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + - method.getInvocationCount() + " " + - method.getBackedgeCount() + " " + - interpreterInvocationCount() + " " + - interpreterThrowoutCount() + " " + - instructionsSize()); + Method method = (Method)getMetadata(); + NMethod nm = method.getNativeMethod(); + out.println("ciMethod " + + nameAsAscii() + " " + + method.getInvocationCount() + " " + + method.getBackedgeCount() + " " + + interpreterInvocationCount() + " " + + interpreterThrowoutCount() + " " + + instructionsSize()); + } + + public void printValueOn(PrintStream tty) { + tty.print("ciMethod " + method().getName().asString() + method().getSignature().asString() + "@" + getAddress()); + } + + public String nameAsAscii() { + Method method = (Method)getMetadata(); + return method.nameAsAscii(); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java index 117a9488cf7..13ad04a9d30 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java @@ -31,7 +31,7 @@ import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; -public class ciMethodData extends ciMetadata { +public class ciMethodData extends ciMetadata implements MethodDataInterface { static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { @@ -54,7 +54,9 @@ public class ciMethodData extends ciMetadata { extraDataSizeField = new CIntField(type.getCIntegerField("_extra_data_size"), 0); dataSizeField = new CIntField(type.getCIntegerField("_data_size"), 0); stateField = new CIntField(type.getCIntegerField("_state"), 0); - sizeofMethodDataOopDesc = (int)db.lookupType("MethodData").getSize();; + Type typeMethodData = db.lookupType("MethodData"); + sizeofMethodDataOopDesc = (int)typeMethodData.getSize(); + parametersTypeDataDi = new CIntField(typeMethodData.getCIntegerField("_parameters_type_data_di"), 0); } private static AddressField origField; @@ -69,11 +71,28 @@ public class ciMethodData extends ciMetadata { private static CIntField dataSizeField; private static CIntField stateField; private static int sizeofMethodDataOopDesc; + private static CIntField parametersTypeDataDi; public ciMethodData(Address addr) { super(addr); } + public ciKlass getKlassAtAddress(Address addr) { + return (ciKlass)ciObjectFactory.getMetadata(addr); + } + + public ciMethod getMethodAtAddress(Address addr) { + return (ciMethod)ciObjectFactory.getMetadata(addr); + } + + public void printKlassValueOn(ciKlass klass, PrintStream st) { + klass.printValueOn(st); + } + + public void printMethodValueOn(ciMethod method, PrintStream st) { + method.printValueOn(st); + } + private byte[] fetchDataAt(Address base, long size) { byte[] result = new byte[(int)size]; for (int i = 0; i < size; i++) { @@ -110,6 +129,10 @@ public class ciMethodData extends ciMetadata { return (int)dataSizeField.getValue(getAddress()); } + int extraDataSize() { + return (int)extraDataSizeField.getValue(getAddress()); + } + int state() { return (int)stateField.getValue(getAddress()); } @@ -122,6 +145,16 @@ public class ciMethodData extends ciMetadata { return dataIndex >= dataSize(); } + ParametersTypeData parametersTypeData() { + Address base = getAddress().addOffsetTo(origField.getOffset()); + int di = (int)parametersTypeDataDi.getValue(base); + if (di == -1) { + return null; + } + DataLayout dataLayout = new DataLayout(dataField.getValue(getAddress()), di); + return new ParametersTypeData(this, dataLayout); + } + ProfileData dataAt(int dataIndex) { if (outOfBounds(dataIndex)) { return null; @@ -139,15 +172,21 @@ public class ciMethodData extends ciMetadata { case DataLayout.jumpDataTag: return new JumpData(dataLayout); case DataLayout.receiverTypeDataTag: - return new ciReceiverTypeData(dataLayout); + return new ReceiverTypeData(this, dataLayout); case DataLayout.virtualCallDataTag: - return new ciVirtualCallData(dataLayout); + return new VirtualCallData(this, dataLayout); case DataLayout.retDataTag: return new RetData(dataLayout); case DataLayout.branchDataTag: return new BranchData(dataLayout); case DataLayout.multiBranchDataTag: return new MultiBranchData(dataLayout); + case DataLayout.callTypeDataTag: + return new CallTypeData(this, dataLayout); + case DataLayout.virtualCallTypeDataTag: + return new VirtualCallTypeData(this, dataLayout); + case DataLayout.parametersTypeDataTag: + return new ParametersTypeData(this, dataLayout); } } @@ -164,7 +203,23 @@ public class ciMethodData extends ciMetadata { } boolean isValid(ProfileData current) { return current != null; } + DataLayout limitDataPosition() { + return new DataLayout(dataField.getValue(getAddress()), dataSize()); + } + DataLayout extraDataBase() { + return limitDataPosition(); + } + DataLayout extraDataLimit() { + return new DataLayout(dataField.getValue(getAddress()), dataSize() + extraDataSize()); + } + DataLayout nextExtra(DataLayout dataLayout) { + return new DataLayout(dataField.getValue(getAddress()), dataLayout.dp() + DataLayout.computeSizeInBytes(MethodData.extraNbCells(dataLayout))); + } + public void printDataOn(PrintStream st) { + if (parametersTypeData() != null) { + parametersTypeData().printDataOn(st); + } ProfileData data = firstData(); for ( ; isValid(data); data = nextData(data)) { st.print(dpToDi(data.dp())); @@ -172,16 +227,96 @@ public class ciMethodData extends ciMetadata { // st->fillTo(6); data.printDataOn(st); } + st.println("--- Extra data:"); + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + for (;; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + continue; + case DataLayout.bitDataTag: + data = new BitData(dp); + break; + case DataLayout.speculativeTrapDataTag: + data = new SpeculativeTrapData(this, dp); + break; + case DataLayout.argInfoDataTag: + data = new ArgInfoData(dp); + dp = end; // ArgInfoData is at the end of extra data section. + break; + default: + throw new InternalError("unexpected tag " + dp.tag()); + } + st.print(dpToDi(data.dp())); + st.print(" "); + data.printDataOn(st); + if (dp == end) return; + } + } + + int dumpReplayDataTypeHelper(PrintStream out, int round, int count, int index, ProfileData pdata, ciKlass k) { + if (k != null) { + if (round == 0) count++; + else out.print(" " + ((pdata.dp() + pdata.cellOffset(index)) / MethodData.cellSize) + " " + k.name()); + } + return count; + } + + int dumpReplayDataReceiverTypeHelper(PrintStream out, int round, int count, ReceiverTypeData vdata) { + for (int i = 0; i < vdata.rowLimit(); i++) { + ciKlass k = vdata.receiver(i); + count = dumpReplayDataTypeHelper(out, round, count, vdata.receiverCellIndex(i), vdata, k); + } + return count; + } + + int dumpReplayDataCallTypeHelper(PrintStream out, int round, int count, CallTypeDataInterface callTypeData) { + if (callTypeData.hasArguments()) { + for (int i = 0; i < callTypeData.numberOfArguments(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.argumentTypeIndex(i), (ProfileData)callTypeData, callTypeData.argumentType(i)); + } + } + if (callTypeData.hasReturn()) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.returnTypeIndex(), (ProfileData)callTypeData, callTypeData.returnType()); + } + return count; + } + + int dumpReplayDataExtraDataHelper(PrintStream out, int round, int count) { + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + + for (;dp != end; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + case DataLayout.argInfoDataTag: + return count; + case DataLayout.bitDataTag: + break; + case DataLayout.speculativeTrapDataTag: { + SpeculativeTrapData data = new SpeculativeTrapData(this, dp); + ciMethod m = data.method(); + if (m != null) { + if (round == 0) { + count++; + } else { + out.print(" " + (dpToDi(data.dp() + data.cellOffset(SpeculativeTrapData.methodIndex())) / MethodData.cellSize) + " " + m.nameAsAscii()); + } + } + break; + } + default: + throw new InternalError("bad tag " + dp.tag()); + } + } + return count; } public void dumpReplayData(PrintStream out) { MethodData mdo = (MethodData)getMetadata(); Method method = mdo.getMethod(); - Klass holder = method.getMethodHolder(); out.print("ciMethodData " + - holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + + method.nameAsAscii() + " " + state() + " " + currentMileage()); byte[] orig = orig(); out.print(" orig " + orig.length); @@ -195,30 +330,28 @@ public class ciMethodData extends ciMetadata { out.print(" 0x" + Long.toHexString(data[i])); } int count = 0; + ParametersTypeData parameters = parametersTypeData(); for (int round = 0; round < 2; round++) { if (round == 1) out.print(" oops " + count); ProfileData pdata = firstData(); for ( ; isValid(pdata); pdata = nextData(pdata)) { - if (pdata instanceof ciReceiverTypeData) { - ciReceiverTypeData vdata = (ciReceiverTypeData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - ciKlass k = vdata.receiverAt(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize) + " " + k.name()); - } - } - } else if (pdata instanceof ciVirtualCallData) { - ciVirtualCallData vdata = (ciVirtualCallData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - ciKlass k = vdata.receiverAt(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize + " " + k.name())); - } - } + if (pdata instanceof ReceiverTypeData) { + count = dumpReplayDataReceiverTypeHelper(out, round, count, (ReceiverTypeData)pdata); + } + if (pdata instanceof CallTypeDataInterface) { + count = dumpReplayDataCallTypeHelper(out, round, count, (CallTypeDataInterface)pdata); } } + if (parameters != null) { + for (int i = 0; i < parameters.numberOfParameters(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, ParametersTypeData.typeIndex(i), parameters, parameters.type(i)); + } + } + } + count = 0; + for (int round = 0; round < 2; round++) { + if (round == 1) out.print(" methods " + count); + count = dumpReplayDataExtraDataHelper(out, round, count); } out.println(); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArgInfoData.java similarity index 62% rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArgInfoData.java index 231ab844e3e..992d86a02ec 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArgInfoData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,31 +22,35 @@ * */ -package sun.jvm.hotspot.ci; +package sun.jvm.hotspot.oops; import java.io.*; import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; -public class ciVirtualCallData extends VirtualCallData { - public ciVirtualCallData(DataLayout data) { - super(data); +public class ArgInfoData extends ArrayData { + + public ArgInfoData(DataLayout layout) { + super(layout); } - public Klass receiver(int row) { - throw new InternalError("should not call"); + int numberOfArgs() { + return arrayLen(); } - public ciKlass receiverAt(int row) { - //assert((uint)row < rowLimit(), "oob"); - ciMetadata recv = ciObjectFactory.getMetadata(addressAt(receiverCellIndex(row))); - if (recv != null && !(recv instanceof ciKlass)) { - System.err.println(recv); + int argModified(int arg) { + return arrayUintAt(arg); + } + + public void printDataOn(PrintStream st) { + printShared(st, "ArgInfoData"); + int nargs = numberOfArgs(); + for (int i = 0; i < nargs; i++) { + st.print(" 0x" + Integer.toHexString(argModified(i))); } - //assert(recv == NULL || recv->isKlass(), "wrong type"); - return (ciKlass)recv; + st.println(); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java new file mode 100644 index 00000000000..a0eb02946b3 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeData.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// CallTypeData +// +// A CallTypeData is used to access profiling information about a non +// virtual call for which we collect type information about arguments +// and return value. +public class CallTypeData extends CounterData implements CallTypeDataInterface { + final TypeStackSlotEntries args; + final ReturnTypeEntry ret; + + int cellCountGlobalOffset() { + return CounterData.staticCellCount() + TypeEntriesAtCall.cellCountLocalOffset(); + } + + int cellCountNoHeader() { + return uintAt(cellCountGlobalOffset()); + } + + public CallTypeData(MethodDataInterface methodData, DataLayout layout) { + super(layout); + args = new TypeStackSlotEntries(methodData, this, CounterData.staticCellCount()+TypeEntriesAtCall.headerCellCount(), numberOfArguments()); + ret = new ReturnTypeEntry(methodData, this, cellCount() - ReturnTypeEntry.staticCellCount()); + } + + static int staticCellCount() { + return -1; + } + + public int cellCount() { + return CounterData.staticCellCount() + + TypeEntriesAtCall.headerCellCount() + + intAt(cellCountGlobalOffset()); + } + + public int numberOfArguments() { + return cellCountNoHeader() / TypeStackSlotEntries.perArgCount(); + } + + public boolean hasArguments() { + return cellCountNoHeader() >= TypeStackSlotEntries.perArgCount(); + } + + public K argumentType(int i) { + return args.type(i); + } + + public boolean hasReturn() { + return (cellCountNoHeader() % TypeStackSlotEntries.perArgCount()) != 0; + } + + public K returnType() { + return ret.type(); + } + + public int argumentTypeIndex(int i) { + return args.typeIndex(i); + } + + public int returnTypeIndex() { + return ret.typeIndex(); + } + + public void printDataOn(PrintStream st) { + super.printDataOn(st); + if (hasArguments()) { + tab(st); + st.print("argument types"); + args.printDataOn(st); + } + if (hasReturn()) { + tab(st); + st.print("return type"); + ret.printDataOn(st); + } + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java new file mode 100644 index 00000000000..0a8bf4721e4 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CallTypeDataInterface.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +public interface CallTypeDataInterface { + int numberOfArguments(); + boolean hasArguments(); + K argumentType(int i); + boolean hasReturn(); + K returnType(); + int argumentTypeIndex(int i); + int returnTypeIndex(); +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java index d9348507a96..4c992f176a8 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java @@ -41,6 +41,11 @@ public class DataLayout { public static final int retDataTag = 6; public static final int branchDataTag = 7; public static final int multiBranchDataTag = 8; + public static final int argInfoDataTag = 9; + public static final int callTypeDataTag = 10; + public static final int virtualCallTypeDataTag = 11; + public static final int parametersTypeDataTag = 12; + public static final int speculativeTrapDataTag = 13; // The _struct._flags word is formatted as [trapState:4 | flags:4]. // The trap state breaks down further as [recompile:1 | reason:3]. @@ -61,8 +66,6 @@ public class DataLayout { private int offset; - private boolean handlized; - public DataLayout(MethodData d, int o) { data = d.getAddress(); offset = o; @@ -71,7 +74,6 @@ public class DataLayout { public DataLayout(Address d, int o) { data = d; offset = o; - handlized = true; } public int dp() { return offset; } @@ -90,12 +92,7 @@ public class DataLayout { } public Address addressAt(int index) { - OopHandle handle; - if (handlized) { - return data.getAddressAt(offset + cellOffset(index)); - } else { - return data.getOopHandleAt(offset + cellOffset(index)); - } + return data.getAddressAt(offset + cellOffset(index)); } // Every data layout begins with a header. This header @@ -128,7 +125,7 @@ public class DataLayout { return 1; } - static int computeSizeInBytes(int cellCount) { + static public int computeSizeInBytes(int cellCount) { return headerSizeInBytes() + cellCount * MethodData.cellSize; } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java index e039470f801..2bde98074ff 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java @@ -354,9 +354,7 @@ public class Method extends Metadata { } Klass holder = getMethodHolder(); out.println("ciMethod " + - holder.getName().asString() + " " + - OopUtilities.escapeString(getName().asString()) + " " + - getSignature().asString() + " " + + nameAsAscii() + " " + getInvocationCount() + " " + getBackedgeCount() + " " + interpreterInvocationCount() + " " + @@ -371,4 +369,10 @@ public class Method extends Metadata { public int interpreterInvocationCount() { return getMethodCounters().interpreterInvocationCount(); } + + public String nameAsAscii() { + return getMethodHolder().getName().asString() + " " + + OopUtilities.escapeString(getName().asString()) + " " + + getSignature().asString(); + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java index 41c121468ea..f07b8268873 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java @@ -33,7 +33,7 @@ import sun.jvm.hotspot.utilities.*; // A MethodData provides interpreter profiling information -public class MethodData extends Metadata { +public class MethodData extends Metadata implements MethodDataInterface { static int TypeProfileWidth = 2; static int BciProfileWidth = 2; static int CompileThreshold; @@ -152,6 +152,8 @@ public class MethodData extends Metadata { dataSize = new CIntField(type.getCIntegerField("_data_size"), 0); data = type.getAddressField("_data[0]"); + parametersTypeDataDi = new CIntField(type.getCIntegerField("_parameters_type_data_di"), 0); + sizeofMethodDataOopDesc = (int)type.getSize();; Reason_many = db.lookupIntConstant("Deoptimization::Reason_many").intValue(); @@ -191,6 +193,22 @@ public class MethodData extends Metadata { super(addr); } + public Klass getKlassAtAddress(Address addr) { + return (Klass)Metadata.instantiateWrapperFor(addr); + } + + public Method getMethodAtAddress(Address addr) { + return (Method)Metadata.instantiateWrapperFor(addr); + } + + public void printKlassValueOn(Klass klass, PrintStream st) { + klass.printValueOn(st); + } + + public void printMethodValueOn(Method method, PrintStream st) { + method.printValueOn(st); + } + public boolean isMethodData() { return true; } private static long baseOffset; @@ -198,7 +216,7 @@ public class MethodData extends Metadata { private static MetadataField method; private static CIntField dataSize; private static AddressField data; - + private static CIntField parametersTypeDataDi; public static int sizeofMethodDataOopDesc; public static int cellSize; @@ -225,6 +243,27 @@ public class MethodData extends Metadata { } } + int sizeInBytes() { + if (size == null) { + return 0; + } else { + return (int)size.getValue(getAddress()); + } + } + + int size() { + return (int)Oop.alignObjectSize(VM.getVM().alignUp(sizeInBytes(), VM.getVM().getBytesPerWord())/VM.getVM().getBytesPerWord()); + } + + ParametersTypeData parametersTypeData() { + int di = (int)parametersTypeDataDi.getValue(getAddress()); + if (di == -1) { + return null; + } + DataLayout dataLayout = new DataLayout(this, di + (int)data.getOffset()); + return new ParametersTypeData(this, dataLayout); + } + boolean outOfBounds(int dataIndex) { return dataIndex >= dataSize(); } @@ -246,15 +285,21 @@ public class MethodData extends Metadata { case DataLayout.jumpDataTag: return new JumpData(dataLayout); case DataLayout.receiverTypeDataTag: - return new ReceiverTypeData(dataLayout); + return new ReceiverTypeData(this, dataLayout); case DataLayout.virtualCallDataTag: - return new VirtualCallData(dataLayout); + return new VirtualCallData(this, dataLayout); case DataLayout.retDataTag: return new RetData(dataLayout); case DataLayout.branchDataTag: return new BranchData(dataLayout); case DataLayout.multiBranchDataTag: return new MultiBranchData(dataLayout); + case DataLayout.callTypeDataTag: + return new CallTypeData(this, dataLayout); + case DataLayout.virtualCallTypeDataTag: + return new VirtualCallTypeData(this, dataLayout); + case DataLayout.parametersTypeDataTag: + return new ParametersTypeData(this, dataLayout); } } @@ -272,7 +317,42 @@ public class MethodData extends Metadata { } boolean isValid(ProfileData current) { return current != null; } + DataLayout limitDataPosition() { + return new DataLayout(this, dataSize() + (int)data.getOffset()); + } + + DataLayout extraDataBase() { + return limitDataPosition(); + } + + DataLayout extraDataLimit() { + return new DataLayout(this, sizeInBytes()); + } + + static public int extraNbCells(DataLayout dataLayout) { + int nbCells = 0; + switch(dataLayout.tag()) { + case DataLayout.bitDataTag: + case DataLayout.noTag: + nbCells = BitData.staticCellCount(); + break; + case DataLayout.speculativeTrapDataTag: + nbCells = SpeculativeTrapData.staticCellCount(); + break; + default: + throw new InternalError("unexpected tag " + dataLayout.tag()); + } + return nbCells; + } + + DataLayout nextExtra(DataLayout dataLayout) { + return new DataLayout(this, dataLayout.dp() + DataLayout.computeSizeInBytes(extraNbCells(dataLayout))); + } + public void printDataOn(PrintStream st) { + if (parametersTypeData() != null) { + parametersTypeData().printDataOn(st); + } ProfileData data = firstData(); for ( ; isValid(data); data = nextData(data)) { st.print(dpToDi(data.dp())); @@ -280,6 +360,31 @@ public class MethodData extends Metadata { // st->fillTo(6); data.printDataOn(st); } + st.println("--- Extra data:"); + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + for (;; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + continue; + case DataLayout.bitDataTag: + data = new BitData(dp); + break; + case DataLayout.speculativeTrapDataTag: + data = new SpeculativeTrapData(this, dp); + break; + case DataLayout.argInfoDataTag: + data = new ArgInfoData(dp); + dp = end; // ArgInfoData is at the end of extra data section. + break; + default: + throw new InternalError("unexpected tag " + dp.tag()); + } + st.print(dpToDi(data.dp())); + st.print(" "); + data.printDataOn(st); + if (dp == end) return; + } } private byte[] fetchDataAt(Address base, long offset, long size) { @@ -332,14 +437,71 @@ public class MethodData extends Metadata { return 20000; } + int dumpReplayDataTypeHelper(PrintStream out, int round, int count, int index, ProfileData pdata, Klass k) { + if (k != null) { + if (round == 0) count++; + else out.print(" " + + (dpToDi(pdata.dp() + + pdata.cellOffset(index)) / cellSize) + " " + + k.getName().asString()); + } + return count; + } + + int dumpReplayDataReceiverTypeHelper(PrintStream out, int round, int count, ReceiverTypeData vdata) { + for (int i = 0; i < vdata.rowLimit(); i++) { + Klass k = vdata.receiver(i); + count = dumpReplayDataTypeHelper(out, round, count, vdata.receiverCellIndex(i), vdata, k); + } + return count; + } + + int dumpReplayDataCallTypeHelper(PrintStream out, int round, int count, CallTypeDataInterface callTypeData) { + if (callTypeData.hasArguments()) { + for (int i = 0; i < callTypeData.numberOfArguments(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.argumentTypeIndex(i), (ProfileData)callTypeData, callTypeData.argumentType(i)); + } + } + if (callTypeData.hasReturn()) { + count = dumpReplayDataTypeHelper(out, round, count, callTypeData.returnTypeIndex(), (ProfileData)callTypeData, callTypeData.returnType()); + } + return count; + } + + int dumpReplayDataExtraDataHelper(PrintStream out, int round, int count) { + DataLayout dp = extraDataBase(); + DataLayout end = extraDataLimit(); + + for (;dp != end; dp = nextExtra(dp)) { + switch(dp.tag()) { + case DataLayout.noTag: + case DataLayout.argInfoDataTag: + return count; + case DataLayout.bitDataTag: + break; + case DataLayout.speculativeTrapDataTag: { + SpeculativeTrapData data = new SpeculativeTrapData(this, dp); + Method m = data.method(); + if (m != null) { + if (round == 0) { + count++; + } else { + out.print(" " + (dpToDi(data.dp() + data.cellOffset(SpeculativeTrapData.methodIndex())) / cellSize) + " " + m.nameAsAscii()); + } + } + break; + } + default: + throw new InternalError("bad tag " + dp.tag()); + } + } + return count; + } + public void dumpReplayData(PrintStream out) { Method method = getMethod(); - Klass holder = method.getMethodHolder(); - out.print("ciMethodData " + - holder.getName().asString() + " " + - OopUtilities.escapeString(method.getName().asString()) + " " + - method.getSignature().asString() + " " + - "2" + " " + + out.print("ciMethodData " + method.nameAsAscii() + + " " + "2" + " " + currentMileage()); byte[] orig = orig(); out.print(" orig " + orig.length); @@ -353,36 +515,28 @@ public class MethodData extends Metadata { out.print(" 0x" + Long.toHexString(data[i])); } int count = 0; + ParametersTypeData parameters = parametersTypeData(); for (int round = 0; round < 2; round++) { if (round == 1) out.print(" oops " + count); ProfileData pdata = firstData(); for ( ; isValid(pdata); pdata = nextData(pdata)) { if (pdata instanceof ReceiverTypeData) { - ReceiverTypeData vdata = (ReceiverTypeData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - Klass k = vdata.receiver(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + - (dpToDi(vdata.dp() + - vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " + - k.getName().asString()); - } - } - } else if (pdata instanceof VirtualCallData) { - VirtualCallData vdata = (VirtualCallData)pdata; - for (int i = 0; i < vdata.rowLimit(); i++) { - Klass k = vdata.receiver(i); - if (k != null) { - if (round == 0) count++; - else out.print(" " + - (dpToDi(vdata.dp() + - vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " + - k.getName().asString()); - } - } + count = dumpReplayDataReceiverTypeHelper(out, round, count, (ReceiverTypeData)pdata); + } + if (pdata instanceof CallTypeDataInterface) { + count = dumpReplayDataCallTypeHelper(out, round, count, (CallTypeDataInterface)pdata); } } + if (parameters != null) { + for (int i = 0; i < parameters.numberOfParameters(); i++) { + count = dumpReplayDataTypeHelper(out, round, count, ParametersTypeData.typeIndex(i), parameters, parameters.type(i)); + } + } + } + count = 0; + for (int round = 0; round < 2; round++) { + if (round == 1) out.print(" methods " + count); + count = dumpReplayDataExtraDataHelper(out, round, count); } out.println(); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java new file mode 100644 index 00000000000..8e6b131ee9d --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodDataInterface.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +public interface MethodDataInterface { + K getKlassAtAddress(Address addr); + M getMethodAtAddress(Address addr); + void printKlassValueOn(K klass, PrintStream st); + void printMethodValueOn(M klass, PrintStream st); +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java new file mode 100644 index 00000000000..d1a1fea6914 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ParametersTypeData.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// ParametersTypeData +// +// A ParametersTypeData is used to access profiling information about +// types of parameters to a method +public class ParametersTypeData extends ArrayData { + final TypeStackSlotEntries parameters; + + static int stackSlotLocalOffset(int i) { + return arrayStartOffSet + TypeStackSlotEntries.stackSlotLocalOffset(i); + } + + static int typeLocalOffset(int i) { + return arrayStartOffSet + TypeStackSlotEntries.typeLocalOffset(i); + } + + public ParametersTypeData(MethodDataInterface methodData, DataLayout layout) { + super(layout); + parameters = new TypeStackSlotEntries(methodData, this, 1, numberOfParameters()); + } + + public int numberOfParameters() { + return arrayLen() / TypeStackSlotEntries.perArgCount(); + } + + int stackSlot(int i) { + return parameters.stackSlot(i); + } + + public K type(int i) { + return parameters.type(i); + } + + static public int typeIndex(int i) { + return typeLocalOffset(i); + } + + public void printDataOn(PrintStream st) { + st.print("parameter types"); + parameters.printDataOn(st); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java index 155035eea18..7ac053fe0c5 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java @@ -37,13 +37,15 @@ import sun.jvm.hotspot.utilities.*; // dynamic type check. It consists of a counter which counts the total times // that the check is reached, and a series of (Klass, count) pairs // which are used to store a type profile for the receiver of the check. -public class ReceiverTypeData extends CounterData { +public class ReceiverTypeData extends CounterData { static final int receiver0Offset = counterCellCount; static final int count0Offset = receiver0Offset + 1; static final int receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset; + final MethodDataInterface methodData; - public ReceiverTypeData(DataLayout layout) { + public ReceiverTypeData(MethodDataInterface methodData, DataLayout layout) { super(layout); + this.methodData = methodData; //assert(layout.tag() == DataLayout.receiverTypeDataTag || // layout.tag() == DataLayout.virtualCallDataTag, "wrong type"); } @@ -73,14 +75,14 @@ public class ReceiverTypeData extends CounterData { // gc; it does not assert the receiver is a klass. During compaction of the // perm gen, the klass may already have moved, so the isKlass() predicate // would fail. The 'normal' version should be used whenever possible. - Klass receiverUnchecked(int row) { + K receiverUnchecked(int row) { //assert(row < rowLimit(), "oob"); Address recv = addressAt(receiverCellIndex(row)); - return (Klass)Metadata.instantiateWrapperFor(recv); + return methodData.getKlassAtAddress(recv); } - public Klass receiver(int row) { - Klass recv = receiverUnchecked(row); + public K receiver(int row) { + K recv = receiverUnchecked(row); //assert(recv == NULL || ((oop)recv).isKlass(), "wrong type"); return recv; } @@ -111,7 +113,7 @@ public class ReceiverTypeData extends CounterData { for (row = 0; row < rowLimit(); row++) { if (receiver(row) != null) { tab(st); - receiver(row).printValueOn(st); + methodData.printKlassValueOn(receiver(row), st); st.println("(" + receiverCount(row) + ")"); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReturnTypeEntry.java similarity index 62% rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReturnTypeEntry.java index e568b3f7cec..667e4cd4a94 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReturnTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,32 +22,39 @@ * */ -package sun.jvm.hotspot.ci; +package sun.jvm.hotspot.oops; import java.io.*; import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; -public class ciReceiverTypeData extends ReceiverTypeData { - public ciReceiverTypeData(DataLayout data) { - super(data); +// Type entry used for return from a call. A single cell to record the +// type. +public class ReturnTypeEntry extends TypeEntries { + static final int cellCount = 1; + + ReturnTypeEntry(MethodDataInterface methodData, ProfileData pd, int baseOff) { + super(methodData, pd, baseOff); } - public Klass receiver(int row) { - throw new InternalError("should not call"); + K type() { + return validKlass(baseOff); } - public ciKlass receiverAt(int row) { - //assert((uint)row < rowLimit(), "oob"); - ciMetadata recv = ciObjectFactory.getMetadata(addressAt(receiverCellIndex(row))); - if (recv != null && !(recv instanceof ciKlass)) { - System.err.println(recv); - } - //assert(recv == NULL || recv->isKlass(), "wrong type"); - return (ciKlass)recv; + static int staticCellCount() { + return cellCount; } + int typeIndex() { + return baseOff; + } + + void printDataOn(PrintStream st) { + pd.tab(st); + printKlass(st, baseOff); + st.println(); + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java new file mode 100644 index 00000000000..16a33f932b9 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/SpeculativeTrapData.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// SpeculativeTrapData +// +// A SpeculativeTrapData is used to record traps due to type +// speculation. It records the root of the compilation. +public class SpeculativeTrapData extends ProfileData { + static final int speculativeTrapMethod = 0; + static final int speculativeTrapCellCount = 1; + final MethodDataInterface methodData; + + public SpeculativeTrapData(MethodDataInterface methodData, DataLayout layout) { + super(layout); + this.methodData = methodData; + } + + static int staticCellCount() { + return speculativeTrapCellCount; + } + + public int cellCount() { + return staticCellCount(); + } + + public M method() { + return methodData.getMethodAtAddress(addressAt(speculativeTrapMethod)); + } + + static public int methodIndex() { + return speculativeTrapMethod; + } + + public void printDataOn(PrintStream st) { + printShared(st, "SpeculativeTrapData"); + tab(st); + methodData.printMethodValueOn(method(), st); + st.println(); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java new file mode 100644 index 00000000000..8b791b5f938 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntries.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// Entries in a ProfileData object to record types: it can either be +// none (no profile), unknown (conflicting profile data) or a klass if +// a single one is seen. Whether a null reference was seen is also +// recorded. No counter is associated with the type and a single type +// is tracked (unlike VirtualCallData). +public abstract class TypeEntries { + static final int nullSeen = 1; + static final int typeMask = ~nullSeen; + static final int typeUnknown = 2; + static final int statusBits = nullSeen | typeUnknown; + static final int typeKlassMask = ~statusBits; + + final ProfileData pd; + final int baseOff; + final MethodDataInterface methodData; + + boolean wasNullSeen(int index) { + int v = pd.intptrAt(index); + return (v & nullSeen) != 0; + } + + boolean isTypeUnknown(int index) { + int v = pd.intptrAt(index); + return (v & typeUnknown) != 0; + } + + boolean isTypeNone(int index) { + int v = pd.intptrAt(index); + return (v & typeMask) == 0; + } + + K validKlass(int index) { + if (!isTypeNone(index) && + !isTypeUnknown(index)) { + return methodData.getKlassAtAddress(pd.addressAt(index).andWithMask(typeKlassMask)); + } else { + return null; + } + } + + void printKlass(PrintStream st, int index) { + if (isTypeNone(index)) { + st.print("none"); + } else if (isTypeUnknown(index)) { + st.print("unknown"); + } else { + methodData.printKlassValueOn(validKlass(index), st); + } + if (wasNullSeen(index)) { + st.print(" (null seen)"); + } + } + + TypeEntries(MethodDataInterface methodData, ProfileData pd, int baseOff) { + this.pd = pd; + this.baseOff = baseOff; + this.methodData = methodData; + } + + long intptrAt(int index) { + return pd.intptrAt(index); + } + +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java new file mode 100644 index 00000000000..2891f91c69e --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeEntriesAtCall.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// Entries to collect type information at a call: contains arguments +// (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a +// number of cells. +public abstract class TypeEntriesAtCall { + + static int stackSlotLocalOffset(int i) { + return headerCellCount() + TypeStackSlotEntries.stackSlotLocalOffset(i); + } + + static int argumentTypeLocalOffset(int i) { + return headerCellCount() + TypeStackSlotEntries.typeLocalOffset(i); + } + + static int headerCellCount() { + return 1; + } + + static int cellCountLocalOffset() { + return 0; + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java new file mode 100644 index 00000000000..9efff34a4c3 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/TypeStackSlotEntries.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// Type entries used for arguments passed at a call and parameters on +// method entry. 2 cells per entry: one for the type encoded as in +// TypeEntries and one initialized with the stack slot where the +// profiled object is to be found so that the interpreter can locate +// it quickly. +public class TypeStackSlotEntries extends TypeEntries { + static final int stackSlotEntry = 0; + static final int typeEntry = 1; + static final int perArgCellCount = 2; + + int stackSlotOffset(int i) { + return baseOff + stackSlotLocalOffset(i); + } + + final int numberOfEntries; + + int typeOffsetInCells(int i) { + return baseOff + typeLocalOffset(i); + } + + TypeStackSlotEntries(MethodDataInterface methodData, ProfileData pd, int baseOff, int nbEntries) { + super(methodData, pd, baseOff); + numberOfEntries = nbEntries; + } + + static int stackSlotLocalOffset(int i) { + return i * perArgCellCount + stackSlotEntry; + } + + static int typeLocalOffset(int i) { + return i * perArgCellCount + typeEntry; + } + + int stackSlot(int i) { + return pd.uintAt(stackSlotOffset(i)); + } + + K type(int i) { + return validKlass(typeOffsetInCells(i)); + } + + static int perArgCount() { + return perArgCellCount; + } + + int typeIndex(int i) { + return typeOffsetInCells(i); + } + + void printDataOn(PrintStream st) { + for (int i = 0; i < numberOfEntries; i++) { + pd.tab(st); + st.print(i + ": stack(" + stackSlot(i)+ ") "); + printKlass(st, typeOffsetInCells(i)); + st.println(); + } + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java index 21b715f343c..eec5000a6a4 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java @@ -35,9 +35,9 @@ import sun.jvm.hotspot.utilities.*; // // A VirtualCallData is used to access profiling information about a // call. For now, it has nothing more than a ReceiverTypeData. -public class VirtualCallData extends ReceiverTypeData { - public VirtualCallData(DataLayout layout) { - super(layout); +public class VirtualCallData extends ReceiverTypeData { + public VirtualCallData(MethodDataInterface methodData, DataLayout layout) { + super(methodData, layout); //assert(layout.tag() == DataLayout.virtualCallDataTag, "wrong type"); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java new file mode 100644 index 00000000000..d7ad5d993ec --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallTypeData.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.oops; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +// VirtualCallTypeData +// +// A VirtualCallTypeData is used to access profiling information about +// a virtual call for which we collect type information about +// arguments and return value. +public class VirtualCallTypeData extends VirtualCallData implements CallTypeDataInterface { + final TypeStackSlotEntries args; + final ReturnTypeEntry ret; + + int cellCountGlobalOffset() { + return VirtualCallData.staticCellCount() + TypeEntriesAtCall.cellCountLocalOffset(); + } + + int cellCountNoHeader() { + return uintAt(cellCountGlobalOffset()); + } + + public VirtualCallTypeData(MethodDataInterface methodData, DataLayout layout) { + super(methodData, layout); + args = new TypeStackSlotEntries(methodData, this, VirtualCallData.staticCellCount()+TypeEntriesAtCall.headerCellCount(), numberOfArguments()); + ret = new ReturnTypeEntry(methodData, this, cellCount() - ReturnTypeEntry.staticCellCount()); + } + + static int staticCellCount() { + return -1; + } + + public int cellCount() { + return VirtualCallData.staticCellCount() + + TypeEntriesAtCall.headerCellCount() + + intAt(cellCountGlobalOffset()); + } + + public int numberOfArguments() { + return cellCountNoHeader() / TypeStackSlotEntries.perArgCount(); + } + + public boolean hasArguments() { + return cellCountNoHeader() >= TypeStackSlotEntries.perArgCount(); + } + + public K argumentType(int i) { + return args.type(i); + } + + public boolean hasReturn() { + return (cellCountNoHeader() % TypeStackSlotEntries.perArgCount()) != 0; + } + + public K returnType() { + return ret.type(); + } + + public int argumentTypeIndex(int i) { + return args.typeIndex(i); + } + + public int returnTypeIndex() { + return ret.typeIndex(); + } + + public void printDataOn(PrintStream st) { + super.printDataOn(st); + if (hasArguments()) { + tab(st); + st.print("argument types"); + args.printDataOn(st); + } + if (hasReturn()) { + tab(st); + st.print("return type"); + ret.printDataOn(st); + } + } +}; diff --git a/hotspot/make/aix/makefiles/vm.make b/hotspot/make/aix/makefiles/vm.make index 4cdb6d92e5a..b579babfffa 100644 --- a/hotspot/make/aix/makefiles/vm.make +++ b/hotspot/make/aix/makefiles/vm.make @@ -136,8 +136,6 @@ include $(MAKEFILES_DIR)/dtrace.make JVM = jvm LIBJVM = lib$(JVM).so -CFLAGS += -DALLOW_OPERATOR_NEW_USAGE - LIBJVM_DEBUGINFO = lib$(JVM).debuginfo LIBJVM_DIZ = lib$(JVM).diz diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make index 40a9d6594af..77dde8bc930 100644 --- a/hotspot/make/bsd/makefiles/vm.make +++ b/hotspot/make/bsd/makefiles/vm.make @@ -146,9 +146,6 @@ JVM = jvm ifeq ($(OS_VENDOR), Darwin) LIBJVM = lib$(JVM).dylib CFLAGS += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE - ifeq (${VERSION}, $(filter ${VERSION}, debug fastdebug)) - CFLAGS += -DALLOW_OPERATOR_NEW_USAGE - endif LIBJVM_DEBUGINFO = lib$(JVM).dylib.dSYM LIBJVM_DIZ = lib$(JVM).diz diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index dcaa3a11a0c..55495e6bef2 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -77,30 +77,40 @@ ifeq ($(INCLUDE_ALL_GCS), false) CXXFLAGS += -DINCLUDE_ALL_GCS=0 CFLAGS += -DINCLUDE_ALL_GCS=0 - Src_Files_EXCLUDE += \ - cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \ - cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp compactibleFreeListSpace.cpp \ - concurrentMarkSweepGeneration.cpp concurrentMarkSweepThread.cpp \ - freeChunk.cpp adaptiveFreeList.cpp promotionInfo.cpp vmCMSOperations.cpp \ - collectionSetChooser.cpp concurrentG1Refine.cpp concurrentG1RefineThread.cpp \ - concurrentMark.cpp concurrentMarkThread.cpp dirtyCardQueue.cpp g1AllocRegion.cpp \ - g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \ - g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \ - g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp g1OopClosures.cpp \ - g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1StringDedup.cpp g1StringDedupStat.cpp \ - g1StringDedupTable.cpp g1StringDedupThread.cpp g1StringDedupQueue.cpp g1_globals.cpp heapRegion.cpp \ - g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ - ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp g1CodeCacheRemSet.cpp \ - adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \ - cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \ - parallelScavengeHeap.cpp parMarkBitMap.cpp pcTasks.cpp psAdaptiveSizePolicy.cpp \ - psCompactionManager.cpp psGCAdaptivePolicyCounters.cpp psGenerationCounters.cpp \ - psMarkSweep.cpp psMarkSweepDecorator.cpp psMemoryPool.cpp psOldGen.cpp \ - psParallelCompact.cpp psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp \ - psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \ - parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \ - gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \ - mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp + gc_impl := $(GAMMADIR)/src/share/vm/gc_implementation + gc_exclude := \ + $(notdir $(wildcard $(gc_impl)/concurrentMarkSweep/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/g1/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/parallelScavenge/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/parNew/*.cpp)) + Src_Files_EXCLUDE += $(gc_exclude) + + # Exclude everything in $(gc_impl)/shared except the files listed + # in $(gc_shared_keep). + gc_shared_all := $(notdir $(wildcard $(gc_impl)/shared/*.cpp)) + gc_shared_keep := \ + adaptiveSizePolicy.cpp \ + ageTable.cpp \ + collectorCounters.cpp \ + cSpaceCounters.cpp \ + gcPolicyCounters.cpp \ + gcStats.cpp \ + gcTimer.cpp \ + gcTrace.cpp \ + gcTraceSend.cpp \ + gcTraceTime.cpp \ + gcUtil.cpp \ + generationCounters.cpp \ + markSweep.cpp \ + objectCountEventSender.cpp \ + spaceDecorator.cpp \ + vmGCOperations.cpp + Src_Files_EXCLUDE += $(filter-out $(gc_shared_keep),$(gc_shared_all)) + + # src/share/vm/services + Src_Files_EXCLUDE += \ + g1MemoryPool.cpp \ + psMemoryPool.cpp endif ifeq ($(INCLUDE_NMT), false) diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile index 4a527ef68c3..51d4e6f1f11 100644 --- a/hotspot/make/windows/projectfiles/common/Makefile +++ b/hotspot/make/windows/projectfiles/common/Makefile @@ -93,7 +93,7 @@ JRE_RELEASE_VERSION="\\\"$(JDK_MAJOR_VER).$(JDK_MINOR_VER).$(JDK_MICRO_VER)\\\"" !if "$(HOTSPOT_RELEASE_VERSION)" != "" HOTSPOT_RELEASE_VERSION="\\\"$(HOTSPOT_RELEASE_VERSION)\\\"" !else -HOTSPOT_RELEASE_VERSION="\\\"$(JRE_RELEASE_VERSION)\\\"" +HOTSPOT_RELEASE_VERSION=$(JRE_RELEASE_VERSION) !endif # Define HOTSPOT_VM_DISTRO if HOTSPOT_VM_DISTRO is set, # and if it is not see if we have the src/closed directory @@ -105,9 +105,18 @@ HOTSPOT_VM_DISTRO="\\\"Java HotSpot(TM)\\\"" !else HOTSPOT_VM_DISTRO="\\\"OpenJDK\\\"" !endif +!if "$(JDK_BUILD_NUMBER)" != "" +JDK_BUILD_NUMBER="\\\"$(JDK_BUILD_NUMBER)\\\"" +!else +JDK_BUILD_NUMBER="\\\"00\\\"" +!endif !endif -ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -define JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -define HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) +JDK_MAJOR_VERSION="\\\"$(JDK_MAJOR_VER)\\\"" +JDK_MINOR_VERSION="\\\"$(JDK_MINOR_VER)\\\"" +JDK_MICRO_VERSION="\\\"$(JDK_MICRO_VER)\\\"" + +ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -define JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -define HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) -define JDK_MAJOR_VERSION=$(JDK_MAJOR_VERSION) -define JDK_MINOR_VERSION=$(JDK_MINOR_VERSION) -define JDK_MICRO_VERSION=$(JDK_MICRO_VERSION) -define JDK_BUILD_NUMBER=$(JDK_BUILD_NUMBER) ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions) $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class diff --git a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp index 58e4f3887cb..cfa7559c42a 100644 --- a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp @@ -41,7 +41,6 @@ define_pd_global(bool, UseOnStackReplacement, true); define_pd_global(bool, ProfileInterpreter, true); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 10000); -define_pd_global(intx, BackEdgeThreshold, 140000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); diff --git a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp index 0a6261a21e8..32fb22ce229 100644 --- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -149,7 +149,7 @@ void VM_Version::initialize() { } void VM_Version::print_features() { - tty->print_cr("Version: %s cache_line_size = %d", cpu_features(), get_cache_line_size()); + tty->print_cr("Version: %s cache_line_size = %d", cpu_features(), (int) get_cache_line_size()); } #ifdef COMPILER2 diff --git a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp index 8584037f1ca..f3709eb8d05 100644 --- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp @@ -414,6 +414,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { void DeoptimizeStub::emit_code(LIR_Assembler* ce) { __ bind(_entry); + __ set(_trap_request, G4); __ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type); __ delayed()->nop(); ce->add_call_info_here(_info); diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index 6f6d4c30e13..4c6f0de0010 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -1221,10 +1221,8 @@ void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { bool is_obj = (type == T_ARRAY || type == T_OBJECT); LIR_Opr offset = off.result(); - if (data != dst) { - __ move(data, dst); - data = dst; - } + // Because we want a 2-arg form of xchg + __ move(data, dst); assert (!x->is_add() && (type == T_INT || (is_obj LP64_ONLY(&& UseCompressedOops))), "unexpected type"); LIR_Address* addr; @@ -1254,7 +1252,7 @@ void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */, true /* do_load */, false /* patch */, NULL); } - __ xchg(LIR_OprFact::address(addr), data, dst, tmp); + __ xchg(LIR_OprFact::address(addr), dst, dst, tmp); if (is_obj) { // Seems to be a precise address post_barrier(ptr, data); diff --git a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index 0b065201261..1eeca870804 100644 --- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -781,7 +781,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { { __ set_info("deoptimize", dont_gc_arguments); OopMap* oop_map = save_live_registers(sasm); - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), G4); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, oop_map); restore_live_registers(sasm); diff --git a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp index 111f22730d3..54e35cb94d9 100644 --- a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp @@ -40,7 +40,6 @@ define_pd_global(bool, ProfileTraps, false); define_pd_global(bool, UseOnStackReplacement, true ); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1000 ); // Design center runs on 1.3.1 -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 1400 ); define_pd_global(bool, UseTLAB, true ); diff --git a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp index 10005a76b89..3969f39ecf8 100644 --- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp @@ -44,7 +44,6 @@ define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP define_pd_global(bool, TieredCompilation, trueInTiered); define_pd_global(intx, CompileThreshold, 10000); -define_pd_global(intx, BackEdgeThreshold, 140000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 4); diff --git a/hotspot/src/cpu/sparc/vm/copy_sparc.hpp b/hotspot/src/cpu/sparc/vm/copy_sparc.hpp index 13829b1da23..3d8fb0e5d5a 100644 --- a/hotspot/src/cpu/sparc/vm/copy_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/copy_sparc.hpp @@ -184,7 +184,7 @@ static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); if (value == 0 && UseBlockZeroing && - (count > (BlockZeroingLowLimit >> LogHeapWordSize))) { + (count > (size_t)(BlockZeroingLowLimit >> LogHeapWordSize))) { // Call it only when block zeroing is used ((_zero_Fn)StubRoutines::zero_aligned_words())(tohw, count); } else { diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp index 7cac116fada..231d1f7d932 100644 --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -3653,9 +3653,9 @@ class StubGenerator: public StubCodeGenerator { const Register len_reg = I4; // cipher length const Register keylen = I5; // reg for storing expanded key array length - // save cipher len before save_frame, to return in the end - __ mov(O4, L0); __ save_frame(0); + // save cipher len to return in the end + __ mov(len_reg, L0); // read expanded key length __ ldsw(Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)), keylen, 0); @@ -3778,9 +3778,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stf(FloatRegisterImpl::D, F60, rvec, 0); __ stf(FloatRegisterImpl::D, F62, rvec, 8); - __ restore(); - __ retl(); - __ delayed()->mov(L0, O0); + __ mov(L0, I0); + __ ret(); + __ delayed()->restore(); __ align(OptoLoopAlignment); __ BIND(L_cbcenc192); @@ -3869,9 +3869,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stf(FloatRegisterImpl::D, F60, rvec, 0); __ stf(FloatRegisterImpl::D, F62, rvec, 8); - __ restore(); - __ retl(); - __ delayed()->mov(L0, O0); + __ mov(L0, I0); + __ ret(); + __ delayed()->restore(); __ align(OptoLoopAlignment); __ BIND(L_cbcenc256); @@ -3962,9 +3962,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stf(FloatRegisterImpl::D, F60, rvec, 0); __ stf(FloatRegisterImpl::D, F62, rvec, 8); - __ restore(); - __ retl(); - __ delayed()->mov(L0, O0); + __ mov(L0, I0); + __ ret(); + __ delayed()->restore(); return start; } @@ -3992,9 +3992,9 @@ class StubGenerator: public StubCodeGenerator { const Register original_key = I5; // original key array only required during decryption const Register keylen = L6; // reg for storing expanded key array length - // save cipher len before save_frame, to return in the end - __ mov(O4, L0); __ save_frame(0); //args are read from I* registers since we save the frame in the beginning + // save cipher len to return in the end + __ mov(len_reg, L7); // load original key from SunJCE expanded decryption key // Since we load original key buffer starting first element, 8-byte alignment is guaranteed @@ -4568,10 +4568,9 @@ class StubGenerator: public StubCodeGenerator { // re-init intial vector for next block, 8-byte alignment is guaranteed __ stx(L0, rvec, 0); __ stx(L1, rvec, 8); - __ restore(); - __ mov(L0, O0); - __ retl(); - __ delayed()->nop(); + __ mov(L7, I0); + __ ret(); + __ delayed()->restore(); return start; } diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp index 129bcd8b6c3..1943705a558 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -318,22 +318,22 @@ void VM_Version::initialize() { tty->print("BIS"); } if (AllocatePrefetchLines > 1) { - tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); } else { - tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); } } if (PrefetchCopyIntervalInBytes > 0) { - tty->print_cr("PrefetchCopyIntervalInBytes %d", PrefetchCopyIntervalInBytes); + tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); } if (PrefetchScanIntervalInBytes > 0) { - tty->print_cr("PrefetchScanIntervalInBytes %d", PrefetchScanIntervalInBytes); + tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } if (PrefetchFieldsAhead > 0) { - tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead); + tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); } if (ContendedPaddingWidth > 0) { - tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth); + tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } } #endif // PRODUCT diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index a89e50b650e..64b8ce731a5 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -522,11 +522,11 @@ address Assembler::locate_operand(address inst, WhichOperand which) { // these asserts are somewhat nonsensical #ifndef _LP64 assert(which == imm_operand || which == disp32_operand, - err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, ip)); + err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip))); #else assert((which == call32_operand || which == imm_operand) && is_64bit || which == narrow_oop_operand && !is_64bit, - err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, ip)); + err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip))); #endif // _LP64 return ip; diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index a6e7731bdd5..718c82904f0 100644 --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -430,6 +430,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { void DeoptimizeStub::emit_code(LIR_Assembler* ce) { __ bind(_entry); + ce->store_parameter(_trap_request, 0); __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id))); ce->add_call_info_here(_info); DEBUG_ONLY(__ should_not_reach_here()); diff --git a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp index 12b01bfab42..ba5dc48623d 100644 --- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,7 @@ void LinearScan::allocate_fpu_stack() { #ifndef PRODUCT if (TraceFPURegisterUsage) { - tty->print("FPU regs for block %d, LIR instr %d): ", b->block_id(), id); regs.print_on(tty); tty->print_cr(""); + tty->print("FPU regs for block %d, LIR instr %d): ", b->block_id(), id); regs.print_on(tty); tty->cr(); } #endif } diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index fd6302d21be..580964a7cd9 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1468,9 +1468,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { case deoptimize_id: { StubFrame f(sasm, "deoptimize", dont_gc_arguments); - const int num_rt_args = 1; // thread + const int num_rt_args = 2; // thread, trap_request OopMap* oop_map = save_live_registers(sasm, num_rt_args); - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); + f.load_argument(0, rax); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), rax); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, oop_map); restore_live_registers(sasm); diff --git a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp index 742a5d8601d..fb7cb2889be 100644 --- a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp @@ -41,7 +41,6 @@ define_pd_global(bool, ProfileTraps, false); define_pd_global(bool, UseOnStackReplacement, true ); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1500 ); -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 933 ); define_pd_global(intx, FreqInlineSize, 325 ); diff --git a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp index 880d9439462..0366d8fcf49 100644 --- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp @@ -45,7 +45,6 @@ define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP define_pd_global(bool, TieredCompilation, trueInTiered); define_pd_global(intx, CompileThreshold, 10000); -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); diff --git a/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp b/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp index 957695fdc32..26d56b86ab3 100644 --- a/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp +++ b/hotspot/src/cpu/x86/vm/compiledIC_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,7 +122,7 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) if (TraceICs) { ResourceMark rm; tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s", - instruction_address(), + p2i(instruction_address()), callee->name_and_sig_as_C_string()); } diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp index deeb48a44bb..7a31e0800c4 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ void RegisterMap::check_location_valid() { } #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Profiling/safepoint support diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp index 02ee74506bb..e9c1ef782d8 100644 --- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,7 @@ #define __ _masm-> +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC #ifdef _WIN64 address AbstractInterpreterGenerator::generate_slow_signature_handler() { diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 3a14d975927..5b324124138 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,7 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC #ifdef ASSERT bool AbstractAssembler::pd_check_instruction_mark() { return true; } diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp index 3c12385fdbb..42c690f5e07 100644 --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "memory/allocation.inline.hpp" #include "prims/methodHandles.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define __ _masm-> #ifdef PRODUCT diff --git a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp index dccd7e0b7cd..cc1573e720a 100644 --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "c1/c1_Runtime1.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void NativeInstruction::wrote(int offset) { ICache::invalidate_word(addr_at(offset)); } diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index 1fc0e614b6d..e09dba38b0d 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -925,16 +925,16 @@ void VM_Version::get_processor_features() { if (PrintMiscellaneous && Verbose) { tty->print_cr("Logical CPUs per core: %u", logical_processors_per_package()); - tty->print("UseSSE=%d",UseSSE); + tty->print("UseSSE=%d", (int) UseSSE); if (UseAVX > 0) { - tty->print(" UseAVX=%d",UseAVX); + tty->print(" UseAVX=%d", (int) UseAVX); } if (UseAES) { tty->print(" UseAES=1"); } #ifdef COMPILER2 if (MaxVectorSize > 0) { - tty->print(" MaxVectorSize=%d", MaxVectorSize); + tty->print(" MaxVectorSize=%d", (int) MaxVectorSize); } #endif tty->cr(); @@ -957,23 +957,23 @@ void VM_Version::get_processor_features() { } } if (AllocatePrefetchLines > 1) { - tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); } else { - tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize); + tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); } } if (PrefetchCopyIntervalInBytes > 0) { - tty->print_cr("PrefetchCopyIntervalInBytes %d", PrefetchCopyIntervalInBytes); + tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); } if (PrefetchScanIntervalInBytes > 0) { - tty->print_cr("PrefetchScanIntervalInBytes %d", PrefetchScanIntervalInBytes); + tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } if (PrefetchFieldsAhead > 0) { - tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead); + tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); } if (ContendedPaddingWidth > 0) { - tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth); + tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } } #endif // !PRODUCT diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index 73c2f3ca20d..8d0353eff64 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,7 +118,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d", - vtable_index, s->entry_point(), + vtable_index, p2i(s->entry_point()), (int)(s->code_end() - s->entry_point()), (int)(s->code_end() - __ pc())); } @@ -199,7 +199,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d", - itable_index, s->entry_point(), + itable_index, p2i(s->entry_point()), (int)(s->code_end() - s->entry_point()), (int)(s->code_end() - __ pc())); } diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 089b368d015..b6dd1b33645 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // machine-dependent part of VtableStubs: create VtableStub of correct size and // initialize its code diff --git a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp index edb7364c80f..b86cb79dd86 100644 --- a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp +++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp @@ -43,7 +43,6 @@ define_pd_global(intx, Tier2CompileThreshold, 1500); define_pd_global(intx, Tier3CompileThreshold, 2500); define_pd_global(intx, Tier4CompileThreshold, 4500); -define_pd_global(intx, BackEdgeThreshold, 100000); define_pd_global(intx, Tier2BackEdgeThreshold, 100000); define_pd_global(intx, Tier3BackEdgeThreshold, 100000); define_pd_global(intx, Tier4BackEdgeThreshold, 100000); diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp index 1fec56484e5..377ff89eacb 100644 --- a/hotspot/src/os/aix/vm/os_aix.cpp +++ b/hotspot/src/os/aix/vm/os_aix.cpp @@ -1871,7 +1871,7 @@ public: // properties. // ShmBkBlock: base class for all blocks in the shared memory bookkeeping -class ShmBkBlock { +class ShmBkBlock : public CHeapObj { ShmBkBlock* _next; diff --git a/hotspot/src/os/aix/vm/porting_aix.cpp b/hotspot/src/os/aix/vm/porting_aix.cpp index b79d33d742c..5e6a78ddcc9 100644 --- a/hotspot/src/os/aix/vm/porting_aix.cpp +++ b/hotspot/src/os/aix/vm/porting_aix.cpp @@ -23,6 +23,7 @@ */ #include "asm/assembler.hpp" +#include "memory/allocation.hpp" #include "loadlib_aix.hpp" #include "porting_aix.hpp" #include "utilities/debug.hpp" @@ -67,7 +68,7 @@ inline char* align_ptr_up(char* ptr, intptr_t alignment) { // a primitive string map. Should this turn out to be a performance // problem, a better hashmap has to be used. class fixed_strings { - struct node { + struct node : public CHeapObj { char* v; node* next; }; diff --git a/hotspot/src/os/aix/vm/thread_aix.inline.hpp b/hotspot/src/os/aix/vm/thread_aix.inline.hpp index 034f6b4e2e0..04623516049 100644 --- a/hotspot/src/os/aix/vm/thread_aix.inline.hpp +++ b/hotspot/src/os/aix/vm/thread_aix.inline.hpp @@ -26,12 +26,9 @@ #ifndef OS_AIX_VM_THREAD_AIX_INLINE_HPP #define OS_AIX_VM_THREAD_AIX_INLINE_HPP -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#include "prefetch_aix_ppc.inline.hpp" - // Contains inlined functions for class Thread and ThreadLocalStorage inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do diff --git a/hotspot/src/os/bsd/vm/decoder_machO.cpp b/hotspot/src/os/bsd/vm/decoder_machO.cpp index b475f23ff94..6ef6314a1d1 100644 --- a/hotspot/src/os/bsd/vm/decoder_machO.cpp +++ b/hotspot/src/os/bsd/vm/decoder_machO.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ bool MachODecoder::decode(address addr, char *buf, struct symtab_command * symt = (struct symtab_command *) mach_find_command((struct mach_header_64 *)mach_base, LC_SYMTAB); if (symt == NULL) { - DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", mach_base)); + DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", p2i(mach_base))); return false; } uint32_t off = symt->symoff; /* symbol table offset (within this mach file) */ diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 9d3ec5ffd2d..c8313235d0c 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -124,6 +124,9 @@ #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) #define LARGEPAGES_BIT (1 << 6) + +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + //////////////////////////////////////////////////////////////////////////////// // global variables julong os::Bsd::_physical_memory = 0; @@ -2394,7 +2397,6 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, (!FLAG_IS_DEFAULT(UseLargePages) || !FLAG_IS_DEFAULT(LargePageSizeInBytes) ); - char msg[128]; // Create a large shared memory region to attach to based on size. // Currently, size is the total size of the heap @@ -2415,8 +2417,7 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, // coalesce into large pages. Try to reserve large pages when // the system is still "fresh". if (warn_on_failure) { - jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); - warning(msg); + warning("Failed to reserve shared memory (errno = %d).", errno); } return NULL; } @@ -2433,8 +2434,7 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, if ((intptr_t)addr == -1) { if (warn_on_failure) { - jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); - warning(msg); + warning("Failed to attach shared memory (errno = %d).", err); } return NULL; } @@ -3810,6 +3810,7 @@ bool os::check_heap(bool force) { return true; } +ATTRIBUTE_PRINTF(3, 0) int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { return ::vsnprintf(buf, count, format, args); } diff --git a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp index f59b763b325..e812a76f51b 100644 --- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp +++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -925,7 +925,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor if (PerfTraceMemOps) { tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at " - INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress); + INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress)); } } diff --git a/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp b/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp index 622707d4f5d..86f125dc5b4 100644 --- a/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp +++ b/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp @@ -31,12 +31,6 @@ #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_bsd_x86 -# include "prefetch_bsd_x86.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_bsd_zero -# include "prefetch_bsd_zero.inline.hpp" -#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index ce771028a3b..7941edf59ce 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -102,6 +102,8 @@ # include # include +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling // getrusage() is prepared to handle the associated failure. #ifndef RUSAGE_THREAD @@ -2138,7 +2140,7 @@ void os::print_os_info(outputStream* st) { // Print warning if unsafe chroot environment detected if (unsafe_chroot_detected) { st->print("WARNING!! "); - st->print_cr(unstable_chroot_error); + st->print_cr("%s", unstable_chroot_error); } os::Linux::print_libversion_info(st); @@ -2199,8 +2201,8 @@ void os::Linux::print_distro_info(outputStream* st) { void os::Linux::print_libversion_info(outputStream* st) { // libc, pthread st->print("libc:"); - st->print(os::Linux::glibc_version()); st->print(" "); - st->print(os::Linux::libpthread_version()); st->print(" "); + st->print("%s ", os::Linux::glibc_version()); + st->print("%s ", os::Linux::libpthread_version()); if (os::Linux::is_LinuxThreads()) { st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed"); } @@ -3417,7 +3419,7 @@ char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char // the system is still "fresh". if (warn_on_failure) { jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); - warning(msg); + warning("%s", msg); } return NULL; } @@ -3435,7 +3437,7 @@ char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char if ((intptr_t)addr == -1) { if (warn_on_failure) { jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); - warning(msg); + warning("%s", msg); } return NULL; } @@ -3455,7 +3457,7 @@ static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) char msg[128]; jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: " PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error); - warning(msg); + warning("%s", msg); } } diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp index d95d33107e6..9708734295f 100644 --- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp +++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp @@ -931,7 +931,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor if (PerfTraceMemOps) { tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at " - INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress); + INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress)); } } diff --git a/hotspot/src/os/linux/vm/thread_linux.inline.hpp b/hotspot/src/os/linux/vm/thread_linux.inline.hpp index 76bdd223449..b58dc078948 100644 --- a/hotspot/src/os/linux/vm/thread_linux.inline.hpp +++ b/hotspot/src/os/linux/vm/thread_linux.inline.hpp @@ -29,24 +29,8 @@ #error "This file should only be included from thread.inline.hpp" #endif -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_linux_x86 -# include "prefetch_linux_x86.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_sparc -# include "prefetch_linux_sparc.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_zero -# include "prefetch_linux_zero.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_arm -# include "prefetch_linux_arm.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_linux_ppc -# include "prefetch_linux_ppc.inline.hpp" -#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp index 41e9b6ccfe9..d17bc15cbae 100644 --- a/hotspot/src/os/posix/vm/os_posix.cpp +++ b/hotspot/src/os/posix/vm/os_posix.cpp @@ -36,6 +36,8 @@ #include #include +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Todo: provide a os::get_max_process_id() or similar. Number of processes // may have been configured, can be read more accurately from proc fs etc. #ifndef MAX_PID @@ -192,10 +194,10 @@ void os::Posix::print_uname_info(outputStream* st) { st->print("uname:"); struct utsname name; uname(&name); - st->print(name.sysname); st->print(" "); - st->print(name.release); st->print(" "); - st->print(name.version); st->print(" "); - st->print(name.machine); + st->print("%s ", name.sysname); + st->print("%s ", name.release); + st->print("%s ", name.version); + st->print("%s", name.machine); st->cr(); } @@ -682,7 +684,7 @@ const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buff void os::Posix::print_signal_set_short(outputStream* st, const sigset_t* set) { char buf[NUM_IMPORTANT_SIGS + 1]; os::Posix::describe_signal_set_short(set, buf, sizeof(buf)); - st->print(buf); + st->print("%s", buf); } // Writes one-line description of a combination of sigaction.sa_flags into a user @@ -742,7 +744,7 @@ const char* os::Posix::describe_sa_flags(int flags, char* buffer, size_t size) { void os::Posix::print_sa_flags(outputStream* st, int flags) { char buffer[0x100]; os::Posix::describe_sa_flags(flags, buffer, sizeof(buffer)); - st->print(buffer); + st->print("%s", buffer); } // Helper function for os::Posix::print_siginfo_...(): diff --git a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp index affc2c824c6..d7d6d378f1a 100644 --- a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp +++ b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp @@ -30,15 +30,8 @@ #endif #include "runtime/atomic.inline.hpp" -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_solaris_x86 -# include "prefetch_solaris_x86.inline.hpp" -#endif -#ifdef TARGET_OS_ARCH_solaris_sparc -# include "prefetch_solaris_sparc.inline.hpp" -#endif // Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of // startup. diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 35c2fcfed64..04b72a9d37d 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -5005,7 +5005,11 @@ bool os::check_heap(bool force) { // wrong; at these points, eax contains the address of the offending block (I think). // To get to the exlicit error message(s) below, just continue twice. HANDLE heap = GetProcessHeap(); - { HeapLock(heap); + + // If we fail to lock the heap, then gflags.exe has been used + // or some other special heap flag has been set that prevents + // locking. We don't try to walk a heap we can't lock. + if (HeapLock(heap) != 0) { PROCESS_HEAP_ENTRY phe; phe.lpData = NULL; while (HeapWalk(heap, &phe) != 0) { diff --git a/hotspot/src/os/windows/vm/thread_windows.inline.hpp b/hotspot/src/os/windows/vm/thread_windows.inline.hpp index a7af8776325..95dd17cecc7 100644 --- a/hotspot/src/os/windows/vm/thread_windows.inline.hpp +++ b/hotspot/src/os/windows/vm/thread_windows.inline.hpp @@ -29,12 +29,8 @@ #error "This file should only be included from thread.inline.hpp" #endif -#include "runtime/prefetch.hpp" #include "runtime/thread.hpp" #include "runtime/threadLocalStorage.hpp" -#ifdef TARGET_OS_ARCH_windows_x86 -# include "prefetch_windows_x86.inline.hpp" -#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index 5718a791959..50051d7c699 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -276,6 +276,8 @@ # endif #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + address os::current_stack_pointer() { #if defined(__clang__) || defined(__llvm__) register void *esp; diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index d269d38ac59..3c8e18eef48 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,6 +89,8 @@ #define SPELL_REG_FP "ebp" #endif // AMD64 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + address os::current_stack_pointer() { #ifdef SPARC_WORKS register void *esp; diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java index faef0ce00ec..1aa3edbc35a 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java @@ -231,6 +231,9 @@ public class CallSite { // identical call sites with the same method name/bci are // possible so we have to try them all until we find the late // inline call site that has a matching inline id. + if (calls == null) { + return null; + } CallSite site = sites.pop(); for (CallSite c : calls) { if (c.matches(site)) { @@ -250,6 +253,27 @@ public class CallSite { return null; } + public ArrayDeque findCallSite2(CallSite site) { + if (calls == null) { + return null; + } + + for (CallSite c : calls) { + if (c.matches(site)) { + ArrayDeque stack = new ArrayDeque(); + stack.push(c); + return stack; + } else { + ArrayDeque stack = c.findCallSite2(site); + if (stack != null) { + stack.push(c); + return stack; + } + } + } + return null; + } + public long getInlineId() { return inlineId; } diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java index 861fe443753..e6617da628d 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java @@ -49,6 +49,12 @@ public class Compilation implements LogEvent { this.id = id; } + void reset() { + call = new CallSite(); + lateInlineCall = new CallSite(); + phases = new ArrayList(4); + } + Phase getPhase(String s) { for (Phase p : getPhases()) { if (p.getName().equals(s)) { @@ -212,10 +218,6 @@ public class Compilation implements LogEvent { return phases; } - public void setPhases(ArrayList phases) { - this.setPhases(phases); - } - public String getFailureReason() { return failureReason; } @@ -240,10 +242,6 @@ public class Compilation implements LogEvent { return call; } - public void setCall(CallSite call) { - this.call = call; - } - public CallSite getLateInlineCall() { return lateInlineCall; } diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java index 077c1d20ab6..50704c3512e 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java @@ -395,6 +395,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants compile.setEnd(Double.parseDouble(search(atts, "stamp"))); if (Integer.parseInt(search(atts, "success")) == 0) { compile.setFailureReason(failureReason); + failureReason = null; } } else if (qname.equals("make_not_entrant")) { String id = makeId(atts); @@ -451,6 +452,12 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants nmethods.put(id, nm); events.add(nm); } else if (qname.equals("parse")) { + if (failureReason != null && scopes.size() == 0 && !lateInlining) { + failureReason = null; + compile.reset(); + site = compile.getCall(); + } + if (methodHandleSite != null) { throw new InternalError("method handle site should have been replaced"); } @@ -529,6 +536,18 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants site = compile.getCall().findCallSite(thisCallScopes); if (site == null) { + System.out.println("call scopes:"); + for (CallSite c : thisCallScopes) { + System.out.println(c.getMethod() + " " + c.getBci() + " " + c.getInlineId()); + } + CallSite c = thisCallScopes.getLast(); + if (c.getInlineId() != 0) { + System.out.println("Looking for call site in entire tree:"); + ArrayDeque stack = compile.getCall().findCallSite2(c); + for (CallSite c2 : stack) { + System.out.println(c2.getMethod() + " " + c2.getBci() + " " + c2.getInlineId()); + } + } System.out.println(caller.getMethod() + " bci: " + bci); throw new InternalError("couldn't find call site"); } diff --git a/hotspot/src/share/vm/adlc/adlc.hpp b/hotspot/src/share/vm/adlc/adlc.hpp index 18f98884c3c..4ced0bf47bd 100644 --- a/hotspot/src/share/vm/adlc/adlc.hpp +++ b/hotspot/src/share/vm/adlc/adlc.hpp @@ -30,12 +30,13 @@ // // standard library constants -#include "stdio.h" -#include "stdlib.h" #include -#include "string.h" -#include "ctype.h" -#include "stdarg.h" + +#include +#include +#include +#include +#include #include /* Make sure that we have the intptr_t and uintptr_t definitions */ diff --git a/hotspot/src/share/vm/adlc/adlparse.hpp b/hotspot/src/share/vm/adlc/adlparse.hpp index 3ea00a24922..8907cf1754d 100644 --- a/hotspot/src/share/vm/adlc/adlparse.hpp +++ b/hotspot/src/share/vm/adlc/adlparse.hpp @@ -64,8 +64,6 @@ class PeepMatch; class PeepConstraint; class PeepReplace; -// class ostream; // ostream is a typedef in some systems - extern char *toUpper(const char *str); //---------------------------ADLParser----------------------------------------- diff --git a/hotspot/src/share/vm/adlc/filebuff.cpp b/hotspot/src/share/vm/adlc/filebuff.cpp index 71daa5cc4bd..bd4a8d161ed 100644 --- a/hotspot/src/share/vm/adlc/filebuff.cpp +++ b/hotspot/src/share/vm/adlc/filebuff.cpp @@ -25,8 +25,6 @@ // FILEBUFF.CPP - Routines for handling a parser file buffer #include "adlc.hpp" -using namespace std; - //------------------------------FileBuff--------------------------------------- // Create a new parsing buffer FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(archDesc) { diff --git a/hotspot/src/share/vm/adlc/filebuff.hpp b/hotspot/src/share/vm/adlc/filebuff.hpp index 292fd1781f6..e2ed6a75665 100644 --- a/hotspot/src/share/vm/adlc/filebuff.hpp +++ b/hotspot/src/share/vm/adlc/filebuff.hpp @@ -26,9 +26,6 @@ #define SHARE_VM_ADLC_FILEBUFF_HPP // FILEBUFF.HPP - Definitions for parser file buffering routines -#include - -using namespace std; // STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index df58c5746de..ffb13e759a4 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1322,7 +1322,7 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) { OperandForm* oper = form->is_operand(); if (oper != NULL && oper->is_bound_register()) { const RegDef* first = oper->get_RegClass()->find_first_elem(); - fprintf(fp, " st->print(\"%s\");\n", first->_regname); + fprintf(fp, " st->print_raw(\"%s\");\n", first->_regname); } else { globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var); } @@ -2530,7 +2530,7 @@ void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) { case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; case Form::idealNKlass: case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; - case Form::idealL: fprintf(fp," st->print(\"#%%lld\", _c%d);\n", const_index); break; + case Form::idealL: fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break; case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; default: diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 2279e75ecc5..7e020fb1726 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -211,7 +211,7 @@ static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) const char *type = oper->ideal_type(globals); if (!strcmp(type, "ConI")) { if (i > 0) fprintf(fp,", "); - fprintf(fp," int32 _c%d;\n", i); + fprintf(fp," int32_t _c%d;\n", i); } else if (!strcmp(type, "ConP")) { if (i > 0) fprintf(fp,", "); @@ -307,7 +307,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, assert(num_consts == 1, "Bad component list detected.\n"); switch( constant_type ) { case Form::idealI : { - fprintf(fp,is_ideal_bool ? "BoolTest::mask c%d" : "int32 c%d", i); + fprintf(fp,is_ideal_bool ? "BoolTest::mask c%d" : "int32_t c%d", i); break; } case Form::idealN : { fprintf(fp,"const TypeNarrowOop *c%d", i); break; } @@ -326,7 +326,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, while((comp = lst.iter()) != NULL) { if (!strcmp(comp->base_type(globals), "ConI")) { if (i > 0) fprintf(fp,", "); - fprintf(fp,"int32 c%d", i); + fprintf(fp,"int32_t c%d", i); i++; } else if (!strcmp(comp->base_type(globals), "ConP")) { @@ -386,14 +386,14 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) { assert(oper != NULL, "what"); CondInterface* cond = oper->_interface->is_CondInterface(); - fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format); - fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format); - fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print(\"%s\");\n",i,cond->_overflow_format); - fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print(\"%s\");\n",i,cond->_no_overflow_format); + fprintf(fp, " if( _c%d == BoolTest::eq ) st->print_raw(\"%s\");\n",i,cond->_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print_raw(\"%s\");\n",i,cond->_not_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::le ) st->print_raw(\"%s\");\n",i,cond->_less_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print_raw(\"%s\");\n",i,cond->_greater_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print_raw(\"%s\");\n",i,cond->_less_format); + fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print_raw(\"%s\");\n",i,cond->_greater_format); + fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print_raw(\"%s\");\n",i,cond->_overflow_format); + fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print_raw(\"%s\");\n",i,cond->_no_overflow_format); } // Output code that dumps constant values, increment "i" if type is constant @@ -416,8 +416,8 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, Operand ++i; } else if (!strcmp(ideal_type, "ConL")) { - fprintf(fp," st->print(\"#\" INT64_FORMAT, _c%d);\n", i); - fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%d);\n", i); + fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", i); + fprintf(fp," st->print(\"/\" PTR64_FORMAT, (uint64_t)_c%d);\n", i); ++i; } else if (!strcmp(ideal_type, "ConF")) { @@ -429,7 +429,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, Operand else if (!strcmp(ideal_type, "ConD")) { fprintf(fp," st->print(\"#%%f\", _c%d);\n", i); fprintf(fp," jlong _c%dl = JavaValue(_c%d).get_jlong();\n", i, i); - fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%dl);\n", i); + fprintf(fp," st->print(\"/\" PTR64_FORMAT, (uint64_t)_c%dl);\n", i); ++i; } else if (!strcmp(ideal_type, "Bool")) { @@ -471,7 +471,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ if ( string != NameList::_signal ) { // Normal string // Pass through to st->print - fprintf(fp," st->print(\"%s\");\n", string); + fprintf(fp," st->print_raw(\"%s\");\n", string); } else { // Replacement variable const char *rep_var = oper._format->_rep_vars.iter(); @@ -542,7 +542,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ if ( string != NameList::_signal ) { // Normal string // Pass through to st->print - fprintf(fp," st->print(\"%s\");\n", string); + fprintf(fp," st->print_raw(\"%s\");\n", string); } else { // Replacement variable const char *rep_var = oper._format->_rep_vars.iter(); @@ -669,7 +669,7 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c } else if( string == NameList::_signal2 ) // Raw program text fputs(inst._format->_strings.iter(), fp); else - fprintf(fp,"st->print(\"%s\");\n", string); + fprintf(fp,"st->print_raw(\"%s\");\n", string); } // Done with all format strings } // Done generating the user-defined portion of the format @@ -696,13 +696,13 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c default: assert(0,"ShouldNotReachHere"); } - fprintf(fp, " st->print_cr(\"\");\n" ); + fprintf(fp, " st->cr();\n" ); fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); fprintf(fp, " st->print(\" # \");\n" ); fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n"); } else if(inst.is_ideal_safepoint()) { - fprintf(fp, " st->print(\"\");\n" ); + fprintf(fp, " st->print_raw(\"\");\n" ); fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); fprintf(fp, " st->print(\" # \");\n" ); fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n"); diff --git a/hotspot/src/share/vm/asm/assembler.cpp b/hotspot/src/share/vm/asm/assembler.cpp index 0eadb5dc273..274aa872e6f 100644 --- a/hotspot/src/share/vm/asm/assembler.cpp +++ b/hotspot/src/share/vm/asm/assembler.cpp @@ -119,7 +119,7 @@ void AbstractAssembler::bind(Label& L) { L.patch_instructions((MacroAssembler*)this); } -void AbstractAssembler::generate_stack_overflow_check( int frame_size_in_bytes) { +void AbstractAssembler::generate_stack_overflow_check(int frame_size_in_bytes) { if (UseStackBanging) { // Each code entry causes one stack bang n pages down the stack where n // is configurable by StackShadowPages. The setting depends on the maximum @@ -134,7 +134,7 @@ void AbstractAssembler::generate_stack_overflow_check( int frame_size_in_bytes) // is greater than a page. const int page_size = os::vm_page_size(); - int bang_end = StackShadowPages*page_size; + int bang_end = StackShadowPages * page_size; // This is how far the previous frame's stack banging extended. const int bang_end_safe = bang_end; diff --git a/hotspot/src/share/vm/asm/codeBuffer.cpp b/hotspot/src/share/vm/asm/codeBuffer.cpp index 0c10e1fdb9e..60d405b35f4 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.cpp +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -988,7 +988,7 @@ void CodeSection::dump() { for (csize_t step; ptr < end(); ptr += step) { step = end() - ptr; if (step > jintSize * 4) step = jintSize * 4; - tty->print(PTR_FORMAT ": ", ptr); + tty->print(INTPTR_FORMAT ": ", p2i(ptr)); while (step > 0) { tty->print(" " PTR32_FORMAT, *(jint*)ptr); ptr += jintSize; @@ -1098,7 +1098,7 @@ void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) con while (c && c->offset() == offset) { stream->bol(); stream->print(" ;; "); - stream->print_cr(c->string()); + stream->print_cr("%s", c->string()); c = c->next_comment(); } } @@ -1154,10 +1154,10 @@ void CodeBuffer::decode_all() { void CodeSection::print(const char* name) { csize_t locs_size = locs_end() - locs_start(); tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)%s", - name, start(), end(), limit(), size(), capacity(), + name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity(), is_frozen()? " [frozen]": ""); tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d", - name, locs_start(), locs_end(), locs_limit(), locs_size, locs_capacity(), locs_point_off()); + name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off()); if (PrintRelocations) { RelocIterator iter(this); iter.print(); diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp index bcc5d51e7ad..5572a39af7d 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.hpp +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,7 +173,7 @@ class CodeSection VALUE_OBJ_CLASS_SPEC { bool allocates(address pc) const { return pc >= _start && pc < _limit; } bool allocates2(address pc) const { return pc >= _start && pc <= _limit; } - void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT, _start, pc, _limit)); _end = pc; } + void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " INTPTR_FORMAT " <= " INTPTR_FORMAT " <= " INTPTR_FORMAT, p2i(_start), p2i(pc), p2i(_limit))); _end = pc; } void set_mark(address pc) { assert(contains2(pc), "not in codeBuffer"); _mark = pc; } void set_mark_off(int offset) { assert(contains2(offset+_start),"not in codeBuffer"); diff --git a/hotspot/src/share/vm/asm/register.hpp b/hotspot/src/share/vm/asm/register.hpp index 5afecdeb116..d9918517dd9 100644 --- a/hotspot/src/share/vm/asm/register.hpp +++ b/hotspot/src/share/vm/asm/register.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,8 +118,8 @@ inline void assert_different_registers( ) { assert( a != b, - err_msg_res("registers must be different: a=%d, b=%d", - a, b) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", + p2i(a), p2i(b)) ); } @@ -132,8 +132,9 @@ inline void assert_different_registers( assert( a != b && a != c && b != c, - err_msg_res("registers must be different: a=%d, b=%d, c=%d", - a, b, c) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c)) ); } @@ -148,8 +149,9 @@ inline void assert_different_registers( a != b && a != c && a != d && b != c && b != d && c != d, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d", - a, b, c, d) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d)) ); } @@ -166,8 +168,9 @@ inline void assert_different_registers( && b != c && b != d && b != e && c != d && c != e && d != e, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d", - a, b, c, d, e) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)) ); } @@ -186,8 +189,10 @@ inline void assert_different_registers( && c != d && c != e && c != f && d != e && d != f && e != f, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d", - a, b, c, d, e, f) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)) ); } @@ -208,8 +213,10 @@ inline void assert_different_registers( && d != e && d != f && d != g && e != f && e != g && f != g, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d", - a, b, c, d, e, f, g) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)) ); } @@ -232,8 +239,10 @@ inline void assert_different_registers( && e != f && e != g && e != h && f != g && f != h && g != h, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d", - a, b, c, d, e, f, g, h) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)) ); } @@ -258,8 +267,11 @@ inline void assert_different_registers( && f != g && f != h && f != i && g != h && g != i && h != i, - err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d", - a, b, c, d, e, f, g, h, i) + err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT + ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT + ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT + ", i=" INTPTR_FORMAT "", + p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)) ); } diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp index 4eaa7d27f68..b0cb94629f4 100644 --- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ class CFGPrinterOutput : public CHeapObj { void inc_indent(); void dec_indent(); - void print(const char* format, ...); + void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void print_begin(const char* tag); void print_end(const char* tag); @@ -161,7 +161,7 @@ void CFGPrinterOutput::print_compilation() { print("name \"%s\"", method_name(_compilation->method(), true)); print("method \"%s\"", method_name(_compilation->method())); - print("date "INT64_FORMAT, os::javaTimeMillis()); + print("date "INT64_FORMAT, (int64_t) os::javaTimeMillis()); print_end("compilation"); } diff --git a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp index d3c5a0d8bbb..2d0c31e2afe 100644 --- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp +++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp @@ -450,9 +450,11 @@ class PatchingStub: public CodeStub { class DeoptimizeStub : public CodeStub { private: CodeEmitInfo* _info; + jint _trap_request; public: - DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {} + DeoptimizeStub(CodeEmitInfo* info, Deoptimization::DeoptReason reason, Deoptimization::DeoptAction action) : + _info(new CodeEmitInfo(info)), _trap_request(Deoptimization::make_trap_request(reason, action)) {} virtual void emit_code(LIR_Assembler* e); virtual CodeEmitInfo* info() const { return _info; } diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp index 8ff7f3e50c3..6ecd26477e0 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.hpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp @@ -251,6 +251,10 @@ class Compilation: public StackObj { return env()->comp_level() == CompLevel_full_profile && C1UpdateMethodData && MethodData::profile_return(); } + bool age_code() const { + return _method->profile_aging(); + } + // will compilation make optimistic assumptions that might lead to // deoptimization and that the runtime will account for? bool is_optimistic() const { diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp index 7f87e1183b0..842acec5be9 100644 --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,23 +134,23 @@ void InstructionPrinter::print_object(Value obj) { if (value->is_null_object()) { output()->print("null"); } else if (!value->is_loaded()) { - output()->print("", value); + output()->print("", p2i(value)); } else { - output()->print(""); } } else if (type->as_InstanceConstant() != NULL) { ciInstance* value = type->as_InstanceConstant()->value(); if (value->is_loaded()) { - output()->print(""); } else { - output()->print("", value); + output()->print("", p2i(value)); } } else if (type->as_ArrayConstant() != NULL) { - output()->print("", type->as_ArrayConstant()->value()->constant_encoding()); + output()->print("", p2i(type->as_ArrayConstant()->value()->constant_encoding())); } else if (type->as_ClassConstant() != NULL) { ciInstanceKlass* klass = type->as_ClassConstant()->value(); if (!klass->is_loaded()) { @@ -268,7 +268,7 @@ void InstructionPrinter::print_inline_level(BlockBegin* block) { void InstructionPrinter::print_unsafe_op(UnsafeOp* op, const char* name) { - output()->print(name); + output()->print("%s", name); output()->print(".("); } @@ -479,7 +479,7 @@ void InstructionPrinter::do_TypeCast(TypeCast* x) { if (x->declared_type()->is_klass()) print_klass(x->declared_type()->as_klass()); else - output()->print(type2name(x->declared_type()->basic_type())); + output()->print("%s", type2name(x->declared_type()->basic_type())); } diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index 2634f5f4105..f60190ae6c3 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1083,7 +1083,7 @@ void LIR_OpLabel::emit_code(LIR_Assembler* masm) { void LIR_OpArrayCopy::emit_code(LIR_Assembler* masm) { masm->emit_arraycopy(this); - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } void LIR_OpUpdateCRC32::emit_code(LIR_Assembler* masm) { @@ -1100,20 +1100,20 @@ void LIR_Op1::emit_code(LIR_Assembler* masm) { void LIR_OpAllocObj::emit_code(LIR_Assembler* masm) { masm->emit_alloc_obj(this); - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } void LIR_OpBranch::emit_code(LIR_Assembler* masm) { masm->emit_opBranch(this); if (stub()) { - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } } void LIR_OpConvert::emit_code(LIR_Assembler* masm) { masm->emit_opConvert(this); if (stub() != NULL) { - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } } @@ -1123,13 +1123,13 @@ void LIR_Op2::emit_code(LIR_Assembler* masm) { void LIR_OpAllocArray::emit_code(LIR_Assembler* masm) { masm->emit_alloc_array(this); - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } void LIR_OpTypeCheck::emit_code(LIR_Assembler* masm) { masm->emit_opTypeCheck(this); if (stub()) { - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } } @@ -1144,7 +1144,7 @@ void LIR_Op3::emit_code(LIR_Assembler* masm) { void LIR_OpLock::emit_code(LIR_Assembler* masm) { masm->emit_lock(this); if (stub()) { - masm->emit_code_stub(stub()); + masm->append_code_stub(stub()); } } @@ -1563,15 +1563,15 @@ void LIR_OprDesc::print(outputStream* out) const { } else if (is_virtual()) { out->print("R%d", vreg_number()); } else if (is_single_cpu()) { - out->print(as_register()->name()); + out->print("%s", as_register()->name()); } else if (is_double_cpu()) { - out->print(as_register_hi()->name()); - out->print(as_register_lo()->name()); + out->print("%s", as_register_hi()->name()); + out->print("%s", as_register_lo()->name()); #if defined(X86) } else if (is_single_xmm()) { - out->print(as_xmm_float_reg()->name()); + out->print("%s", as_xmm_float_reg()->name()); } else if (is_double_xmm()) { - out->print(as_xmm_double_reg()->name()); + out->print("%s", as_xmm_double_reg()->name()); } else if (is_single_fpu()) { out->print("fpu%d", fpu_regnr()); } else if (is_double_fpu()) { @@ -1583,9 +1583,9 @@ void LIR_OprDesc::print(outputStream* out) const { out->print("d%d", fpu_regnrLo() >> 1); #else } else if (is_single_fpu()) { - out->print(as_float_reg()->name()); + out->print("%s", as_float_reg()->name()); } else if (is_double_fpu()) { - out->print(as_double_reg()->name()); + out->print("%s", as_double_reg()->name()); #endif } else if (is_illegal()) { @@ -1611,9 +1611,9 @@ void LIR_Const::print_value_on(outputStream* out) const { case T_LONG: out->print("lng:" JLONG_FORMAT, as_jlong()); break; case T_FLOAT: out->print("flt:%f", as_jfloat()); break; case T_DOUBLE: out->print("dbl:%f", as_jdouble()); break; - case T_OBJECT: out->print("obj:0x%x", as_jobject()); break; - case T_METADATA: out->print("metadata:0x%x", as_metadata());break; - default: out->print("%3d:0x%x",type(), as_jdouble()); break; + case T_OBJECT: out->print("obj:" INTPTR_FORMAT, p2i(as_jobject())); break; + case T_METADATA: out->print("metadata:" INTPTR_FORMAT, p2i(as_metadata()));break; + default: out->print("%3d:0x" UINT64_FORMAT_X, type(), (uint64_t)as_jlong()); break; } } @@ -1629,7 +1629,7 @@ void LIR_Address::print_value_on(outputStream* out) const { case times_8: out->print(" * 8"); break; } } - out->print(" Disp: %d", _disp); + out->print(" Disp: " INTX_FORMAT, _disp); } // debug output of block header without InstructionPrinter @@ -1703,7 +1703,7 @@ void LIR_Op::print_on(outputStream* out) const { } else { out->print(" "); } - out->print(name()); out->print(" "); + out->print("%s ", name()); print_instr(out); if (info() != NULL) out->print(" [bci:%d]", info()->stack()->bci()); #ifdef ASSERT @@ -1833,7 +1833,7 @@ const char * LIR_Op::name() const { // LIR_OpJavaCall void LIR_OpJavaCall::print_instr(outputStream* out) const { out->print("call: "); - out->print("[addr: 0x%x]", address()); + out->print("[addr: " INTPTR_FORMAT "]", p2i(address())); if (receiver()->is_valid()) { out->print(" [recv: "); receiver()->print(out); out->print("]"); } @@ -1844,7 +1844,7 @@ void LIR_OpJavaCall::print_instr(outputStream* out) const { // LIR_OpLabel void LIR_OpLabel::print_instr(outputStream* out) const { - out->print("[label:0x%x]", _label); + out->print("[label:" INTPTR_FORMAT "]", p2i(_label)); } // LIR_OpArrayCopy @@ -1911,7 +1911,7 @@ void LIR_Op1::print_instr(outputStream* out) const { // LIR_Op1 void LIR_OpRTCall::print_instr(outputStream* out) const { intx a = (intx)addr(); - out->print(Runtime1::name_for_address(addr())); + out->print("%s", Runtime1::name_for_address(addr())); out->print(" "); tmp()->print(out); } @@ -1934,10 +1934,10 @@ void LIR_OpBranch::print_instr(outputStream* out) const { } else if (stub() != NULL) { out->print("["); stub()->print_name(out); - out->print(": 0x%x]", stub()); + out->print(": " INTPTR_FORMAT "]", p2i(stub())); if (stub()->info() != NULL) out->print(" [bci:%d]", stub()->info()->stack()->bci()); } else { - out->print("[label:0x%x] ", label()); + out->print("[label:" INTPTR_FORMAT "] ", p2i(label())); } if (ublock() != NULL) { out->print("unordered: [B%d] ", ublock()->block_id()); @@ -2004,7 +2004,7 @@ void LIR_OpAllocObj::print_instr(outputStream* out) const { tmp4()->print(out); out->print(" "); out->print("[hdr:%d]", header_size()); out->print(" "); out->print("[obj:%d]", object_size()); out->print(" "); - out->print("[lbl:0x%x]", stub()->entry()); + out->print("[lbl:" INTPTR_FORMAT "]", p2i(stub()->entry())); } void LIR_OpRoundFP::print_instr(outputStream* out) const { @@ -2037,7 +2037,7 @@ void LIR_OpAllocArray::print_instr(outputStream* out) const { tmp3()->print(out); out->print(" "); tmp4()->print(out); out->print(" "); out->print("[type:0x%x]", type()); out->print(" "); - out->print("[label:0x%x]", stub()->entry()); + out->print("[label:" INTPTR_FORMAT "]", p2i(stub()->entry())); } @@ -2074,7 +2074,7 @@ void LIR_OpLock::print_instr(outputStream* out) const { if (_scratch->is_valid()) { _scratch->print(out); out->print(" "); } - out->print("[lbl:0x%x]", stub()->entry()); + out->print("[lbl:" INTPTR_FORMAT "]", p2i(stub()->entry())); } #ifdef ASSERT @@ -2082,7 +2082,7 @@ void LIR_OpAssert::print_instr(outputStream* out) const { print_condition(out, condition()); out->print(" "); in_opr1()->print(out); out->print(" "); in_opr2()->print(out); out->print(", \""); - out->print(msg()); out->print("\""); + out->print("%s", msg()); out->print("\""); } #endif diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index a339af5098f..e26c280c38a 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -1127,6 +1127,7 @@ class LIR_Op: public CompilationResourceObj { virtual void print_instr(outputStream* out) const = 0; virtual void print_on(outputStream* st) const PRODUCT_RETURN; + virtual bool is_patching() { return false; } virtual LIR_OpCall* as_OpCall() { return NULL; } virtual LIR_OpJavaCall* as_OpJavaCall() { return NULL; } virtual LIR_OpLabel* as_OpLabel() { return NULL; } @@ -1387,6 +1388,7 @@ class LIR_Op1: public LIR_Op { return (LIR_MoveKind)_flags; } + virtual bool is_patching() { return _patch != lir_patch_none; } virtual void emit_code(LIR_Assembler* masm); virtual LIR_Op1* as_Op1() { return this; } virtual const char * name() const PRODUCT_RETURN0; @@ -1619,6 +1621,7 @@ public: int profiled_bci() const { return _profiled_bci; } bool should_profile() const { return _should_profile; } + virtual bool is_patching() { return _info_for_patch != NULL; } virtual void emit_code(LIR_Assembler* masm); virtual LIR_OpTypeCheck* as_OpTypeCheck() { return this; } void print_instr(outputStream* out) const PRODUCT_RETURN; diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp index 826cf70080a..ef2b10623a4 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp @@ -58,7 +58,7 @@ void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_cod _masm->nop(); } patch->install(_masm, patch_code, obj, info); - append_patching_stub(patch); + append_code_stub(patch); #ifdef ASSERT Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci()); @@ -131,11 +131,6 @@ LIR_Assembler::~LIR_Assembler() { } -void LIR_Assembler::append_patching_stub(PatchingStub* stub) { - _slow_case_stubs->append(stub); -} - - void LIR_Assembler::check_codespace() { CodeSection* cs = _masm->code_section(); if (cs->remaining() < (int)(NOT_LP64(1*K)LP64_ONLY(2*K))) { @@ -144,7 +139,7 @@ void LIR_Assembler::check_codespace() { } -void LIR_Assembler::emit_code_stub(CodeStub* stub) { +void LIR_Assembler::append_code_stub(CodeStub* stub) { _slow_case_stubs->append(stub); } @@ -442,7 +437,7 @@ void LIR_Assembler::add_debug_info_for_null_check_here(CodeEmitInfo* cinfo) { void LIR_Assembler::add_debug_info_for_null_check(int pc_offset, CodeEmitInfo* cinfo) { ImplicitNullCheckStub* stub = new ImplicitNullCheckStub(pc_offset, cinfo); - emit_code_stub(stub); + append_code_stub(stub); } void LIR_Assembler::add_debug_info_for_div0_here(CodeEmitInfo* info) { @@ -451,7 +446,7 @@ void LIR_Assembler::add_debug_info_for_div0_here(CodeEmitInfo* info) { void LIR_Assembler::add_debug_info_for_div0(int pc_offset, CodeEmitInfo* cinfo) { DivByZeroStub* stub = new DivByZeroStub(pc_offset, cinfo); - emit_code_stub(stub); + append_code_stub(stub); } void LIR_Assembler::emit_rtcall(LIR_OpRTCall* op) { diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 0d4c64823eb..2211b0cc32c 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -144,7 +144,7 @@ class LIR_Assembler: public CompilationResourceObj { // stubs void emit_slow_case_stubs(); void emit_static_call_stub(); - void emit_code_stub(CodeStub* op); + void append_code_stub(CodeStub* op); void add_call_info_here(CodeEmitInfo* info) { add_call_info(code_offset(), info); } // code patterns diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index 14bc1993ff6..4e4caaa26cb 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2782,7 +2782,10 @@ void LIRGenerator::do_Base(Base* x) { __ lock_object(syncTempOpr(), obj, lock, new_register(T_OBJECT), slow_path, NULL); } } - + if (compilation()->age_code()) { + CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, 0), NULL, false); + decrement_age(info); + } // increment invocation counters if needed if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting. profile_parameters(x); @@ -3328,6 +3331,27 @@ void LIRGenerator::increment_event_counter(CodeEmitInfo* info, int bci, bool bac increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true); } +void LIRGenerator::decrement_age(CodeEmitInfo* info) { + ciMethod* method = info->scope()->method(); + MethodCounters* mc_adr = method->ensure_method_counters(); + if (mc_adr != NULL) { + LIR_Opr mc = new_pointer_register(); + __ move(LIR_OprFact::intptrConst(mc_adr), mc); + int offset = in_bytes(MethodCounters::nmethod_age_offset()); + LIR_Address* counter = new LIR_Address(mc, offset, T_INT); + LIR_Opr result = new_register(T_INT); + __ load(counter, result); + __ sub(result, LIR_OprFact::intConst(1), result); + __ store(result, counter); + // DeoptimizeStub will reexecute from the current state in code info. + CodeStub* deopt = new DeoptimizeStub(info, Deoptimization::Reason_tenured, + Deoptimization::Action_make_not_entrant); + __ cmp(lir_cond_lessEqual, result, LIR_OprFact::intConst(0)); + __ branch(lir_cond_lessEqual, T_INT, deopt); + } +} + + void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info, ciMethod *method, int frequency, int bci, bool backedge, bool notify) { diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp index 90b278f4356..13446a9ebe9 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp @@ -372,7 +372,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { increment_event_counter(info, bci, true); } } - + void decrement_age(CodeEmitInfo* info); CodeEmitInfo* state_for(Instruction* x, ValueStack* state, bool ignore_xhandler = false); CodeEmitInfo* state_for(Instruction* x); diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp index 74e04f85dda..91bef59ef17 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp @@ -2382,16 +2382,6 @@ OopMap* LinearScan::compute_oop_map(IntervalWalker* iw, LIR_Op* op, CodeEmitInfo int arg_count = frame_map()->oop_map_arg_count(); OopMap* map = new OopMap(frame_size, arg_count); - // Check if this is a patch site. - bool is_patch_info = false; - if (op->code() == lir_move) { - assert(!is_call_site, "move must not be a call site"); - assert(op->as_Op1() != NULL, "move must be LIR_Op1"); - LIR_Op1* move = (LIR_Op1*)op; - - is_patch_info = move->patch_code() != lir_patch_none; - } - // Iterate through active intervals for (Interval* interval = iw->active_first(fixedKind); interval != Interval::end(); interval = interval->next()) { int assigned_reg = interval->assigned_reg(); @@ -2406,7 +2396,7 @@ OopMap* LinearScan::compute_oop_map(IntervalWalker* iw, LIR_Op* op, CodeEmitInfo // moves, any intervals which end at this instruction are included // in the oop map since we may safepoint while doing the patch // before we've consumed the inputs. - if (is_patch_info || op->id() < interval->current_to()) { + if (op->is_patching() || op->id() < interval->current_to()) { // caller-save registers must not be included into oop-maps at calls assert(!is_call_site || assigned_reg >= nof_regs || !is_caller_save(assigned_reg), "interval is in a caller-save register at a call -> register will be overwritten"); diff --git a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp index 599cedb99d0..71e9de00b30 100644 --- a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp +++ b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,10 +62,10 @@ RangeCheckEliminator::RangeCheckEliminator(IR *ir) : _optimistic = ir->compilation()->is_optimistic(); TRACE_RANGE_CHECK_ELIMINATION( - tty->print_cr(""); + tty->cr(); tty->print_cr("Range check elimination"); ir->method()->print_name(tty); - tty->print_cr(""); + tty->cr(); ); TRACE_RANGE_CHECK_ELIMINATION( @@ -1024,7 +1024,7 @@ void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) { tty->print("i%d", phi->id()); tty->print(": "); bound->print(); - tty->print_cr(""); + tty->cr(); ); } }); @@ -1039,7 +1039,7 @@ void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) { tty->print("i%d", instr->id()); tty->print(": "); bound->print(); - tty->print_cr(""); + tty->cr(); ); } } @@ -1400,7 +1400,7 @@ Value RangeCheckEliminator::Bound::lower_instr() { // print void RangeCheckEliminator::Bound::print() { - tty->print(""); + tty->print("%s", ""); if (this->_lower_instr || this->_lower != min_jint) { if (this->_lower_instr) { tty->print("i%d", this->_lower_instr->id()); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 11542c4a50b..1bafb67f69c 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -532,8 +532,8 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t if (TraceExceptions) { ttyLocker ttyl; ResourceMark rm; - tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " for thread 0x%x", - exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, thread); + tty->print_cr("Exception <%s> (" INTPTR_FORMAT ") thrown in compiled method <%s> at PC " INTPTR_FORMAT " for thread " INTPTR_FORMAT "", + exception->print_value_string(), p2i((address)exception()), nm->method()->print_value_string(), p2i(pc), p2i(thread)); } // for AbortVMOnException flag NOT_PRODUCT(Exceptions::debug_check_abort(exception)); @@ -563,7 +563,7 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t ttyLocker ttyl; ResourceMark rm; tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT, - thread, continuation, pc); + p2i(thread), p2i(continuation), p2i(pc)); } return continuation; @@ -685,19 +685,32 @@ JRT_LEAF(void, Runtime1::monitorexit(JavaThread* thread, BasicObjectLock* lock)) JRT_END // Cf. OptoRuntime::deoptimize_caller_frame -JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread)) +JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread, jint trap_request)) // Called from within the owner thread, so no need for safepoint RegisterMap reg_map(thread, false); frame stub_frame = thread->last_frame(); - assert(stub_frame.is_runtime_frame(), "sanity check"); + assert(stub_frame.is_runtime_frame(), "Sanity check"); frame caller_frame = stub_frame.sender(®_map); + nmethod* nm = caller_frame.cb()->as_nmethod_or_null(); + assert(nm != NULL, "Sanity check"); + methodHandle method(thread, nm->method()); + assert(nm == CodeCache::find_nmethod(caller_frame.pc()), "Should be the same"); + Deoptimization::DeoptAction action = Deoptimization::trap_request_action(trap_request); + Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request); - // We are coming from a compiled method; check this is true. - assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity"); + if (action == Deoptimization::Action_make_not_entrant) { + if (nm->make_not_entrant()) { + if (reason == Deoptimization::Reason_tenured) { + MethodData* trap_mdo = Deoptimization::get_method_data(thread, method, true /*create_if_missing*/); + if (trap_mdo != NULL) { + trap_mdo->inc_tenure_traps(); + } + } + } + } // Deoptimize the caller frame. Deoptimization::deoptimize_frame(thread, caller_frame.id()); - // Return to the now deoptimized frame. JRT_END @@ -988,8 +1001,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i address copy_buff = stub_location - *byte_skip - *byte_count; address being_initialized_entry = stub_location - *being_initialized_entry_offset; if (TracePatching) { - tty->print_cr(" Patching %s at bci %d at address 0x%x (%s)", Bytecodes::name(code), bci, - instr_pc, (stub_id == Runtime1::access_field_patching_id) ? "field" : "klass"); + tty->print_cr(" Patching %s at bci %d at address " INTPTR_FORMAT " (%s)", Bytecodes::name(code), bci, + p2i(instr_pc), (stub_id == Runtime1::access_field_patching_id) ? "field" : "klass"); nmethod* caller_code = CodeCache::find_nmethod(caller_frame.pc()); assert(caller_code != NULL, "nmethod not found"); @@ -1448,7 +1461,7 @@ JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* thread)) methodHandle inlinee = methodHandle(vfst.method()); inlinee->print_short_name(&ss1); m->print_short_name(&ss2); - tty->print_cr("Predicate failed trap in method %s at bci %d inlined in %s at pc %x", ss1.as_string(), vfst.bci(), ss2.as_string(), caller_frame.pc()); + tty->print_cr("Predicate failed trap in method %s at bci %d inlined in %s at pc " INTPTR_FORMAT, ss1.as_string(), vfst.bci(), ss2.as_string(), p2i(caller_frame.pc())); } diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.hpp b/hotspot/src/share/vm/c1/c1_Runtime1.hpp index 276ca44ffbe..9d72a45c891 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp @@ -156,7 +156,7 @@ class Runtime1: public AllStatic { static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock); static void monitorexit (JavaThread* thread, BasicObjectLock* lock); - static void deoptimize(JavaThread* thread); + static void deoptimize(JavaThread* thread, jint trap_request); static int access_field_patching(JavaThread* thread); static int move_klass_patching(JavaThread* thread); diff --git a/hotspot/src/share/vm/c1/c1_ValueType.hpp b/hotspot/src/share/vm/c1/c1_ValueType.hpp index a0bb5647d76..291dd2386d3 100644 --- a/hotspot/src/share/vm/c1/c1_ValueType.hpp +++ b/hotspot/src/share/vm/c1/c1_ValueType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,7 +175,7 @@ class ValueType: public CompilationResourceObj { ValueType* join(ValueType* y) const; // debugging - void print(outputStream* s = tty) { s->print(name()); } + void print(outputStream* s = tty) { s->print("%s", name()); } }; diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp index 24b2830ed83..ae9def38b26 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,6 +158,9 @@ void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { clear_bits(vars, _arg_local); + if (vars.contains_allocated()) { + _allocated_escapes = true; + } } void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) { @@ -1287,10 +1290,10 @@ void BCEscapeAnalyzer::compute_escape_info() { tty->print_cr("class of method is not initialized."); else if (_level > MaxBCEAEstimateLevel) tty->print_cr("level (%d) exceeds MaxBCEAEstimateLevel (%d).", - _level, MaxBCEAEstimateLevel); + _level, (int) MaxBCEAEstimateLevel); else if (method()->code_size() > MaxBCEAEstimateSize) - tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize.", - method()->code_size(), MaxBCEAEstimateSize); + tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize (%d).", + method()->code_size(), (int) MaxBCEAEstimateSize); else ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/ci/ciConstant.cpp b/hotspot/src/share/vm/ci/ciConstant.cpp index 4955a088ffa..a059f2c8a3e 100644 --- a/hotspot/src/share/vm/ci/ciConstant.cpp +++ b/hotspot/src/share/vm/ci/ciConstant.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ void ciConstant::print() { tty->print("%d", _value._int); break; case T_LONG: - tty->print(INT64_FORMAT, _value._long); + tty->print(INT64_FORMAT, (int64_t)(_value._long)); break; case T_FLOAT: tty->print("%f", _value._float); diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index df6017e0a4a..fbe7bbbd83c 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1250,8 +1250,7 @@ void ciEnv::dump_replay_data(int compile_id) { if (replay_data_file != NULL) { fileStream replay_data_stream(replay_data_file, /*need_close=*/true); dump_replay_data(&replay_data_stream); - tty->print("# Compiler replay data is saved as: "); - tty->print_cr(buffer); + tty->print_cr("# Compiler replay data is saved as: %s", buffer); } else { tty->print_cr("# Can't open file to dump replay data."); } @@ -1274,7 +1273,7 @@ void ciEnv::dump_inline_data(int compile_id) { ) replay_data_stream.flush(); tty->print("# Compiler inline data is saved as: "); - tty->print_cr(buffer); + tty->print_cr("%s", buffer); } else { tty->print_cr("# Can't open file to dump inline data."); } diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index f4389da46a6..f8b39ed79c9 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,7 +292,7 @@ bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) { // Implementation of the print method. void ciInstanceKlass::print_impl(outputStream* st) { ciKlass::print_impl(st); - GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());) + GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i((address)loader()));) if (is_loaded()) { st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", bool_to_str(is_initialized()), @@ -618,7 +618,7 @@ class StaticFinalFieldPrinter : public FieldClosure { case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; - case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break; + case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break; case T_FLOAT: { float f = mirror->float_field(fd->offset()); _out->print_cr("%d", *(int*)&f); @@ -626,7 +626,7 @@ class StaticFinalFieldPrinter : public FieldClosure { } case T_DOUBLE: { double d = mirror->double_field(fd->offset()); - _out->print_cr(INT64_FORMAT, *(jlong*)&d); + _out->print_cr(INT64_FORMAT, *(int64_t*)&d); break; } case T_ARRAY: { @@ -656,7 +656,7 @@ class StaticFinalFieldPrinter : public FieldClosure { _out->print_cr("\""); } else { const char* klass_name = value->klass()->name()->as_quoted_ascii(); - _out->print_cr(klass_name); + _out->print_cr("%s", klass_name); } } else { ShouldNotReachHere(); diff --git a/hotspot/src/share/vm/ci/ciMetadata.cpp b/hotspot/src/share/vm/ci/ciMetadata.cpp index fb738798549..efb4f58aef2 100644 --- a/hotspot/src/share/vm/ci/ciMetadata.cpp +++ b/hotspot/src/share/vm/ci/ciMetadata.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ void ciMetadata::print(outputStream* st) { st->print("<%s", type_string()); GUARDED_VM_ENTRY(print_impl(st);) - st->print(" ident=%d address=0x%x>", ident(), (address)this); + st->print(" ident=%d address=" INTPTR_FORMAT ">", ident(), p2i((address)this)); } diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index dbbbb7fabc8..2e4ef93a946 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -129,6 +129,7 @@ ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { constantPoolHandle cpool = h_m()->constants(); _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); _method_data = NULL; + _nmethod_age = h_m()->nmethod_age(); // Take a snapshot of these values, so they will be commensurate with the MDO. if (ProfileInterpreter || TieredCompilation) { int invcnt = h_m()->interpreter_invocation_count(); @@ -1275,6 +1276,14 @@ bool ciMethod::check_call(int refinfo_index, bool is_static) const { return false; } +// ------------------------------------------------------------------ +// ciMethod::profile_aging +// +// Should the method be compiled with an age counter? +bool ciMethod::profile_aging() const { + return UseCodeAging && (!MethodCounters::is_nmethod_hot(nmethod_age()) && + !MethodCounters::is_nmethod_age_unset(nmethod_age())); +} // ------------------------------------------------------------------ // ciMethod::print_codes // diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index e061ea463e5..2b9cf376991 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -68,6 +68,7 @@ class ciMethod : public ciMetadata { int _max_locals; vmIntrinsics::ID _intrinsic_id; int _handler_count; + int _nmethod_age; int _interpreter_invocation_count; int _interpreter_throwout_count; int _instructions_size; @@ -168,6 +169,10 @@ class ciMethod : public ciMetadata { int interpreter_invocation_count() const { check_is_loaded(); return _interpreter_invocation_count; } int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } int size_of_parameters() const { check_is_loaded(); return _size_of_parameters; } + int nmethod_age() const { check_is_loaded(); return _nmethod_age; } + + // Should the method be compiled with an age counter? + bool profile_aging() const; // Code size for inlining decisions. int code_size_for_inlining(); diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index bc8794063ad..9a7c405a2d8 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,7 +177,7 @@ void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) { void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) { - for (int i = 0; i < _number_of_entries; i++) { + for (int i = 0; i < number_of_entries(); i++) { intptr_t k = entries->type(i); TypeStackSlotEntries::set_type(i, translate_klass(k)); } @@ -242,7 +242,6 @@ ciProfileData* ciMethodData::next_data(ciProfileData* current) { } ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) { - // bci_to_extra_data(bci) ... DataLayout* dp = data_layout_at(data_size()); DataLayout* end = data_layout_at(data_size() + extra_data_size()); two_free_slots = false; @@ -506,6 +505,63 @@ void ciMethodData::print_impl(outputStream* st) { ciMetadata::print_impl(st); } +void ciMethodData::dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k) { + if (k != NULL) { + if (round == 0) { + count++; + } else { + out->print(" %d %s", (int)(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)), k->name()->as_quoted_ascii()); + } + } +} + +template void ciMethodData::dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* vdata) { + for (uint i = 0; i < vdata->row_limit(); i++) { + dump_replay_data_type_helper(out, round, count, vdata, vdata->receiver_offset(i), vdata->receiver(i)); + } +} + +template void ciMethodData::dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data) { + if (call_type_data->has_arguments()) { + for (int i = 0; i < call_type_data->number_of_arguments(); i++) { + dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->argument_type_offset(i), call_type_data->valid_argument_type(i)); + } + } + if (call_type_data->has_return()) { + dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->return_type_offset(), call_type_data->valid_return_type()); + } +} + +void ciMethodData::dump_replay_data_extra_data_helper(outputStream* out, int round, int& count) { + DataLayout* dp = data_layout_at(data_size()); + DataLayout* end = data_layout_at(data_size() + extra_data_size()); + + for (;dp < end; dp = MethodData::next_extra(dp)) { + switch(dp->tag()) { + case DataLayout::no_tag: + case DataLayout::arg_info_data_tag: + return; + case DataLayout::bit_data_tag: + break; + case DataLayout::speculative_trap_data_tag: { + ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp); + ciMethod* m = data->method(); + if (m != NULL) { + if (round == 0) { + count++; + } else { + out->print(" %d ", (int)(dp_to_di(((address)dp) + in_bytes(ciSpeculativeTrapData::method_offset())) / sizeof(intptr_t))); + m->dump_name_as_ascii(out); + } + } + break; + } + default: + fatal(err_msg("bad tag = %d", dp->tag())); + } + } +} + void ciMethodData::dump_replay_data(outputStream* out) { ResourceMark rm; MethodData* mdo = get_MethodData(); @@ -527,7 +583,7 @@ void ciMethodData::dump_replay_data(outputStream* out) { } // dump the MDO data as raw data - int elements = data_size() / sizeof(intptr_t); + int elements = (data_size() + extra_data_size()) / sizeof(intptr_t); out->print(" data %d", elements); for (int i = 0; i < elements; i++) { // We could use INTPTR_FORMAT here but that's a zero justified @@ -544,37 +600,35 @@ void ciMethodData::dump_replay_data(outputStream* out) { // and emit pairs of offset and klass name so that they can be // reconstructed at runtime. The first round counts the number of // oop references and the second actually emits them. - int count = 0; - for (int round = 0; round < 2; round++) { + ciParametersTypeData* parameters = parameters_type_data(); + for (int count = 0, round = 0; round < 2; round++) { if (round == 1) out->print(" oops %d", count); ProfileData* pdata = first_data(); for ( ; is_valid(pdata); pdata = next_data(pdata)) { - if (pdata->is_ReceiverTypeData()) { - ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata; - for (uint i = 0; i < vdata->row_limit(); i++) { - ciKlass* k = vdata->receiver(i); - if (k != NULL) { - if (round == 0) { - count++; - } else { - out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii()); - } - } - } - } else if (pdata->is_VirtualCallData()) { + if (pdata->is_VirtualCallData()) { ciVirtualCallData* vdata = (ciVirtualCallData*)pdata; - for (uint i = 0; i < vdata->row_limit(); i++) { - ciKlass* k = vdata->receiver(i); - if (k != NULL) { - if (round == 0) { - count++; - } else { - out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii()); - } - } + dump_replay_data_receiver_type_helper(out, round, count, vdata); + if (pdata->is_VirtualCallTypeData()) { + ciVirtualCallTypeData* call_type_data = (ciVirtualCallTypeData*)pdata; + dump_replay_data_call_type_helper(out, round, count, call_type_data); } + } else if (pdata->is_ReceiverTypeData()) { + ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata; + dump_replay_data_receiver_type_helper(out, round, count, vdata); + } else if (pdata->is_CallTypeData()) { + ciCallTypeData* call_type_data = (ciCallTypeData*)pdata; + dump_replay_data_call_type_helper(out, round, count, call_type_data); } } + if (parameters != NULL) { + for (int i = 0; i < parameters->number_of_parameters(); i++) { + dump_replay_data_type_helper(out, round, count, parameters, ParametersTypeData::type_offset(i), parameters->valid_parameter_type(i)); + } + } + } + for (int count = 0, round = 0; round < 2; round++) { + if (round == 1) out->print(" methods %d", count); + dump_replay_data_extra_data_helper(out, round, count); } out->cr(); } @@ -586,6 +640,10 @@ void ciMethodData::print() { void ciMethodData::print_data_on(outputStream* st) { ResourceMark rm; + ciParametersTypeData* parameters = parameters_type_data(); + if (parameters != NULL) { + parameters->print_data_on(st); + } ciProfileData* data; for (data = first_data(); is_valid(data); data = next_data(data)) { st->print("%d", dp_to_di(data->dp())); @@ -607,6 +665,9 @@ void ciMethodData::print_data_on(outputStream* st) { data = new ciArgInfoData(dp); dp = end; // ArgInfoData is at the end of extra data section. break; + case DataLayout::speculative_trap_data_tag: + data = new ciSpeculativeTrapData(dp); + break; default: fatal(err_msg("unexpected tag %d", dp->tag())); } @@ -631,7 +692,7 @@ void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) { } void ciTypeStackSlotEntries::print_data_on(outputStream* st) const { - for (int i = 0; i < _number_of_entries; i++) { + for (int i = 0; i < number_of_entries(); i++) { _pd->tab(st); st->print("%d: stack (%u) ", i, stack_slot(i)); print_ciklass(st, type(i)); @@ -650,12 +711,12 @@ void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const { print_shared(st, "ciCallTypeData", extra); if (has_arguments()) { tab(st, true); - st->print("argument types"); + st->print_cr("argument types"); args()->print_data_on(st); } if (has_return()) { tab(st, true); - st->print("return type"); + st->print_cr("return type"); ret()->print_data_on(st); } } diff --git a/hotspot/src/share/vm/ci/ciMethodData.hpp b/hotspot/src/share/vm/ci/ciMethodData.hpp index b1809a19d10..9b9f67c446a 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.hpp +++ b/hotspot/src/share/vm/ci/ciMethodData.hpp @@ -45,7 +45,7 @@ class ciArgInfoData; class ciCallTypeData; class ciVirtualCallTypeData; class ciParametersTypeData; -class ciSpeculativeTrapData;; +class ciSpeculativeTrapData; typedef ProfileData ciProfileData; @@ -175,7 +175,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -202,7 +202,7 @@ public: } void translate_receiver_data_from(const ProfileData* data); #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; void print_receiver_data_on(outputStream* st) const; #endif }; @@ -227,7 +227,7 @@ public: rtd_super()->translate_receiver_data_from(data); } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -289,7 +289,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -338,7 +338,7 @@ public: } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -349,15 +349,15 @@ public: virtual void translate_from(const ProfileData* data); ciMethod* method() const { - return (ciMethod*)intptr_at(method_offset); + return (ciMethod*)intptr_at(speculative_trap_method); } void set_method(ciMethod* m) { - set_intptr_at(method_offset, (intptr_t)m); + set_intptr_at(speculative_trap_method, (intptr_t)m); } #ifndef PRODUCT - void print_data_on(outputStream* st, const char* extra) const; + void print_data_on(outputStream* st, const char* extra = NULL) const; #endif }; @@ -406,8 +406,8 @@ private: // Coherent snapshot of original header. MethodData _orig; - // Dedicated area dedicated to parameters. Null if no parameter - // profiling for this method. + // Area dedicated to parameters. NULL if no parameter profiling for + // this method. DataLayout* _parameters; ciMethodData(MethodData* md); @@ -467,6 +467,11 @@ private: void load_extra_data(); ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots); + void dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k); + template void dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data); + template void dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* call_type_data); + void dump_replay_data_extra_data_helper(outputStream* out, int round, int& count); + public: bool is_method_data() const { return true; } diff --git a/hotspot/src/share/vm/ci/ciObject.cpp b/hotspot/src/share/vm/ci/ciObject.cpp index 9685356754c..0fe31d54b13 100644 --- a/hotspot/src/share/vm/ci/ciObject.cpp +++ b/hotspot/src/share/vm/ci/ciObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,9 +213,9 @@ void ciObject::init_flags_from(oop x) { void ciObject::print(outputStream* st) { st->print("<%s", type_string()); GUARDED_VM_ENTRY(print_impl(st);) - st->print(" ident=%d %s address=0x%x>", ident(), + st->print(" ident=%d %s address=" INTPTR_FORMAT ">", ident(), is_scavengable() ? "SCAVENGABLE" : "", - (address)this); + p2i((address)this)); } // ------------------------------------------------------------------ diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp index 6acde213d57..51897b26300 100644 --- a/hotspot/src/share/vm/ci/ciReplay.cpp +++ b/hotspot/src/share/vm/ci/ciReplay.cpp @@ -48,11 +48,14 @@ typedef struct _ciMethodDataRecord { intptr_t* _data; char* _orig_data; - jobject* _oops_handles; - int* _oops_offsets; + Klass** _classes; + Method** _methods; + int* _classes_offsets; + int* _methods_offsets; int _data_length; int _orig_data_length; - int _oops_length; + int _classes_length; + int _methods_length; } ciMethodDataRecord; typedef struct _ciMethodRecord { @@ -565,7 +568,7 @@ class CompileReplay : public StackObj { rec->_instructions_size = parse_int("instructions_size"); } - // ciMethodData orig # # ... data # # ... oops + // ciMethodData orig # # ... data # # ... oops # ... methods void process_ciMethodData(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; @@ -602,21 +605,34 @@ class CompileReplay : public StackObj { if (rec->_data == NULL) { return; } - if (!parse_tag_and_count("oops", rec->_oops_length)) { + if (!parse_tag_and_count("oops", rec->_classes_length)) { return; } - rec->_oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->_oops_length); - rec->_oops_offsets = NEW_RESOURCE_ARRAY(int, rec->_oops_length); - for (int i = 0; i < rec->_oops_length; i++) { + rec->_classes = NEW_RESOURCE_ARRAY(Klass*, rec->_classes_length); + rec->_classes_offsets = NEW_RESOURCE_ARRAY(int, rec->_classes_length); + for (int i = 0; i < rec->_classes_length; i++) { int offset = parse_int("offset"); if (had_error()) { return; } Klass* k = parse_klass(CHECK); - rec->_oops_offsets[i] = offset; - KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler); - ::new ((void*)kh) KlassHandle(THREAD, k); - rec->_oops_handles[i] = (jobject)kh; + rec->_classes_offsets[i] = offset; + rec->_classes[i] = k; + } + + if (!parse_tag_and_count("methods", rec->_methods_length)) { + return; + } + rec->_methods = NEW_RESOURCE_ARRAY(Method*, rec->_methods_length); + rec->_methods_offsets = NEW_RESOURCE_ARRAY(int, rec->_methods_length); + for (int i = 0; i < rec->_methods_length; i++) { + int offset = parse_int("offset"); + if (had_error()) { + return; + } + Method* m = parse_method(CHECK); + rec->_methods_offsets[i] = offset; + rec->_methods[i] = m; } } @@ -1105,14 +1121,22 @@ void ciReplay::initialize(ciMethodData* m) { m->_state = rec->_state; m->_current_mileage = rec->_current_mileage; if (rec->_data_length != 0) { - assert(m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree"); + assert(m->_data_size + m->_extra_data_size == rec->_data_length * (int)sizeof(rec->_data[0]) || + m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree"); // Write the correct ciObjects back into the profile data ciEnv* env = ciEnv::current(); - for (int i = 0; i < rec->_oops_length; i++) { - KlassHandle *h = (KlassHandle *)rec->_oops_handles[i]; - *(ciMetadata**)(rec->_data + rec->_oops_offsets[i]) = - env->get_metadata((*h)()); + for (int i = 0; i < rec->_classes_length; i++) { + Klass *k = rec->_classes[i]; + // In case this class pointer is is tagged, preserve the tag + // bits + rec->_data[rec->_classes_offsets[i]] = + ciTypeEntries::with_status(env->get_metadata(k)->as_klass(), rec->_data[rec->_classes_offsets[i]]); + } + for (int i = 0; i < rec->_methods_length; i++) { + Method *m = rec->_methods[i]; + *(ciMetadata**)(rec->_data + rec->_methods_offsets[i]) = + env->get_metadata(m); } // Copy the updated profile data into place as intptr_ts #ifdef _LP64 diff --git a/hotspot/src/share/vm/ci/ciSignature.cpp b/hotspot/src/share/vm/ci/ciSignature.cpp index d09cc2fd2fe..634ca47981c 100644 --- a/hotspot/src/share/vm/ci/ciSignature.cpp +++ b/hotspot/src/share/vm/ci/ciSignature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,5 +148,5 @@ void ciSignature::print() { print_signature(); tty->print(" accessing_klass="); _accessing_klass->print(); - tty->print(" address=0x%x>", (address)this); + tty->print(" address=" INTPTR_FORMAT ">", p2i((address)this)); } diff --git a/hotspot/src/share/vm/ci/ciType.cpp b/hotspot/src/share/vm/ci/ciType.cpp index 15c884213bb..43df753cb49 100644 --- a/hotspot/src/share/vm/ci/ciType.cpp +++ b/hotspot/src/share/vm/ci/ciType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,7 @@ void ciType::print_impl(outputStream* st) { // Print the name of this type void ciType::print_name_on(outputStream* st) { ResourceMark rm; - st->print(name()); + st->print("%s", name()); } diff --git a/hotspot/src/share/vm/classfile/classFileError.cpp b/hotspot/src/share/vm/classfile/classFileError.cpp index a9c55fb73a5..3c3302fb29f 100644 --- a/hotspot/src/share/vm/classfile/classFileError.cpp +++ b/hotspot/src/share/vm/classfile/classFileError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,9 @@ // Keep these in a separate file to prevent inlining +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED + void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) { ResourceMark rm(THREAD); Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -53,6 +56,8 @@ void ClassFileParser::classfile_parse_error(const char* msg, int index, const ch msg, index, name, _class_name->as_C_string()); } +PRAGMA_DIAG_POP + void StackMapStream::stackmap_format_error(const char* msg, TRAPS) { ResourceMark rm(THREAD); Exceptions::fthrow( diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 8d73c099a71..61d9875c283 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -875,6 +875,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_annotations_exists = false; bool runtime_invisible_type_annotations_exists = false; while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length @@ -920,6 +921,10 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, } generic_signature_index = cfs->get_u2(CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes for field in class file %s", CHECK); + } runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); @@ -928,11 +933,18 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, parsed_annotations, CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK); - } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { - runtime_invisible_annotations_length = attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - cfs->skip_u1(runtime_invisible_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes for field in class file %s", CHECK); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { if (runtime_visible_type_annotations != NULL) { classfile_parse_error( @@ -2066,7 +2078,9 @@ methodHandle ClassFileParser::parse_method(bool is_interface, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_annotations_exists = false; bool runtime_invisible_type_annotations_exists = false; + bool runtime_invisible_parameter_annotations_exists = false; u1* annotation_default = NULL; int annotation_default_length = 0; @@ -2295,6 +2309,10 @@ methodHandle ClassFileParser::parse_method(bool is_interface, cfs->guarantee_more(2, CHECK_(nullHandle)); // generic_signature_index generic_signature_index = cfs->get_u2_fast(); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); @@ -2302,22 +2320,45 @@ methodHandle ClassFileParser::parse_method(bool is_interface, runtime_visible_annotations_length, &parsed_annotations, CHECK_(nullHandle)); cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { - runtime_invisible_annotations_length = method_attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = method_attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) { + if (runtime_visible_parameter_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } runtime_visible_parameter_annotations_length = method_attribute_length; runtime_visible_parameter_annotations = cfs->get_u1_buffer(); assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations"); cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle)); - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { - runtime_invisible_parameter_annotations_length = method_attribute_length; - runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); - cfs->skip_u1(runtime_invisible_parameter_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { + if (runtime_invisible_parameter_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_invisible_parameter_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_parameter_annotations_length = method_attribute_length; + runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_annotation_default()) { + if (annotation_default != NULL) { + classfile_parse_error( + "Multiple AnnotationDefault attributes for method in class file %s", + CHECK_(nullHandle)); + } annotation_default_length = method_attribute_length; annotation_default = cfs->get_u1_buffer(); assert(annotation_default != NULL, "null annotation default"); @@ -2764,7 +2805,7 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_b "Short length on BootstrapMethods in class file %s", CHECK); - guarantee_property(attribute_byte_length > sizeof(u2), + guarantee_property(attribute_byte_length >= sizeof(u2), "Invalid BootstrapMethods attribute length %u in class file %s", attribute_byte_length, CHECK); @@ -2846,6 +2887,8 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; bool runtime_invisible_type_annotations_exists = false; + bool runtime_invisible_annotations_exists = false; + bool parsed_source_debug_ext_annotations_exist = false; u1* inner_classes_attribute_start = NULL; u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; @@ -2873,6 +2916,11 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio parse_classfile_sourcefile_attribute(CHECK); } else if (tag == vmSymbols::tag_source_debug_extension()) { // Check for SourceDebugExtension tag + if (parsed_source_debug_ext_annotations_exist) { + classfile_parse_error( + "Multiple SourceDebugExtension attributes in class file %s", CHECK); + } + parsed_source_debug_ext_annotations_exist = true; parse_classfile_source_debug_extension_attribute((int)attribute_length, CHECK); } else if (tag == vmSymbols::tag_inner_classes()) { // Check for InnerClasses tag @@ -2909,6 +2957,10 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio } parse_classfile_signature_attribute(CHECK); } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes in class file %s", CHECK); + } runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); @@ -2917,11 +2969,18 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio parsed_annotations, CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK); - } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { - runtime_invisible_annotations_length = attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - cfs->skip_u1(runtime_invisible_annotations_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes in class file %s", CHECK); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else if (tag == vmSymbols::tag_enclosing_method()) { if (parsed_enclosingmethod_attribute) { classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index ba12f26fde0..10170eb49eb 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -312,7 +312,9 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { if (!b) { classfile_parse_error(msg, CHECK); } } - inline void assert_property(bool b, const char* msg, TRAPS) { +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED +inline void assert_property(bool b, const char* msg, TRAPS) { #ifdef ASSERT if (!b) { ResourceMark rm(THREAD); @@ -329,6 +331,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { } #endif } +PRAGMA_DIAG_POP inline void check_property(bool property, const char* msg, int index, TRAPS) { if (_need_verify) { diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index c1dcb36dba4..8366c8fc4ce 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -343,7 +343,7 @@ static void print_meta_index(LazyClassPathEntry* entry, tty->print("[Meta index for %s=", entry->name()); for (int i = 0; i < meta_packages.length(); i++) { if (i > 0) tty->print(" "); - tty->print(meta_packages.at(i)); + tty->print("%s", meta_packages.at(i)); } tty->print_cr("]"); } @@ -1299,7 +1299,7 @@ void ClassLoader::compile_the_world() { e = e->next(); } jlong end = os::javaTimeMillis(); - tty->print_cr("CompileTheWorld : Done (%d classes, %d methods, %d ms)", + tty->print_cr("CompileTheWorld : Done (%d classes, %d methods, " JLONG_FORMAT " ms)", _compile_the_world_class_counter, _compile_the_world_method_counter, (end - start)); { // Print statistics as if before normal exit: diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index efd141332dc..bc88beb4343 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -274,6 +274,8 @@ void ClassLoaderData::add_class(Klass* k) { MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); Klass* old_value = _klasses; k->set_next_link(old_value); + // Make sure linked class is stable, since the class list is walked without a lock + OrderAccess::storestore(); // link the new item into the list _klasses = k; @@ -281,10 +283,10 @@ void ClassLoaderData::add_class(Klass* k) { ResourceMark rm; tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: " PTR_FORMAT " loader: " PTR_FORMAT " %s", - k, + p2i(k), k->external_name(), - k->class_loader_data(), - (void *)k->class_loader(), + p2i(k->class_loader_data()), + p2i((void *)k->class_loader()), loader_name()); } } @@ -319,11 +321,11 @@ void ClassLoaderData::unload() { if (TraceClassLoaderData) { ResourceMark rm; - tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this); - tty->print(" for instance "PTR_FORMAT" of %s", (void *)class_loader(), + tty->print("[ClassLoaderData: unload loader data " INTPTR_FORMAT, p2i(this)); + tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()), loader_name()); if (is_anonymous()) { - tty->print(" for anonymous class "PTR_FORMAT " ", _klasses); + tty->print(" for anonymous class " INTPTR_FORMAT " ", p2i(_klasses)); } tty->print_cr("]"); } @@ -485,14 +487,14 @@ const char* ClassLoaderData::loader_name() { void ClassLoaderData::dump(outputStream * const out) { ResourceMark rm; out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {", - this, (void *)class_loader(), - class_loader() != NULL ? class_loader()->klass() : NULL, loader_name()); + p2i(this), p2i((void *)class_loader()), + p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); if (claimed()) out->print(" claimed "); if (is_unloading()) out->print(" unloading "); - out->print(" handles " INTPTR_FORMAT, handles()); + out->print(" handles " INTPTR_FORMAT, p2i(handles())); out->cr(); if (metaspace_or_null() != NULL) { - out->print_cr("metaspace: " PTR_FORMAT, metaspace_or_null()); + out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); metaspace_or_null()->dump(out); } else { out->print_cr("metaspace: NULL"); @@ -549,6 +551,8 @@ ClassLoaderData* ClassLoaderDataGraph::_head = NULL; ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; +bool ClassLoaderDataGraph::_should_purge = false; + // Add a new class loader data node to the list. Assign the newly created // ClassLoaderData into the java/lang/ClassLoader object as a hidden field ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { @@ -586,8 +590,8 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRA if (TraceClassLoaderData) { ResourceMark rm; tty->print("[ClassLoaderData: "); - tty->print("create class loader data "PTR_FORMAT, cld); - tty->print(" for instance "PTR_FORMAT" of %s", (void *)cld->class_loader(), + tty->print("create class loader data " INTPTR_FORMAT, p2i(cld)); + tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()), cld->loader_name()); tty->print_cr("]"); } @@ -675,32 +679,6 @@ GrowableArray* ClassLoaderDataGraph::new_clds() { return array; } -// For profiling and hsfind() only. Otherwise, this is unsafe (and slow). This -// is done lock free to avoid lock inversion problems. It is safe because -// new ClassLoaderData are added to the end of the CLDG, and only removed at -// safepoint. The _unloading list can be deallocated concurrently with CMS so -// this doesn't look in metaspace for classes that have been unloaded. -bool ClassLoaderDataGraph::contains(const void* x) { - if (DumpSharedSpaces) { - // There are only two metaspaces to worry about. - ClassLoaderData* ncld = ClassLoaderData::the_null_class_loader_data(); - return (ncld->ro_metaspace()->contains(x) || ncld->rw_metaspace()->contains(x)); - } - - if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(x)) { - return true; - } - - for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { - if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) { - return true; - } - } - - // Do not check unloading list because deallocation can be concurrent. - return false; -} - #ifndef PRODUCT bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { @@ -759,6 +737,7 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { } void ClassLoaderDataGraph::purge() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); ClassLoaderData* list = _unloading; _unloading = NULL; ClassLoaderData* next = list; @@ -847,7 +826,7 @@ void ClassLoaderData::print_value_on(outputStream* out) const { if (class_loader() == NULL) { out->print("NULL class_loader"); } else { - out->print("class loader "PTR_FORMAT, this); + out->print("class loader " INTPTR_FORMAT, p2i(this)); class_loader()->print_value_on(out); } } diff --git a/hotspot/src/share/vm/classfile/classLoaderData.hpp b/hotspot/src/share/vm/classfile/classLoaderData.hpp index e03d1625045..5be3caa6515 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.hpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp @@ -66,6 +66,7 @@ class ClassLoaderDataGraph : public AllStatic { static ClassLoaderData* _unloading; // CMS support. static ClassLoaderData* _saved_head; + static bool _should_purge; static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS); static void post_class_unload_events(void); @@ -87,12 +88,20 @@ class ClassLoaderDataGraph : public AllStatic { static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); } static GrowableArray* new_clds(); + static void set_should_purge(bool b) { _should_purge = b; } + static void purge_if_needed() { + // Only purge the CLDG for CMS if concurrent sweep is complete. + if (_should_purge) { + purge(); + // reset for next time. + set_should_purge(false); + } + } + static void dump_on(outputStream * const out) PRODUCT_RETURN; static void dump() { dump_on(tty); } static void verify(); - // expensive test for pointer in metaspace for debugging - static bool contains(const void* x); #ifndef PRODUCT static bool contains_loader_data(ClassLoaderData* loader_data); #endif diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index b5e4da63f0f..1b56ff2fba4 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -436,7 +436,7 @@ class MethodFamily : public ResourceObj { _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); if (TraceDefaultMethods) { _exception_message->print_value_on(tty); - tty->print_cr(""); + tty->cr(); } } } @@ -463,7 +463,7 @@ class MethodFamily : public ResourceObj { if (_members.at(i).second == DISQUALIFIED) { str->print(" (disqualified)"); } - str->print_cr(""); + str->cr(); } if (_selected_target != NULL) { @@ -480,7 +480,7 @@ class MethodFamily : public ResourceObj { if (!method_holder->is_interface()) { tty->print(" : in superclass"); } - str->print_cr(""); + str->cr(); } void print_exception(outputStream* str, int indent) { @@ -688,7 +688,7 @@ static GrowableArray* find_empty_vtable_slots( for (int i = 0; i < slots->length(); ++i) { tty->indent(); slots->at(i)->print_on(tty); - tty->print_cr(""); + tty->cr(); } } #endif // ndef PRODUCT @@ -828,7 +828,7 @@ void DefaultMethods::generate_default_methods( streamIndentor si(tty, 2); tty->indent().print("Looking for default methods for slot "); slot->print_on(tty); - tty->print_cr(""); + tty->cr(); } #endif // ndef PRODUCT @@ -946,7 +946,7 @@ static void create_defaults_and_exceptions( if (TraceDefaultMethods) { tty->print("for slot: "); slot->print_on(tty); - tty->print_cr(""); + tty->cr(); if (method->has_target()) { method->print_selected(tty, 1); } else if (method->throws_exception()) { diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp index ec64adc2476..b84475a8dbb 100644 --- a/hotspot/src/share/vm/classfile/dictionary.cpp +++ b/hotspot/src/share/vm/classfile/dictionary.cpp @@ -31,6 +31,7 @@ #include "runtime/orderAccess.inline.hpp" #include "utilities/hashtable.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC DictionaryEntry* Dictionary::_current_class_entry = NULL; int Dictionary::_current_class_index = 0; diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp index 17d916f0629..bc25c811c52 100644 --- a/hotspot/src/share/vm/classfile/dictionary.hpp +++ b/hotspot/src/share/vm/classfile/dictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -379,7 +379,7 @@ class SymbolPropertyEntry : public HashtableEntry { } if (method_type() != NULL) { if (printed) st->print(" and "); - st->print(INTPTR_FORMAT, (void *)method_type()); + st->print(INTPTR_FORMAT, p2i((void *)method_type())); printed = true; } st->print_cr(printed ? "" : "(empty)"); diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index a9d213948eb..628ddf910b7 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/vmSymbols.hpp" #include "code/debugInfo.hpp" #include "code/pcDesc.hpp" @@ -51,6 +51,8 @@ #include "runtime/vframe.hpp" #include "utilities/preserveException.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum); @@ -1490,7 +1492,7 @@ void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { while (h_throwable.not_null()) { objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); if (result.is_null()) { - st->print_cr(no_stack_trace_message()); + st->print_cr("%s", no_stack_trace_message()); return; } diff --git a/hotspot/src/share/vm/classfile/stringTable.cpp b/hotspot/src/share/vm/classfile/stringTable.cpp new file mode 100644 index 00000000000..07ccbd354dc --- /dev/null +++ b/hotspot/src/share/vm/classfile/stringTable.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "classfile/altHashing.hpp" +#include "classfile/javaClasses.hpp" +#include "classfile/stringTable.hpp" +#include "classfile/systemDictionary.hpp" +#include "gc_interface/collectedHeap.inline.hpp" +#include "memory/allocation.inline.hpp" +#include "memory/filemap.hpp" +#include "memory/gcLocker.inline.hpp" +#include "oops/oop.inline.hpp" +#include "oops/oop.inline2.hpp" +#include "runtime/mutexLocker.hpp" +#include "utilities/hashtable.inline.hpp" +#if INCLUDE_ALL_GCS +#include "gc_implementation/g1/g1StringDedup.hpp" +#endif + +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + +// the number of buckets a thread claims +const int ClaimChunkSize = 32; + +#ifdef ASSERT +class StableMemoryChecker : public StackObj { + enum { _bufsize = wordSize*4 }; + + address _region; + jint _size; + u1 _save_buf[_bufsize]; + + int sample(u1* save_buf) { + if (_size <= _bufsize) { + memcpy(save_buf, _region, _size); + return _size; + } else { + // copy head and tail + memcpy(&save_buf[0], _region, _bufsize/2); + memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2); + return (_bufsize/2)*2; + } + } + + public: + StableMemoryChecker(const void* region, jint size) { + _region = (address) region; + _size = size; + sample(_save_buf); + } + + bool verify() { + u1 check_buf[sizeof(_save_buf)]; + int check_size = sample(check_buf); + return (0 == memcmp(_save_buf, check_buf, check_size)); + } + + void set_region(const void* region) { _region = (address) region; } +}; +#endif + + +// -------------------------------------------------------------------------- +StringTable* StringTable::_the_table = NULL; + +bool StringTable::_needs_rehashing = false; + +volatile int StringTable::_parallel_claimed_idx = 0; + +// Pick hashing algorithm +unsigned int StringTable::hash_string(const jchar* s, int len) { + return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : + java_lang_String::hash_code(s, len); +} + +oop StringTable::lookup(int index, jchar* name, + int len, unsigned int hash) { + int count = 0; + for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { + count++; + if (l->hash() == hash) { + if (java_lang_String::equals(l->literal(), name, len)) { + return l->literal(); + } + } + } + // If the bucket size is too deep check if this hash code is insufficient. + if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { + _needs_rehashing = check_rehash_table(count); + } + return NULL; +} + + +oop StringTable::basic_add(int index_arg, Handle string, jchar* name, + int len, unsigned int hashValue_arg, TRAPS) { + + assert(java_lang_String::equals(string(), name, len), + "string must be properly initialized"); + // Cannot hit a safepoint in this function because the "this" pointer can move. + No_Safepoint_Verifier nsv; + + // Check if the symbol table has been rehashed, if so, need to recalculate + // the hash value and index before second lookup. + unsigned int hashValue; + int index; + if (use_alternate_hashcode()) { + hashValue = hash_string(name, len); + index = hash_to_index(hashValue); + } else { + hashValue = hashValue_arg; + index = index_arg; + } + + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. + + oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int) + if (test != NULL) { + // Entry already added + return test; + } + + HashtableEntry* entry = new_entry(hashValue, string()); + add_entry(index, entry); + return string(); +} + + +oop StringTable::lookup(Symbol* symbol) { + ResourceMark rm; + int length; + jchar* chars = symbol->as_unicode(length); + return lookup(chars, length); +} + + +oop StringTable::lookup(jchar* name, int len) { + unsigned int hash = hash_string(name, len); + int index = the_table()->hash_to_index(hash); + return the_table()->lookup(index, name, len, hash); +} + + +oop StringTable::intern(Handle string_or_null, jchar* name, + int len, TRAPS) { + unsigned int hashValue = hash_string(name, len); + int index = the_table()->hash_to_index(hashValue); + oop found_string = the_table()->lookup(index, name, len, hashValue); + + // Found + if (found_string != NULL) return found_string; + + debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); + assert(!Universe::heap()->is_in_reserved(name), + "proposed name of symbol must be stable"); + + Handle string; + // try to reuse the string if possible + if (!string_or_null.is_null()) { + string = string_or_null; + } else { + string = java_lang_String::create_from_unicode(name, len, CHECK_NULL); + } + +#if INCLUDE_ALL_GCS + if (G1StringDedup::is_enabled()) { + // Deduplicate the string before it is interned. Note that we should never + // deduplicate a string after it has been interned. Doing so will counteract + // compiler optimizations done on e.g. interned string literals. + G1StringDedup::deduplicate(string()); + } +#endif + + // Grab the StringTable_lock before getting the_table() because it could + // change at safepoint. + MutexLocker ml(StringTable_lock, THREAD); + + // Otherwise, add to symbol to table + return the_table()->basic_add(index, string, name, len, + hashValue, CHECK_NULL); +} + +oop StringTable::intern(Symbol* symbol, TRAPS) { + if (symbol == NULL) return NULL; + ResourceMark rm(THREAD); + int length; + jchar* chars = symbol->as_unicode(length); + Handle string; + oop result = intern(string, chars, length, CHECK_NULL); + return result; +} + + +oop StringTable::intern(oop string, TRAPS) +{ + if (string == NULL) return NULL; + ResourceMark rm(THREAD); + int length; + Handle h_string (THREAD, string); + jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL); + oop result = intern(h_string, chars, length, CHECK_NULL); + return result; +} + + +oop StringTable::intern(const char* utf8_string, TRAPS) { + if (utf8_string == NULL) return NULL; + ResourceMark rm(THREAD); + int length = UTF8::unicode_length(utf8_string); + jchar* chars = NEW_RESOURCE_ARRAY(jchar, length); + UTF8::convert_to_unicode(utf8_string, chars, length); + Handle string; + oop result = intern(string, chars, length, CHECK_NULL); + return result; +} + +void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { + buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed); +} + +void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { + // Readers of the table are unlocked, so we should only be removing + // entries at a safepoint. + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + const int limit = the_table()->table_size(); + + for (;;) { + // Grab next set of buckets to scan + int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; + if (start_idx >= limit) { + // End of table + break; + } + + int end_idx = MIN2(limit, start_idx + ClaimChunkSize); + buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed); + } +} + +void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { + const int limit = the_table()->table_size(); + + assert(0 <= start_idx && start_idx <= limit, + err_msg("start_idx (%d) is out of bounds", start_idx)); + assert(0 <= end_idx && end_idx <= limit, + err_msg("end_idx (%d) is out of bounds", end_idx)); + assert(start_idx <= end_idx, + err_msg("Index ordering: start_idx=%d, end_idx=%d", + start_idx, end_idx)); + + for (int i = start_idx; i < end_idx; i += 1) { + HashtableEntry* entry = the_table()->bucket(i); + while (entry != NULL) { + assert(!entry->is_shared(), "CDS not used for the StringTable"); + + f->do_oop((oop*)entry->literal_addr()); + + entry = entry->next(); + } + } +} + +void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) { + const int limit = the_table()->table_size(); + + assert(0 <= start_idx && start_idx <= limit, + err_msg("start_idx (%d) is out of bounds", start_idx)); + assert(0 <= end_idx && end_idx <= limit, + err_msg("end_idx (%d) is out of bounds", end_idx)); + assert(start_idx <= end_idx, + err_msg("Index ordering: start_idx=%d, end_idx=%d", + start_idx, end_idx)); + + for (int i = start_idx; i < end_idx; ++i) { + HashtableEntry** p = the_table()->bucket_addr(i); + HashtableEntry* entry = the_table()->bucket(i); + while (entry != NULL) { + assert(!entry->is_shared(), "CDS not used for the StringTable"); + + if (is_alive->do_object_b(entry->literal())) { + if (f != NULL) { + f->do_oop((oop*)entry->literal_addr()); + } + p = entry->next_addr(); + } else { + *p = entry->next(); + the_table()->free_entry(entry); + (*removed)++; + } + (*processed)++; + entry = *p; + } + } +} + +void StringTable::oops_do(OopClosure* f) { + buckets_oops_do(f, 0, the_table()->table_size()); +} + +void StringTable::possibly_parallel_oops_do(OopClosure* f) { + const int limit = the_table()->table_size(); + + for (;;) { + // Grab next set of buckets to scan + int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; + if (start_idx >= limit) { + // End of table + break; + } + + int end_idx = MIN2(limit, start_idx + ClaimChunkSize); + buckets_oops_do(f, start_idx, end_idx); + } +} + +// This verification is part of Universe::verify() and needs to be quick. +// See StringTable::verify_and_compare() below for exhaustive verification. +void StringTable::verify() { + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + oop s = p->literal(); + guarantee(s != NULL, "interned string is NULL"); + unsigned int h = java_lang_String::hash_string(s); + guarantee(p->hash() == h, "broken hash in string table entry"); + guarantee(the_table()->hash_to_index(h) == i, + "wrong index in string table"); + } + } +} + +void StringTable::dump(outputStream* st) { + the_table()->dump_table(st, "StringTable"); +} + +StringTable::VerifyRetTypes StringTable::compare_entries( + int bkt1, int e_cnt1, + HashtableEntry* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry* e_ptr2) { + // These entries are sanity checked by verify_and_compare_entries() + // before this function is called. + oop str1 = e_ptr1->literal(); + oop str2 = e_ptr2->literal(); + + if (str1 == str2) { + tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " + "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", + (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + if (java_lang_String::equals(str1, str2)) { + tty->print_cr("ERROR: identical String values in entry @ " + "bucket[%d][%d] and entry @ bucket[%d][%d]", + bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + return _verify_pass; +} + +StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, + HashtableEntry* e_ptr, + StringTable::VerifyMesgModes mesg_mode) { + + VerifyRetTypes ret = _verify_pass; // be optimistic + + oop str = e_ptr->literal(); + if (str == NULL) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, + e_cnt); + } + // NULL oop means no more verifications are possible + return _verify_fail_done; + } + + if (str->klass() != SystemDictionary::String_klass()) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", + bkt, e_cnt); + } + // not a String means no more verifications are possible + return _verify_fail_done; + } + + unsigned int h = java_lang_String::hash_string(str); + if (e_ptr->hash() != h) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " + "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); + } + ret = _verify_fail_continue; + } + + if (the_table()->hash_to_index(h) != bkt) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " + "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, + the_table()->hash_to_index(h)); + } + ret = _verify_fail_continue; + } + + return ret; +} + +// See StringTable::verify() above for the quick verification that is +// part of Universe::verify(). This verification is exhaustive and +// reports on every issue that is found. StringTable::verify() only +// reports on the first issue that is found. +// +// StringTable::verify_entry() checks: +// - oop value != NULL (same as verify()) +// - oop value is a String +// - hash(String) == hash in entry (same as verify()) +// - index for hash == index of entry (same as verify()) +// +// StringTable::compare_entries() checks: +// - oops are unique across all entries +// - String values are unique across all entries +// +int StringTable::verify_and_compare_entries() { + assert(StringTable_lock->is_locked(), "sanity check"); + + int fail_cnt = 0; + + // first, verify all the entries individually: + for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { + HashtableEntry* e_ptr = the_table()->bucket(bkt); + for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { + VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); + if (ret != _verify_pass) { + fail_cnt++; + } + } + } + + // Optimization: if the above check did not find any failures, then + // the comparison loop below does not need to call verify_entry() + // before calling compare_entries(). If there were failures, then we + // have to call verify_entry() to see if the entry can be passed to + // compare_entries() safely. When we call verify_entry() in the loop + // below, we do so quietly to void duplicate messages and we don't + // increment fail_cnt because the failures have already been counted. + bool need_entry_verify = (fail_cnt != 0); + + // second, verify all entries relative to each other: + for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { + HashtableEntry* e_ptr1 = the_table()->bucket(bkt1); + for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot use the current entry to compare against other entries + continue; + } + } + + for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { + HashtableEntry* e_ptr2 = the_table()->bucket(bkt2); + int e_cnt2; + for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { + if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { + // skip the entries up to and including the one that + // we're comparing against + continue; + } + + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot compare against this entry + continue; + } + } + + // compare two entries, report and count any failures: + if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) + != _verify_pass) { + fail_cnt++; + } + } + } + } + } + return fail_cnt; +} + +// Create a new table and using alternate hash code, populate the new table +// with the existing strings. Set flag to use the alternate hash code afterwards. +void StringTable::rehash_table() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + // This should never happen with -Xshare:dump but it might in testing mode. + if (DumpSharedSpaces) return; + StringTable* new_table = new StringTable(); + + // Rehash the table + the_table()->move_to(new_table); + + // Delete the table and buckets (entries are reused in new table). + delete _the_table; + // Don't check if we need rehashing until the table gets unbalanced again. + // Then rehash with a new global seed. + _needs_rehashing = false; + _the_table = new_table; +} diff --git a/hotspot/src/share/vm/classfile/stringTable.hpp b/hotspot/src/share/vm/classfile/stringTable.hpp new file mode 100644 index 00000000000..af6f909f200 --- /dev/null +++ b/hotspot/src/share/vm/classfile/stringTable.hpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_CLASSFILE_STRINGTABLE_HPP +#define SHARE_VM_CLASSFILE_STRINGTABLE_HPP + +#include "memory/allocation.inline.hpp" +#include "utilities/hashtable.hpp" + +class StringTable : public Hashtable { + friend class VMStructs; + friend class Symbol; + +private: + // The string table + static StringTable* _the_table; + + // Set if one bucket is out of balance due to hash algorithm deficiency + static bool _needs_rehashing; + + // Claimed high water mark for parallel chunked scanning + static volatile int _parallel_claimed_idx; + + static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); + oop basic_add(int index, Handle string_or_null, jchar* name, int len, + unsigned int hashValue, TRAPS); + + oop lookup(int index, jchar* chars, int length, unsigned int hashValue); + + // Apply the give oop closure to the entries to the buckets + // in the range [start_idx, end_idx). + static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); + // Unlink or apply the give oop closure to the entries to the buckets + // in the range [start_idx, end_idx). + static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); + + StringTable() : Hashtable((int)StringTableSize, + sizeof (HashtableEntry)) {} + + StringTable(HashtableBucket* t, int number_of_entries) + : Hashtable((int)StringTableSize, sizeof (HashtableEntry), t, + number_of_entries) {} +public: + // The string table + static StringTable* the_table() { return _the_table; } + + // Size of one bucket in the string table. Used when checking for rollover. + static uint bucket_size() { return sizeof(HashtableBucket); } + + static void create_table() { + assert(_the_table == NULL, "One string table allowed."); + _the_table = new StringTable(); + } + + // GC support + // Delete pointers to otherwise-unreachable objects. + static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { + int processed = 0; + int removed = 0; + unlink_or_oops_do(cl, f, &processed, &removed); + } + static void unlink(BoolObjectClosure* cl) { + int processed = 0; + int removed = 0; + unlink_or_oops_do(cl, NULL, &processed, &removed); + } + static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); + static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { + unlink_or_oops_do(cl, NULL, processed, removed); + } + // Serially invoke "f->do_oop" on the locations of all oops in the table. + static void oops_do(OopClosure* f); + + // Possibly parallel versions of the above + static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); + static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { + possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); + } + static void possibly_parallel_oops_do(OopClosure* f); + + // Hashing algorithm, used as the hash value used by the + // StringTable for bucket selection and comparison (stored in the + // HashtableEntry structures). This is used in the String.intern() method. + static unsigned int hash_string(const jchar* s, int len); + + // Internal test. + static void test_alt_hash() PRODUCT_RETURN; + + // Probing + static oop lookup(Symbol* symbol); + static oop lookup(jchar* chars, int length); + + // Interning + static oop intern(Symbol* symbol, TRAPS); + static oop intern(oop string, TRAPS); + static oop intern(const char *utf8_string, TRAPS); + + // Debugging + static void verify(); + static void dump(outputStream* st); + + enum VerifyMesgModes { + _verify_quietly = 0, + _verify_with_mesgs = 1 + }; + + enum VerifyRetTypes { + _verify_pass = 0, + _verify_fail_continue = 1, + _verify_fail_done = 2 + }; + + static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, + HashtableEntry* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry* e_ptr2); + static VerifyRetTypes verify_entry(int bkt, int e_cnt, + HashtableEntry* e_ptr, + VerifyMesgModes mesg_mode); + static int verify_and_compare_entries(); + + // Sharing + static void copy_buckets(char** top, char*end) { + the_table()->Hashtable::copy_buckets(top, end); + } + static void copy_table(char** top, char*end) { + the_table()->Hashtable::copy_table(top, end); + } + static void reverse() { + the_table()->Hashtable::reverse(); + } + + // Rehash the symbol table if it gets out of balance + static void rehash_table(); + static bool needs_rehashing() { return _needs_rehashing; } + + // Parallel chunked scanning + static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } + static int parallel_claimed_index() { return _parallel_claimed_idx; } +}; +#endif // SHARE_VM_CLASSFILE_STRINGTABLE_HPP diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index 40a06da9b34..dddf271e42a 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -35,12 +35,10 @@ #include "oops/oop.inline2.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" -#if INCLUDE_ALL_GCS -#include "gc_implementation/g1/g1StringDedup.hpp" -#endif + +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // -------------------------------------------------------------------------- - // the number of buckets a thread claims const int ClaimChunkSize = 32; @@ -587,493 +585,3 @@ void SymbolTable::print() { } } #endif // PRODUCT - -// -------------------------------------------------------------------------- - -#ifdef ASSERT -class StableMemoryChecker : public StackObj { - enum { _bufsize = wordSize*4 }; - - address _region; - jint _size; - u1 _save_buf[_bufsize]; - - int sample(u1* save_buf) { - if (_size <= _bufsize) { - memcpy(save_buf, _region, _size); - return _size; - } else { - // copy head and tail - memcpy(&save_buf[0], _region, _bufsize/2); - memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2); - return (_bufsize/2)*2; - } - } - - public: - StableMemoryChecker(const void* region, jint size) { - _region = (address) region; - _size = size; - sample(_save_buf); - } - - bool verify() { - u1 check_buf[sizeof(_save_buf)]; - int check_size = sample(check_buf); - return (0 == memcmp(_save_buf, check_buf, check_size)); - } - - void set_region(const void* region) { _region = (address) region; } -}; -#endif - - -// -------------------------------------------------------------------------- -StringTable* StringTable::_the_table = NULL; - -bool StringTable::_needs_rehashing = false; - -volatile int StringTable::_parallel_claimed_idx = 0; - -// Pick hashing algorithm -unsigned int StringTable::hash_string(const jchar* s, int len) { - return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : - java_lang_String::hash_code(s, len); -} - -oop StringTable::lookup(int index, jchar* name, - int len, unsigned int hash) { - int count = 0; - for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { - count++; - if (l->hash() == hash) { - if (java_lang_String::equals(l->literal(), name, len)) { - return l->literal(); - } - } - } - // If the bucket size is too deep check if this hash code is insufficient. - if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { - _needs_rehashing = check_rehash_table(count); - } - return NULL; -} - - -oop StringTable::basic_add(int index_arg, Handle string, jchar* name, - int len, unsigned int hashValue_arg, TRAPS) { - - assert(java_lang_String::equals(string(), name, len), - "string must be properly initialized"); - // Cannot hit a safepoint in this function because the "this" pointer can move. - No_Safepoint_Verifier nsv; - - // Check if the symbol table has been rehashed, if so, need to recalculate - // the hash value and index before second lookup. - unsigned int hashValue; - int index; - if (use_alternate_hashcode()) { - hashValue = hash_string(name, len); - index = hash_to_index(hashValue); - } else { - hashValue = hashValue_arg; - index = index_arg; - } - - // Since look-up was done lock-free, we need to check if another - // thread beat us in the race to insert the symbol. - - oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int) - if (test != NULL) { - // Entry already added - return test; - } - - HashtableEntry* entry = new_entry(hashValue, string()); - add_entry(index, entry); - return string(); -} - - -oop StringTable::lookup(Symbol* symbol) { - ResourceMark rm; - int length; - jchar* chars = symbol->as_unicode(length); - return lookup(chars, length); -} - - -oop StringTable::lookup(jchar* name, int len) { - unsigned int hash = hash_string(name, len); - int index = the_table()->hash_to_index(hash); - return the_table()->lookup(index, name, len, hash); -} - - -oop StringTable::intern(Handle string_or_null, jchar* name, - int len, TRAPS) { - unsigned int hashValue = hash_string(name, len); - int index = the_table()->hash_to_index(hashValue); - oop found_string = the_table()->lookup(index, name, len, hashValue); - - // Found - if (found_string != NULL) return found_string; - - debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); - assert(!Universe::heap()->is_in_reserved(name), - "proposed name of symbol must be stable"); - - Handle string; - // try to reuse the string if possible - if (!string_or_null.is_null()) { - string = string_or_null; - } else { - string = java_lang_String::create_from_unicode(name, len, CHECK_NULL); - } - -#if INCLUDE_ALL_GCS - if (G1StringDedup::is_enabled()) { - // Deduplicate the string before it is interned. Note that we should never - // deduplicate a string after it has been interned. Doing so will counteract - // compiler optimizations done on e.g. interned string literals. - G1StringDedup::deduplicate(string()); - } -#endif - - // Grab the StringTable_lock before getting the_table() because it could - // change at safepoint. - MutexLocker ml(StringTable_lock, THREAD); - - // Otherwise, add to symbol to table - return the_table()->basic_add(index, string, name, len, - hashValue, CHECK_NULL); -} - -oop StringTable::intern(Symbol* symbol, TRAPS) { - if (symbol == NULL) return NULL; - ResourceMark rm(THREAD); - int length; - jchar* chars = symbol->as_unicode(length); - Handle string; - oop result = intern(string, chars, length, CHECK_NULL); - return result; -} - - -oop StringTable::intern(oop string, TRAPS) -{ - if (string == NULL) return NULL; - ResourceMark rm(THREAD); - int length; - Handle h_string (THREAD, string); - jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL); - oop result = intern(h_string, chars, length, CHECK_NULL); - return result; -} - - -oop StringTable::intern(const char* utf8_string, TRAPS) { - if (utf8_string == NULL) return NULL; - ResourceMark rm(THREAD); - int length = UTF8::unicode_length(utf8_string); - jchar* chars = NEW_RESOURCE_ARRAY(jchar, length); - UTF8::convert_to_unicode(utf8_string, chars, length); - Handle string; - oop result = intern(string, chars, length, CHECK_NULL); - return result; -} - -void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { - buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed); -} - -void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { - // Readers of the table are unlocked, so we should only be removing - // entries at a safepoint. - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); - const int limit = the_table()->table_size(); - - for (;;) { - // Grab next set of buckets to scan - int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; - if (start_idx >= limit) { - // End of table - break; - } - - int end_idx = MIN2(limit, start_idx + ClaimChunkSize); - buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed); - } -} - -void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { - const int limit = the_table()->table_size(); - - assert(0 <= start_idx && start_idx <= limit, - err_msg("start_idx (%d) is out of bounds", start_idx)); - assert(0 <= end_idx && end_idx <= limit, - err_msg("end_idx (%d) is out of bounds", end_idx)); - assert(start_idx <= end_idx, - err_msg("Index ordering: start_idx=%d, end_idx=%d", - start_idx, end_idx)); - - for (int i = start_idx; i < end_idx; i += 1) { - HashtableEntry* entry = the_table()->bucket(i); - while (entry != NULL) { - assert(!entry->is_shared(), "CDS not used for the StringTable"); - - f->do_oop((oop*)entry->literal_addr()); - - entry = entry->next(); - } - } -} - -void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) { - const int limit = the_table()->table_size(); - - assert(0 <= start_idx && start_idx <= limit, - err_msg("start_idx (%d) is out of bounds", start_idx)); - assert(0 <= end_idx && end_idx <= limit, - err_msg("end_idx (%d) is out of bounds", end_idx)); - assert(start_idx <= end_idx, - err_msg("Index ordering: start_idx=%d, end_idx=%d", - start_idx, end_idx)); - - for (int i = start_idx; i < end_idx; ++i) { - HashtableEntry** p = the_table()->bucket_addr(i); - HashtableEntry* entry = the_table()->bucket(i); - while (entry != NULL) { - assert(!entry->is_shared(), "CDS not used for the StringTable"); - - if (is_alive->do_object_b(entry->literal())) { - if (f != NULL) { - f->do_oop((oop*)entry->literal_addr()); - } - p = entry->next_addr(); - } else { - *p = entry->next(); - the_table()->free_entry(entry); - (*removed)++; - } - (*processed)++; - entry = *p; - } - } -} - -void StringTable::oops_do(OopClosure* f) { - buckets_oops_do(f, 0, the_table()->table_size()); -} - -void StringTable::possibly_parallel_oops_do(OopClosure* f) { - const int limit = the_table()->table_size(); - - for (;;) { - // Grab next set of buckets to scan - int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; - if (start_idx >= limit) { - // End of table - break; - } - - int end_idx = MIN2(limit, start_idx + ClaimChunkSize); - buckets_oops_do(f, start_idx, end_idx); - } -} - -// This verification is part of Universe::verify() and needs to be quick. -// See StringTable::verify_and_compare() below for exhaustive verification. -void StringTable::verify() { - for (int i = 0; i < the_table()->table_size(); ++i) { - HashtableEntry* p = the_table()->bucket(i); - for ( ; p != NULL; p = p->next()) { - oop s = p->literal(); - guarantee(s != NULL, "interned string is NULL"); - unsigned int h = java_lang_String::hash_string(s); - guarantee(p->hash() == h, "broken hash in string table entry"); - guarantee(the_table()->hash_to_index(h) == i, - "wrong index in string table"); - } - } -} - -void StringTable::dump(outputStream* st) { - the_table()->dump_table(st, "StringTable"); -} - -StringTable::VerifyRetTypes StringTable::compare_entries( - int bkt1, int e_cnt1, - HashtableEntry* e_ptr1, - int bkt2, int e_cnt2, - HashtableEntry* e_ptr2) { - // These entries are sanity checked by verify_and_compare_entries() - // before this function is called. - oop str1 = e_ptr1->literal(); - oop str2 = e_ptr2->literal(); - - if (str1 == str2) { - tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " - "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", - (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2); - return _verify_fail_continue; - } - - if (java_lang_String::equals(str1, str2)) { - tty->print_cr("ERROR: identical String values in entry @ " - "bucket[%d][%d] and entry @ bucket[%d][%d]", - bkt1, e_cnt1, bkt2, e_cnt2); - return _verify_fail_continue; - } - - return _verify_pass; -} - -StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, - HashtableEntry* e_ptr, - StringTable::VerifyMesgModes mesg_mode) { - - VerifyRetTypes ret = _verify_pass; // be optimistic - - oop str = e_ptr->literal(); - if (str == NULL) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, - e_cnt); - } - // NULL oop means no more verifications are possible - return _verify_fail_done; - } - - if (str->klass() != SystemDictionary::String_klass()) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", - bkt, e_cnt); - } - // not a String means no more verifications are possible - return _verify_fail_done; - } - - unsigned int h = java_lang_String::hash_string(str); - if (e_ptr->hash() != h) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " - "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); - } - ret = _verify_fail_continue; - } - - if (the_table()->hash_to_index(h) != bkt) { - if (mesg_mode == _verify_with_mesgs) { - tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " - "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, - the_table()->hash_to_index(h)); - } - ret = _verify_fail_continue; - } - - return ret; -} - -// See StringTable::verify() above for the quick verification that is -// part of Universe::verify(). This verification is exhaustive and -// reports on every issue that is found. StringTable::verify() only -// reports on the first issue that is found. -// -// StringTable::verify_entry() checks: -// - oop value != NULL (same as verify()) -// - oop value is a String -// - hash(String) == hash in entry (same as verify()) -// - index for hash == index of entry (same as verify()) -// -// StringTable::compare_entries() checks: -// - oops are unique across all entries -// - String values are unique across all entries -// -int StringTable::verify_and_compare_entries() { - assert(StringTable_lock->is_locked(), "sanity check"); - - int fail_cnt = 0; - - // first, verify all the entries individually: - for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { - HashtableEntry* e_ptr = the_table()->bucket(bkt); - for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { - VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); - if (ret != _verify_pass) { - fail_cnt++; - } - } - } - - // Optimization: if the above check did not find any failures, then - // the comparison loop below does not need to call verify_entry() - // before calling compare_entries(). If there were failures, then we - // have to call verify_entry() to see if the entry can be passed to - // compare_entries() safely. When we call verify_entry() in the loop - // below, we do so quietly to void duplicate messages and we don't - // increment fail_cnt because the failures have already been counted. - bool need_entry_verify = (fail_cnt != 0); - - // second, verify all entries relative to each other: - for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { - HashtableEntry* e_ptr1 = the_table()->bucket(bkt1); - for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { - if (need_entry_verify) { - VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, - _verify_quietly); - if (ret == _verify_fail_done) { - // cannot use the current entry to compare against other entries - continue; - } - } - - for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { - HashtableEntry* e_ptr2 = the_table()->bucket(bkt2); - int e_cnt2; - for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { - if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { - // skip the entries up to and including the one that - // we're comparing against - continue; - } - - if (need_entry_verify) { - VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, - _verify_quietly); - if (ret == _verify_fail_done) { - // cannot compare against this entry - continue; - } - } - - // compare two entries, report and count any failures: - if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) - != _verify_pass) { - fail_cnt++; - } - } - } - } - } - return fail_cnt; -} - -// Create a new table and using alternate hash code, populate the new table -// with the existing strings. Set flag to use the alternate hash code afterwards. -void StringTable::rehash_table() { - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); - // This should never happen with -Xshare:dump but it might in testing mode. - if (DumpSharedSpaces) return; - StringTable* new_table = new StringTable(); - - // Rehash the table - the_table()->move_to(new_table); - - // Delete the table and buckets (entries are reused in new table). - delete _the_table; - // Don't check if we need rehashing until the table gets unbalanced again. - // Then rehash with a new global seed. - _needs_rehashing = false; - _the_table = new_table; -} diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp index b0a2fcb38b8..c5dd75b82ea 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.hpp +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp @@ -42,7 +42,6 @@ class BoolObjectClosure; class outputStream; - // Class to hold a newly created or referenced Symbol* temporarily in scope. // new_symbol() and lookup() will create a Symbol* if not already in the // symbol table and add to the symbol's reference count. @@ -252,134 +251,4 @@ public: static int parallel_claimed_index() { return _parallel_claimed_idx; } }; -class StringTable : public Hashtable { - friend class VMStructs; - -private: - // The string table - static StringTable* _the_table; - - // Set if one bucket is out of balance due to hash algorithm deficiency - static bool _needs_rehashing; - - // Claimed high water mark for parallel chunked scanning - static volatile int _parallel_claimed_idx; - - static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); - oop basic_add(int index, Handle string_or_null, jchar* name, int len, - unsigned int hashValue, TRAPS); - - oop lookup(int index, jchar* chars, int length, unsigned int hashValue); - - // Apply the give oop closure to the entries to the buckets - // in the range [start_idx, end_idx). - static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); - // Unlink or apply the give oop closure to the entries to the buckets - // in the range [start_idx, end_idx). - static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); - - StringTable() : Hashtable((int)StringTableSize, - sizeof (HashtableEntry)) {} - - StringTable(HashtableBucket* t, int number_of_entries) - : Hashtable((int)StringTableSize, sizeof (HashtableEntry), t, - number_of_entries) {} -public: - // The string table - static StringTable* the_table() { return _the_table; } - - // Size of one bucket in the string table. Used when checking for rollover. - static uint bucket_size() { return sizeof(HashtableBucket); } - - static void create_table() { - assert(_the_table == NULL, "One string table allowed."); - _the_table = new StringTable(); - } - - // GC support - // Delete pointers to otherwise-unreachable objects. - static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { - int processed = 0; - int removed = 0; - unlink_or_oops_do(cl, f, &processed, &removed); - } - static void unlink(BoolObjectClosure* cl) { - int processed = 0; - int removed = 0; - unlink_or_oops_do(cl, NULL, &processed, &removed); - } - static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); - static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { - unlink_or_oops_do(cl, NULL, processed, removed); - } - // Serially invoke "f->do_oop" on the locations of all oops in the table. - static void oops_do(OopClosure* f); - - // Possibly parallel versions of the above - static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); - static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { - possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); - } - static void possibly_parallel_oops_do(OopClosure* f); - - // Hashing algorithm, used as the hash value used by the - // StringTable for bucket selection and comparison (stored in the - // HashtableEntry structures). This is used in the String.intern() method. - static unsigned int hash_string(const jchar* s, int len); - - // Internal test. - static void test_alt_hash() PRODUCT_RETURN; - - // Probing - static oop lookup(Symbol* symbol); - static oop lookup(jchar* chars, int length); - - // Interning - static oop intern(Symbol* symbol, TRAPS); - static oop intern(oop string, TRAPS); - static oop intern(const char *utf8_string, TRAPS); - - // Debugging - static void verify(); - static void dump(outputStream* st); - - enum VerifyMesgModes { - _verify_quietly = 0, - _verify_with_mesgs = 1 - }; - - enum VerifyRetTypes { - _verify_pass = 0, - _verify_fail_continue = 1, - _verify_fail_done = 2 - }; - - static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, - HashtableEntry* e_ptr1, - int bkt2, int e_cnt2, - HashtableEntry* e_ptr2); - static VerifyRetTypes verify_entry(int bkt, int e_cnt, - HashtableEntry* e_ptr, - VerifyMesgModes mesg_mode); - static int verify_and_compare_entries(); - - // Sharing - static void copy_buckets(char** top, char*end) { - the_table()->Hashtable::copy_buckets(top, end); - } - static void copy_table(char** top, char*end) { - the_table()->Hashtable::copy_table(top, end); - } - static void reverse() { - the_table()->Hashtable::reverse(); - } - - // Rehash the symbol table if it gets out of balance - static void rehash_table(); - static bool needs_rehashing() { return _needs_rehashing; } - - // Parallel chunked scanning - static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } - static int parallel_claimed_index() { return _parallel_claimed_idx; } -}; #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 8d52bef7194..d09de41114d 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -29,6 +29,7 @@ #include "classfile/loaderConstraints.hpp" #include "classfile/placeholders.hpp" #include "classfile/resolutionErrors.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" @@ -603,7 +604,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Ticks class_load_start_time = Ticks::now(); - // UseNewReflection // Fix for 4474172; see evaluation for more details class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); @@ -897,7 +897,6 @@ Klass* SystemDictionary::find(Symbol* class_name, Handle protection_domain, TRAPS) { - // UseNewReflection // The result of this call should be consistent with the result // of the call to resolve_instance_class_or_null(). // See evaluation 6790209 and 4474172 for more details. @@ -2269,7 +2268,7 @@ static methodHandle unpack_method_and_appendix(Handle mname, oop appendix = appendix_box->obj_at(0); if (TraceMethodHandles) { #ifndef PRODUCT - tty->print("Linked method="INTPTR_FORMAT": ", m); + tty->print("Linked method=" INTPTR_FORMAT ": ", p2i(m)); m->print(); if (appendix != NULL) { tty->print("appendix = "); appendix->print(); } tty->cr(); diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index dad4b8efa66..4e1b75dc241 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -390,7 +390,7 @@ public: return k; } static Klass* check_klass_Opt_Only_JDK14NewRef(Klass* k) { - assert(JDK_Version::is_gte_jdk14x_version() && UseNewReflection, "JDK 1.4 only"); + assert(JDK_Version::is_gte_jdk14x_version(), "JDK 1.4 only"); // despite the optional loading, if you use this it must be present: return check_klass(k); } diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index d1238f609fa..c7eca2d011b 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -211,9 +211,9 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool shou // reflection implementation, not just those associated with // sun/reflect/SerializationConstructorAccessor. // NOTE: this is called too early in the bootstrapping process to be - // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. + // guarded by Universe::is_gte_jdk14x_version(). // Also for lambda generated code, gte jdk8 - (!is_reflect || VerifyReflectionBytecodes)); + (!is_reflect)); } Symbol* Verifier::inference_verify( @@ -364,7 +364,7 @@ void TypeOrigin::print_on(outputStream* str) const { void ErrorContext::details(outputStream* ss, const Method* method) const { if (is_valid()) { - ss->print_cr(""); + ss->cr(); ss->print_cr("Exception Details:"); location_details(ss, method); reason_details(ss); @@ -379,7 +379,7 @@ void ErrorContext::reason_details(outputStream* ss) const { streamIndentor si(ss); ss->indent().print_cr("Reason:"); streamIndentor si2(ss); - ss->indent().print(""); + ss->indent().print("%s", ""); switch (_fault) { case INVALID_BYTECODE: ss->print("Error exists in the bytecode"); @@ -432,7 +432,7 @@ void ErrorContext::reason_details(outputStream* ss) const { ShouldNotReachHere(); ss->print_cr("Unknown"); } - ss->print_cr(""); + ss->cr(); } void ErrorContext::location_details(outputStream* ss, const Method* method) const { @@ -507,7 +507,7 @@ void ErrorContext::stackmap_details(outputStream* ss, const Method* method) cons for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { ss->indent(); sm_frame->print_on(ss, current_offset); - ss->print_cr(""); + ss->cr(); current_offset += sm_frame->offset_delta(); sm_frame = sm_frame->next(); } @@ -579,7 +579,8 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) { tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); } - const char* bad_type_msg = "Bad type on operand stack in %s"; +// For clang, the only good constant format string is a literal constant format string. +#define bad_type_msg "Bad type on operand stack in %s" int32_t max_stack = m->verifier_max_stack(); int32_t max_locals = m->max_locals(); @@ -1676,6 +1677,8 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) { } } +#undef bad_type_message + char* ClassVerifier::generate_code_data(methodHandle m, u4 code_length, TRAPS) { char* code_data = NEW_RESOURCE_ARRAY(char, code_length); memset(code_data, 0, sizeof(char) * code_length); @@ -2033,7 +2036,7 @@ void ClassVerifier::verify_switch( while ((bcp + padding_offset) < aligned_bcp) { if(*(bcp + padding_offset) != 0) { verify_error(ErrorContext::bad_code(bci), - "Nonzero padding byte in lookswitch or tableswitch"); + "Nonzero padding byte in lookupswitch or tableswitch"); return; } padding_offset++; @@ -2363,8 +2366,8 @@ void ClassVerifier::verify_invoke_instructions( if (opcode == Bytecodes::_invokedynamic) { if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { class_format_error( - "invokedynamic instructions not supported by this class file version", - _klass->external_name()); + "invokedynamic instructions not supported by this class file version (%d), class %s", + _klass->major_version(), _klass->external_name()); return; } } else { diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp index 74143a6e787..557f567bf78 100644 --- a/hotspot/src/share/vm/classfile/verifier.hpp +++ b/hotspot/src/share/vm/classfile/verifier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -375,15 +375,15 @@ class ClassVerifier : public StackObj { bool has_error() const { return result() != NULL; } char* exception_message() { stringStream ss; - ss.print(_message); + ss.print("%s", _message); _error_context.details(&ss, _method()); return ss.as_string(); } // Called when verify or class format errors are encountered. // May throw an exception based upon the mode. - void verify_error(ErrorContext ctx, const char* fmt, ...); - void class_format_error(const char* fmt, ...); + void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4); + void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3); Klass* load_class(Symbol* name, TRAPS); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp index 855c6bdd773..6d13995c588 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -533,7 +533,7 @@ void vmIntrinsics::verify_method(ID actual_id, Method* m) { xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'", actual_name, declared_name); xtty->method(mh); - xtty->end_elem(""); + xtty->end_elem("%s", ""); } if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):", diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp index 141bbae007b..f9e78bfb9e2 100644 --- a/hotspot/src/share/vm/code/codeBlob.cpp +++ b/hotspot/src/share/vm/code/codeBlob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -530,7 +530,7 @@ void CodeBlob::verify() { } void CodeBlob::print_on(outputStream* st) const { - st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", this); + st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this)); st->print_cr("Framesize: %d", _frame_size); } @@ -548,7 +548,7 @@ void BufferBlob::print_on(outputStream* st) const { } void BufferBlob::print_value_on(outputStream* st) const { - st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", this, name()); + st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name()); } void RuntimeStub::verify() { @@ -558,13 +558,13 @@ void RuntimeStub::verify() { void RuntimeStub::print_on(outputStream* st) const { ttyLocker ttyl; CodeBlob::print_on(st); - st->print("Runtime Stub (" INTPTR_FORMAT "): ", this); - st->print_cr(name()); + st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this)); + st->print_cr("%s", name()); Disassembler::decode((CodeBlob*)this, st); } void RuntimeStub::print_value_on(outputStream* st) const { - st->print("RuntimeStub (" INTPTR_FORMAT "): ", this); st->print(name()); + st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name()); } void SingletonBlob::verify() { @@ -574,12 +574,12 @@ void SingletonBlob::verify() { void SingletonBlob::print_on(outputStream* st) const { ttyLocker ttyl; CodeBlob::print_on(st); - st->print_cr(name()); + st->print_cr("%s", name()); Disassembler::decode((CodeBlob*)this, st); } void SingletonBlob::print_value_on(outputStream* st) const { - st->print_cr(name()); + st->print_cr("%s", name()); } void DeoptimizationBlob::print_value_on(outputStream* st) const { diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index b3a857c2062..8fe9efcb427 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,10 +81,10 @@ class CodeBlob_sizes { bool is_empty() { return count == 0; } void print(const char* title) { - tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, data %d%%, pcs %d%%])", + tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, metadata %d%%, data %d%%, pcs %d%%])", count, title, - total() / K, + (int)(total() / K), header_size * 100 / total_size, relocation_size * 100 / total_size, code_size * 100 / total_size, @@ -178,10 +178,12 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) { // cache will contain a garbage CodeBlob until the caller can // run the constructor for the CodeBlob subclass he is busy // instantiating. - guarantee(size >= 0, "allocation request must be reasonable"); assert_locked_or_safepoint(CodeCache_lock); + assert(size > 0, "allocation request must be reasonable"); + if (size <= 0) { + return NULL; + } CodeBlob* cb = NULL; - _number_of_blobs++; while (true) { cb = (CodeBlob*)_heap->allocate(size, is_critical); if (cb != NULL) break; @@ -191,7 +193,7 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) { } if (PrintCodeCacheExtension) { ResourceMark rm; - tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)", + tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (" SSIZE_FORMAT " bytes)", (intptr_t)_heap->low_boundary(), (intptr_t)_heap->high(), (address)_heap->high() - (address)_heap->low_boundary()); } @@ -199,6 +201,7 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) { maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - (address)_heap->low_boundary()) - unallocated_capacity()); print_trace("allocation", cb, size); + _number_of_blobs++; return cb; } @@ -487,7 +490,7 @@ void CodeCache::gc_epilogue() { if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) { CompiledIC *ic = CompiledIC_at(iter.reloc()); if (TraceCompiledIC) { - tty->print("noticed icholder " INTPTR_FORMAT " ", ic->cached_icholder()); + tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder())); ic->print(); } assert(ic->cached_icholder() != NULL, "must be non-NULL"); @@ -741,10 +744,10 @@ void CodeCache::print_memory_overhead() { } // Print bytes that are allocated in the freelist ttyLocker ttl; - tty->print_cr("Number of elements in freelist: %d", freelist_length()); - tty->print_cr("Allocated in freelist: %dkB", bytes_allocated_in_freelist()/K); - tty->print_cr("Unused bytes in CodeBlobs: %dkB", (int)(wasted_bytes/K)); - tty->print_cr("Segment map size: %dkB", allocated_segments()/K); // 1 byte per segment + tty->print_cr("Number of elements in freelist: " SSIZE_FORMAT, freelist_length()); + tty->print_cr("Allocated in freelist: " SSIZE_FORMAT "kB", bytes_allocated_in_freelist()/K); + tty->print_cr("Unused bytes in CodeBlobs: " SSIZE_FORMAT "kB", (wasted_bytes/K)); + tty->print_cr("Segment map size: " SSIZE_FORMAT "kB", allocated_segments()/K); // 1 byte per segment } //------------------------------------------------------------------------------------------------ @@ -756,7 +759,7 @@ void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) { if (PrintCodeCache2) { // Need to add a new flag ResourceMark rm; if (size == 0) size = cb->size(); - tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size); + tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, p2i(cb), size); } } @@ -926,9 +929,9 @@ void CodeCache::print_summary(outputStream* st, bool detailed) { if (detailed) { st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", - _heap->low_boundary(), - _heap->high(), - _heap->high_boundary()); + p2i(_heap->low_boundary()), + p2i(_heap->high()), + p2i(_heap->high_boundary())); st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT " adapters=" UINT32_FORMAT, nof_blobs(), nof_nmethods(), nof_adapters()); diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index 251a4c79c43..9a038164689 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,9 +88,9 @@ void CompiledIC::internal_set_ic_destination(address entry_point, bool is_icstub if (TraceCompiledIC) { tty->print(" "); print_compiled_ic(); - tty->print(" changing destination to " INTPTR_FORMAT, entry_point); + tty->print(" changing destination to " INTPTR_FORMAT, p2i(entry_point)); if (!is_optimized()) { - tty->print(" changing cached %s to " INTPTR_FORMAT, is_icholder ? "icholder" : "metadata", (address)cache); + tty->print(" changing cached %s to " INTPTR_FORMAT, is_icholder ? "icholder" : "metadata", p2i((address)cache)); } if (is_icstub) { tty->print(" (icstub)"); @@ -195,7 +195,7 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod if (TraceICs) { ResourceMark rm; tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT, - instruction_address(), call_info->selected_method()->print_value_string(), entry); + p2i(instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry)); } // We can't check this anymore. With lazy deopt we could have already @@ -272,7 +272,7 @@ bool CompiledIC::is_call_to_interpreted() const { void CompiledIC::set_to_clean() { assert(SafepointSynchronize::is_at_safepoint() || CompiledIC_lock->is_locked() , "MT-unsafe call"); if (TraceInlineCacheClearing || TraceICs) { - tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", instruction_address()); + tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", p2i(instruction_address())); print(); } @@ -354,7 +354,7 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { if (TraceICs) { ResourceMark rm(thread); tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter: %s", - instruction_address(), + p2i(instruction_address()), method->print_value_string()); } } else { @@ -362,7 +362,7 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { InlineCacheBuffer::create_transition_stub(this, info.claim_cached_icholder(), info.entry()); if (TraceICs) { ResourceMark rm(thread); - tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", instruction_address()); + tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", p2i(instruction_address())); } } } else { @@ -392,7 +392,7 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { ResourceMark rm(thread); assert(info.cached_metadata() == NULL || info.cached_metadata()->is_klass(), "must be"); tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to compiled (rcvr klass) %s: %s", - instruction_address(), + p2i(instruction_address()), ((Klass*)info.cached_metadata())->print_value_string(), (safe) ? "" : "via stub"); } @@ -530,8 +530,8 @@ void CompiledStaticCall::set(const StaticCallInfo& info) { if (TraceICs) { ResourceMark rm; tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_compiled " INTPTR_FORMAT, - instruction_address(), - info.entry()); + p2i(instruction_address()), + p2i(info.entry())); } // Call to compiled code assert (CodeCache::contains(info.entry()), "wrong entry point"); @@ -600,11 +600,11 @@ void CompiledIC::print() { void CompiledIC::print_compiled_ic() { tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT " cached_value " INTPTR_FORMAT, - instruction_address(), is_call_to_interpreted() ? "interpreted " : "", ic_destination(), is_optimized() ? NULL : cached_value()); + p2i(instruction_address()), is_call_to_interpreted() ? "interpreted " : "", p2i(ic_destination()), p2i(is_optimized() ? NULL : cached_value())); } void CompiledStaticCall::print() { - tty->print("static call at " INTPTR_FORMAT " -> ", instruction_address()); + tty->print("static call at " INTPTR_FORMAT " -> ", p2i(instruction_address())); if (is_clean()) { tty->print("clean"); } else if (is_call_to_compiled()) { diff --git a/hotspot/src/share/vm/code/compressedStream.cpp b/hotspot/src/share/vm/code/compressedStream.cpp index 1716ffac651..4687372f833 100644 --- a/hotspot/src/share/vm/code/compressedStream.cpp +++ b/hotspot/src/share/vm/code/compressedStream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -212,6 +212,8 @@ static jlong stretch(jint x, int bits) { return h ^ l; } +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_IGNORED // Someone needs to deal with this. void test_compressed_stream(int trace) { CompressedWriteStream bytes(stretch_limit * 100); jint n; @@ -275,6 +277,7 @@ void test_compressed_stream(int trace) { guarantee(length == length2, "bad length"); guarantee(fails == 0, "test failures"); } +PRAGMA_DIAG_POP #if defined(_MSC_VER) &&_MSC_VER >=1400 && !defined(_WIN64) #pragma warning(default: 4748) diff --git a/hotspot/src/share/vm/code/debugInfo.cpp b/hotspot/src/share/vm/code/debugInfo.cpp index ecdae461039..3b01884c6e4 100644 --- a/hotspot/src/share/vm/code/debugInfo.cpp +++ b/hotspot/src/share/vm/code/debugInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,9 @@ #include "code/nmethod.hpp" #include "runtime/handles.inline.hpp" -// Comstructors +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + +// Constructors DebugInfoWriteStream::DebugInfoWriteStream(DebugInformationRecorder* recorder, int initial_size) : CompressedWriteStream(initial_size) { diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp index 21e0f816d83..0f50425bcdd 100644 --- a/hotspot/src/share/vm/code/dependencies.cpp +++ b/hotspot/src/share/vm/code/dependencies.cpp @@ -1429,6 +1429,10 @@ Klass* Dependencies::check_unique_concrete_method(Klass* ctxk, Method* uniqm, // Include m itself in the set, unless it is abstract. // If this set has exactly one element, return that element. Method* Dependencies::find_unique_concrete_method(Klass* ctxk, Method* m) { + // Return NULL if m is marked old; must have been a redefined method. + if (m->is_old()) { + return NULL; + } ClassHierarchyWalker wf(m); assert(wf.check_method_context(ctxk, m), "proper context"); wf.record_witnesses(1); diff --git a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp index 9e259008287..511b84d220d 100644 --- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp +++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "code/nmethod.hpp" #include "memory/allocation.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void ExceptionHandlerTable::add_entry(HandlerTableEntry entry) { _nesting.check(); if (_length >= _size) { diff --git a/hotspot/src/share/vm/code/icBuffer.cpp b/hotspot/src/share/vm/code/icBuffer.cpp index 81ef87ce200..0fe6e0d1145 100644 --- a/hotspot/src/share/vm/code/icBuffer.cpp +++ b/hotspot/src/share/vm/code/icBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ #include "runtime/mutexLocker.hpp" #include "runtime/stubRoutines.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC DEF_STUB_INTERFACE(ICStub); diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 89604e0caa8..86264436755 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,8 @@ #include "shark/sharkCompiler.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef DTRACE_ENABLED // Only bother with this argument setup if dtrace is available diff --git a/hotspot/src/share/vm/code/pcDesc.cpp b/hotspot/src/share/vm/code/pcDesc.cpp index 7ba25464f7d..7f27cc0c08c 100644 --- a/hotspot/src/share/vm/code/pcDesc.cpp +++ b/hotspot/src/share/vm/code/pcDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "code/scopeDesc.hpp" #include "memory/resourceArea.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) { _pc_offset = pc_offset; _scope_decode_offset = scope_decode_offset; diff --git a/hotspot/src/share/vm/code/relocInfo.cpp b/hotspot/src/share/vm/code/relocInfo.cpp index 7cff27f085e..aa0ef6b106e 100644 --- a/hotspot/src/share/vm/code/relocInfo.cpp +++ b/hotspot/src/share/vm/code/relocInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "runtime/stubCodeGenerator.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC const RelocationHolder RelocationHolder::none; // its type is relocInfo::none diff --git a/hotspot/src/share/vm/code/scopeDesc.cpp b/hotspot/src/share/vm/code/scopeDesc.cpp index b1c3ccef764..7e557afcd35 100644 --- a/hotspot/src/share/vm/code/scopeDesc.cpp +++ b/hotspot/src/share/vm/code/scopeDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { _code = code; diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index b3bfc258f56..ac99da40e1c 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include "opto/matcher.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // ----------------------------------------------------------------------------------------- // Implementation of VtableStub diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 8521806cd1f..ff292fbd747 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,7 +172,7 @@ class CompilationLog : public StringEventLog { void log_nmethod(JavaThread* thread, nmethod* nm) { log(thread, "nmethod %d%s " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]", nm->compile_id(), nm->is_osr_method() ? "%" : "", - nm, nm->code_begin(), nm->code_end()); + p2i(nm), p2i(nm->code_begin()), p2i(nm->code_end())); } void log_failure(JavaThread* thread, CompileTask* task, const char* reason, const char* retry_message) { @@ -704,13 +704,39 @@ CompileTask* CompileQueue::get() { return NULL; } - CompileTask* task = CompilationPolicy::policy()->select_task(this); + CompileTask* task; + { + No_Safepoint_Verifier nsv; + task = CompilationPolicy::policy()->select_task(this); + } remove(task); + purge_stale_tasks(); // may temporarily release MCQ lock return task; } -void CompileQueue::remove(CompileTask* task) -{ +// Clean & deallocate stale compile tasks. +// Temporarily releases MethodCompileQueue lock. +void CompileQueue::purge_stale_tasks() { + assert(lock()->owned_by_self(), "must own lock"); + if (_first_stale != NULL) { + // Stale tasks are purged when MCQ lock is released, + // but _first_stale updates are protected by MCQ lock. + // Once task processing starts and MCQ lock is released, + // other compiler threads can reuse _first_stale. + CompileTask* head = _first_stale; + _first_stale = NULL; + { + MutexUnlocker ul(lock()); + for (CompileTask* task = head; task != NULL; ) { + CompileTask* next_task = task->next(); + CompileTaskWrapper ctw(task); // Frees the task + task = next_task; + } + } + } +} + +void CompileQueue::remove(CompileTask* task) { assert(lock()->owned_by_self(), "must own lock"); if (task->prev() != NULL) { task->prev()->set_next(task->next()); @@ -730,6 +756,16 @@ void CompileQueue::remove(CompileTask* task) --_size; } +void CompileQueue::remove_and_mark_stale(CompileTask* task) { + assert(lock()->owned_by_self(), "must own lock"); + remove(task); + + // Enqueue the task for reclamation (should be done outside MCQ lock) + task->set_next(_first_stale); + task->set_prev(NULL); + _first_stale = task; +} + // methods in the compile queue need to be marked as used on the stack // so that they don't get reclaimed by Redefine Classes void CompileQueue::mark_on_stack() { @@ -1786,7 +1822,7 @@ void CompileBroker::init_compiler_thread_log() { if (xtty != NULL) { ttyLocker ttyl; // Record any per thread log files - xtty->elem("thread_logfile thread='%d' filename='%s'", thread_id, file_name); + xtty->elem("thread_logfile thread='" INTX_FORMAT "' filename='%s'", thread_id, file_name); } return; } @@ -1817,7 +1853,7 @@ void CompileBroker::maybe_block() { if (_should_block) { #ifndef PRODUCT if (PrintCompilation && (Verbose || WizardMode)) - tty->print_cr("compiler thread " INTPTR_FORMAT " poll detects block request", Thread::current()); + tty->print_cr("compiler thread " INTPTR_FORMAT " poll detects block request", p2i(Thread::current())); #endif ThreadInVMfromNative tivfn(JavaThread::current()); } @@ -1834,7 +1870,7 @@ static void codecache_print(bool detailed) CodeCache::print_summary(&s, detailed); } ttyLocker ttyl; - tty->print(s.as_string()); + tty->print("%s", s.as_string()); } // ------------------------------------------------------------------ @@ -2006,7 +2042,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { // Note that the queued_for_compilation bits are cleared without // protection of a mutex. [They were set by the requester thread, - // when adding the task to the complie queue -- at which time the + // when adding the task to the compile queue -- at which time the // compile queue lock was held. Subsequently, we acquired the compile // queue lock to get this task off the compile queue; thus (to belabour // the point somewhat) our clearing of the bits must be occurring @@ -2039,7 +2075,7 @@ void CompileBroker::handle_full_code_cache() { // Lock to prevent tearing ttyLocker ttyl; xtty->begin_elem("code_cache_full"); - xtty->print(s.as_string()); + xtty->print("%s", s.as_string()); xtty->stamp(); xtty->end_elem(); } diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp index dc0b0ba854f..d3a25dddcc4 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.hpp +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp @@ -196,7 +196,11 @@ class CompileQueue : public CHeapObj { CompileTask* _first; CompileTask* _last; + CompileTask* _first_stale; + int _size; + + void purge_stale_tasks(); public: CompileQueue(const char* name, Monitor* lock) { _name = name; @@ -204,6 +208,7 @@ class CompileQueue : public CHeapObj { _first = NULL; _last = NULL; _size = 0; + _first_stale = NULL; } const char* name() const { return _name; } @@ -211,6 +216,7 @@ class CompileQueue : public CHeapObj { void add(CompileTask* task); void remove(CompileTask* task); + void remove_and_mark_stale(CompileTask* task); CompileTask* first() { return _first; } CompileTask* last() { return _last; } @@ -219,6 +225,7 @@ class CompileQueue : public CHeapObj { bool is_empty() const { return _first == NULL; } int size() const { return _size; } + // Redefine Classes support void mark_on_stack(); void free_all(); diff --git a/hotspot/src/share/vm/compiler/compileLog.cpp b/hotspot/src/share/vm/compiler/compileLog.cpp index 8753e7b2859..f2c04b6e4ff 100644 --- a/hotspot/src/share/vm/compiler/compileLog.cpp +++ b/hotspot/src/share/vm/compiler/compileLog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,9 +174,9 @@ void CompileLog::name(ciSymbol* name) { void CompileLog::name(ciKlass* k) { print(" name='"); if (!k->is_loaded()) { - text()->print(k->name()->as_klass_external_name()); + text()->print("%s", k->name()->as_klass_external_name()); } else { - text()->print(k->external_name()); + text()->print("%s", k->external_name()); } print("'"); } @@ -303,7 +303,7 @@ void CompileLog::finish_log(outputStream* file) { // Print about successful method inlining. void CompileLog::inline_success(const char* reason) { begin_elem("inline_success reason='"); - text(reason); + text("%s", reason); end_elem("'"); } @@ -313,7 +313,7 @@ void CompileLog::inline_success(const char* reason) { // Print about failed method inlining. void CompileLog::inline_fail(const char* reason) { begin_elem("inline_fail reason='"); - text(reason); + text("%s", reason); end_elem("'"); } @@ -339,5 +339,5 @@ void CompileLog::set_context(const char* format, ...) { void CompileLog::code_cache_state() { begin_elem("code_cache"); CodeCache::log_state(this); - end_elem(""); + end_elem("%s", ""); } diff --git a/hotspot/src/share/vm/compiler/compileLog.hpp b/hotspot/src/share/vm/compiler/compileLog.hpp index 094dc767f7e..49e2b6a6180 100644 --- a/hotspot/src/share/vm/compiler/compileLog.hpp +++ b/hotspot/src/share/vm/compiler/compileLog.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ class CompileLog : public xmlStream { static CompileLog* _first; // head of static chain - void va_tag(bool push, const char* format, va_list ap); + void va_tag(bool push, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0); public: CompileLog(const char* file_name, FILE* fp, intx thread_id); @@ -69,7 +69,7 @@ class CompileLog : public xmlStream { // or reset, context string will be silently ignored stringStream* context() { return &_context; } void clear_context() { context()->reset(); } - void set_context(const char* format, ...); + void set_context(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void name(ciSymbol* s); // name='s' void name(Symbol* s) { xmlStream::name(s); } diff --git a/hotspot/src/share/vm/compiler/compilerOracle.cpp b/hotspot/src/share/vm/compiler/compilerOracle.cpp index 582ec675d4d..b646158af28 100644 --- a/hotspot/src/share/vm/compiler/compilerOracle.cpp +++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -307,6 +307,9 @@ bool CompilerOracle::should_print(methodHandle method) { return (check_predicate(PrintCommand, method)); } +bool CompilerOracle::should_print_methods() { + return lists[PrintCommand] != NULL; +} bool CompilerOracle::should_log(methodHandle method) { if (!LogCompilation) return false; @@ -520,7 +523,7 @@ void CompilerOracle::parse_from_line(char* line) { tty->print_cr("CompilerOracle: unrecognized line"); tty->print_cr(" \"%s\"", original_line); if (error_msg != NULL) { - tty->print_cr(error_msg); + tty->print_cr("%s", error_msg); } } } @@ -642,7 +645,7 @@ void CompilerOracle::parse_compile_only(char * line) { char method_sep = have_colon ? ':' : '.'; if (Verbose) { - tty->print_cr(line); + tty->print_cr("%s", line); } ResourceMark rm; diff --git a/hotspot/src/share/vm/compiler/compilerOracle.hpp b/hotspot/src/share/vm/compiler/compilerOracle.hpp index f736a4eebfc..df025f76be5 100644 --- a/hotspot/src/share/vm/compiler/compilerOracle.hpp +++ b/hotspot/src/share/vm/compiler/compilerOracle.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,6 +73,9 @@ class CompilerOracle : AllStatic { // For updating the oracle file static void append_comment_to_file(const char* message); static void append_exclude_to_file(methodHandle method); + + // Tells whether there are any methods to print for print_method_statistics() + static bool should_print_methods(); }; #endif // SHARE_VM_COMPILER_COMPILERORACLE_HPP diff --git a/hotspot/src/share/vm/compiler/disassembler.cpp b/hotspot/src/share/vm/compiler/disassembler.cpp index 8495210c384..a0b2b49903c 100644 --- a/hotspot/src/share/vm/compiler/disassembler.cpp +++ b/hotspot/src/share/vm/compiler/disassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,8 @@ #include "shark/sharkEntry.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void* Disassembler::_library = NULL; bool Disassembler::_tried_to_load_library = false; @@ -84,7 +86,7 @@ bool Disassembler::load_library() { { // Match "jvm[^/]*" in jvm_path. const char* base = buf; - const char* p = strrchr(buf, '/'); + const char* p = strrchr(buf, *os::file_separator()); if (p != NULL) lib_offset = p - base + 1; p = strstr(p ? p : base, "jvm"); if (p != NULL) jvm_offset = p - base; @@ -109,7 +111,7 @@ bool Disassembler::load_library() { if (_library == NULL) { // 3. /jre/lib//hsdis-.so buf[lib_offset - 1] = '\0'; - const char* p = strrchr(buf, '/'); + const char* p = strrchr(buf, *os::file_separator()); if (p != NULL) { lib_offset = p - buf + 1; strcpy(&buf[lib_offset], hsdis_library_name); @@ -411,6 +413,7 @@ static void* event_to_env(void* env_pv, const char* event, void* arg) { return env->handle_event(event, (address) arg); } +ATTRIBUTE_PRINTF(2, 3) static int printf_to_env(void* env_pv, const char* format, ...) { decode_env* env = (decode_env*) env_pv; outputStream* st = env->output(); diff --git a/hotspot/src/share/vm/compiler/methodLiveness.cpp b/hotspot/src/share/vm/compiler/methodLiveness.cpp index 4fcc5613336..0c1d9b09232 100644 --- a/hotspot/src/share/vm/compiler/methodLiveness.cpp +++ b/hotspot/src/share/vm/compiler/methodLiveness.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "memory/allocation.inline.hpp" #include "utilities/bitMap.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // The MethodLiveness class performs a simple liveness analysis on a method // in order to decide which locals are live (that is, will be used again) at // a particular bytecode index (bci). diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp index c4c83fc164d..5e1801584c2 100644 --- a/hotspot/src/share/vm/compiler/oopMap.cpp +++ b/hotspot/src/share/vm/compiler/oopMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -633,8 +633,8 @@ void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) { tty->print_cr( "Add derived pointer@" INTPTR_FORMAT " - Derived: " INTPTR_FORMAT - " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: %d)", - derived_loc, (address)*derived_loc, (address)*base_loc, base_loc, offset + " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: " INTX_FORMAT ")", + p2i(derived_loc), p2i((address)*derived_loc), p2i((address)*base_loc), p2i(base_loc), offset ); } // Set derived oop location to point to base. @@ -661,8 +661,8 @@ void DerivedPointerTable::update_pointers() { if (TraceDerivedPointers) { tty->print_cr("Updating derived pointer@" INTPTR_FORMAT - " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: %d)", - derived_loc, (address)*derived_loc, (address)base, offset); + " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: " INTX_FORMAT ")", + p2i(derived_loc), p2i((address)*derived_loc), p2i((address)base), offset); } // Delete entry diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp index 309fe014aa1..b7f7ed1f0a3 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -157,7 +157,7 @@ void AdaptiveFreeList::verify_stats() const { " split_deaths(" SIZE_FORMAT ")" " coal_deaths(" SIZE_FORMAT ")" " + count(" SSIZE_FORMAT ")", - this, size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(), + p2i(this), size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(), _allocation_stats.coal_births(), _allocation_stats.split_deaths(), _allocation_stats.coal_deaths(), count())); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index bbaffb9bf2e..640265fbf56 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ #include "memory/allocation.inline.hpp" #include "memory/blockOffsetTable.inline.hpp" #include "memory/resourceArea.hpp" +#include "memory/space.inline.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/globals.hpp" @@ -428,7 +429,7 @@ size_t CompactibleFreeListSpace::max_alloc_in_words() const { void LinearAllocBlock::print_on(outputStream* st) const { st->print_cr(" LinearAllocBlock: ptr = " PTR_FORMAT ", word_size = " SIZE_FORMAT ", refillsize = " SIZE_FORMAT ", allocation_size_limit = " SIZE_FORMAT, - _ptr, _word_size, _refillSize, _allocation_size_limit); + p2i(_ptr), _word_size, _refillSize, _allocation_size_limit); } void CompactibleFreeListSpace::print_on(outputStream* st) const { @@ -459,7 +460,7 @@ const { for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; fc = fc->next()) { gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", - fc, (HeapWord*)fc + i, + p2i(fc), p2i((HeapWord*)fc + i), fc->cantCoalesce() ? "\t CC" : ""); } } @@ -503,7 +504,7 @@ size_t BlkPrintingClosure::do_blk(HeapWord* addr) { if (_sp->block_is_obj(addr)) { const bool dead = _post_remark && !_live_bit_map->isMarked(addr); _st->print_cr(PTR_FORMAT ": %s object of size " SIZE_FORMAT "%s", - addr, + p2i(addr), dead ? "dead" : "live", sz, (!dead && CMSPrintObjectsInDump) ? ":" : "."); @@ -513,7 +514,7 @@ size_t BlkPrintingClosure::do_blk(HeapWord* addr) { } } else { // free block _st->print_cr(PTR_FORMAT ": free block of size " SIZE_FORMAT "%s", - addr, sz, CMSPrintChunksInDump ? ":" : "."); + p2i(addr), sz, CMSPrintChunksInDump ? ":" : "."); if (CMSPrintChunksInDump) { ((FreeChunk*)addr)->print_on(_st); _st->print_cr("--------------------------------------"); @@ -1983,7 +1984,7 @@ void CompactibleFreeListSpace::save_marks() { assert(ur.contains(urasm), err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")" " should contain [" PTR_FORMAT "," PTR_FORMAT ")", - ur.start(), ur.end(), urasm.start(), urasm.end())); + p2i(ur.start()), p2i(ur.end()), p2i(urasm.start()), p2i(urasm.end()))); #endif // inform allocator that promotions should be tracked. assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); @@ -2206,7 +2207,7 @@ void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { if (PrintFLSStatistics > 0) { HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict(); gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT, - largestAddr); + p2i(largestAddr)); } setFLSurplus(); setFLHints(); @@ -2355,8 +2356,8 @@ class VerifyAllBlksClosure: public BlkClosure { gclog_or_tty->print_cr( " Current: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n" " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n", - addr, res, was_obj ?"true":"false", was_live ?"true":"false", - _last_addr, _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); + p2i(addr), res, was_obj ?"true":"false", was_live ?"true":"false", + p2i(_last_addr), _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); _sp->print_on(gclog_or_tty); guarantee(false, "Seppuku!"); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp index 9f01fcd54a4..e1d5e29a84b 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -403,7 +403,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { if (CMSTraceSweeper) { gclog_or_tty->print_cr(">>>>> Saving sweep limit " PTR_FORMAT " for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<", - _sweep_limit, bottom(), end()); + p2i(_sweep_limit), p2i(bottom()), p2i(end())); } } NOT_PRODUCT( diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 3d108c28181..43d6e923a7b 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" @@ -64,6 +64,8 @@ #include "services/memoryService.hpp" #include "services/runtimeService.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // statics CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL; bool CMSCollector::_full_gc_requested = false; @@ -1182,7 +1184,7 @@ void CMSCollector::icms_update_allocation_limits() gclog_or_tty->print(" icms alloc limits: " PTR_FORMAT "," PTR_FORMAT " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ", - _icms_start_limit, _icms_stop_limit, + p2i(_icms_start_limit), p2i(_icms_stop_limit), percent_of_space(eden, _icms_start_limit), percent_of_space(eden, _icms_stop_limit)); if (Verbose) { @@ -1210,7 +1212,7 @@ CMSCollector::allocation_limit_reached(Space* space, HeapWord* top, gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT ", new limit=" PTR_FORMAT " (" SIZE_FORMAT "%%)", - top, _icms_stop_limit, + p2i(top), p2i(_icms_stop_limit), percent_of_space(space, _icms_stop_limit)); } ConcurrentMarkSweepThread::start_icms(); @@ -1227,7 +1229,7 @@ CMSCollector::allocation_limit_reached(Space* space, HeapWord* top, gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT ", new limit=" PTR_FORMAT " (" SIZE_FORMAT "%%)", - top, space->end(), + p2i(top), p2i(space->end()), percent_of_space(space, space->end())); } ConcurrentMarkSweepThread::stop_icms(); @@ -1502,7 +1504,7 @@ bool CMSCollector::shouldConcurrentCollect() { if (PrintCMSInitiationStatistics && stats().valid()) { gclog_or_tty->print("CMSCollector shouldConcurrentCollect: "); gclog_or_tty->stamp(); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); stats().print_on(gclog_or_tty); gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full()); @@ -3588,7 +3590,7 @@ CMSPhaseAccounting::~CMSPhaseAccounting() { _collector->cmsGen()->short_name(), _phase, _collector->timerValue(), _wallclock.seconds()); if (_print_cr) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); } if (PrintCMSStatistics != 0) { gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase, @@ -6360,7 +6362,9 @@ void CMSCollector::sweep(bool asynch) { verify_overflow_empty(); if (should_unload_classes()) { - ClassLoaderDataGraph::purge(); + // Delay purge to the beginning of the next safepoint. Metaspace::contains + // requires that the virtual spaces are stable and not deleted. + ClassLoaderDataGraph::set_should_purge(true); } _intra_sweep_timer.stop(); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp index 75c1ddcc0dd..0479143d4f9 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ void ConcurrentMarkSweepThread::run() { // From this time Thread::current() should be working. assert(this == Thread::current(), "just checking"); if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { - warning("Couldn't bind CMS thread to processor %u", CPUForCMSThread); + warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread); } // Wait until Universe::is_fully_initialized() { diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp index 7da7511905f..5f508cc09a4 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -239,7 +239,7 @@ inline void ConcurrentMarkSweepThread::trace_state(const char* desc) { jio_snprintf(buf, sizeof(buf), " [%.3f: CMSThread %s] ", ts.seconds(), desc); buf[sizeof(buf) - 1] = '\0'; - gclog_or_tty->print(buf); + gclog_or_tty->print("%s", buf); } } @@ -271,7 +271,7 @@ class CMSLoopCountWarn: public StackObj { inline void tick() { _ticks++; if (CMSLoopWarn && _ticks % _threshold == 0) { - warning("%s has looped %d times %s", _src, _ticks, _msg); + warning("%s has looped " INTX_FORMAT " times %s", _src, _ticks, _msg); } } }; diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp index 34ee7d67b9a..133ed3c5969 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "memory/freeBlockDictionary.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifndef PRODUCT #define baadbabeHeapWord badHeapWordVal diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp index cc870308548..44f5a287c6e 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "oops/markOop.inline.hpp" #include "oops/oop.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ///////////////////////////////////////////////////////////////////////// //// PromotionInfo ///////////////////////////////////////////////////////////////////////// diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp index 46c0650a772..ca1a1124643 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ #include "runtime/os.hpp" #include "utilities/dtrace.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC ////////////////////////////////////////////////////////// // Methods in abstract class VM_CMS_Operation diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index de13a943c10..24c62d775bd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" +#include "runtime/prefetch.inline.hpp" #include "services/memTracker.hpp" // Concurrent marking bit map wrapper @@ -537,7 +538,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : if (verbose_low()) { gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", " - "heap end = "PTR_FORMAT, _heap_start, _heap_end); + "heap end = " PTR_FORMAT, p2i(_heap_start), p2i(_heap_end)); } if (!_markBitMap1.allocate(heap_rs)) { @@ -651,7 +652,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : if (!(mark_stack_size >= 1 && mark_stack_size <= MarkStackSizeMax)) { warning("Invalid value calculated for MarkStackSize (" UINTX_FORMAT "): " "must be between " UINTX_FORMAT " and " UINTX_FORMAT, - mark_stack_size, 1, MarkStackSizeMax); + mark_stack_size, (uintx) 1, MarkStackSizeMax); return; } FLAG_SET_ERGO(uintx, MarkStackSize, mark_stack_size); @@ -662,7 +663,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : if (!(MarkStackSize >= 1 && MarkStackSize <= MarkStackSizeMax)) { warning("Invalid value specified for MarkStackSize (" UINTX_FORMAT "): " "must be between " UINTX_FORMAT " and " UINTX_FORMAT, - MarkStackSize, 1, MarkStackSizeMax); + MarkStackSize, (uintx) 1, MarkStackSizeMax); return; } } else if (FLAG_IS_CMDLINE(MarkStackSizeMax)) { @@ -819,9 +820,9 @@ void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurren // false before we start remark. At this point we should also be // in a STW phase. assert(!concurrent_marking_in_progress(), "invariant"); - assert(_finger == _heap_end, + assert(out_of_regions(), err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, - _finger, _heap_end)); + p2i(_finger), p2i(_heap_end))); update_g1_committed(true); } } @@ -978,7 +979,9 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { if (concurrent()) { SuspendibleThreadSet::leave(); } - _first_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_first_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } @@ -986,7 +989,17 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { // more work if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted first barrier", worker_id); + } else { + gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + } + } + + if (barrier_aborted) { + // If the barrier aborted we ignore the overflow condition and + // just abort the whole marking phase as quickly as possible. + return; } // If we're executing the concurrent phase of marking, reset the marking @@ -1026,14 +1039,20 @@ void ConcurrentMark::enter_second_sync_barrier(uint worker_id) { if (concurrent()) { SuspendibleThreadSet::leave(); } - _second_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_second_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everything should be re-initialized and ready to go if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted second barrier", worker_id); + } else { + gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + } } } @@ -1424,7 +1443,7 @@ public: assert(start <= hr->end() && start <= ntams && ntams <= hr->end(), err_msg("Preconditions not met - " "start: "PTR_FORMAT", ntams: "PTR_FORMAT", end: "PTR_FORMAT, - start, ntams, hr->end())); + p2i(start), p2i(ntams), p2i(hr->end()))); // Find the first marked object at or after "start". start = _bm->getNextMarkedWordAddress(start, ntams); @@ -1609,7 +1628,7 @@ public: if (failures > 0 && _verbose) { gclog_or_tty->print_cr("Region " HR_FORMAT ", ntams: " PTR_FORMAT ", " "marked_bytes: calc/actual " SIZE_FORMAT "/" SIZE_FORMAT, - HR_FORMAT_PARAMS(hr), hr->next_top_at_mark_start(), + HR_FORMAT_PARAMS(hr), p2i(hr->next_top_at_mark_start()), _calc_cl.region_marked_bytes(), hr->next_marked_bytes()); } @@ -2241,7 +2260,7 @@ class G1CMKeepAliveAndDrainClosure: public OopClosure { if (_cm->verbose_high()) { gclog_or_tty->print_cr("\t[%u] we're looking at location " "*"PTR_FORMAT" = "PTR_FORMAT, - _task->worker_id(), p, (void*) obj); + _task->worker_id(), p2i(p), p2i((void*) obj)); } _task->deal_with_reference(obj); @@ -2675,7 +2694,7 @@ public: } _out->print_cr(" "PTR_FORMAT": "PTR_FORMAT"%s%s", - p, (void*) obj, str, str2); + p2i(p), p2i((void*) obj), str, str2); } }; @@ -2702,7 +2721,7 @@ public: if (print_it) { _out->print_cr(" "PTR_FORMAT"%s", - (void *)o, (over_tams) ? " >" : (marked) ? " M" : ""); + p2i((void *)o), (over_tams) ? " >" : (marked) ? " M" : ""); PrintReachableOopClosure oopCl(_out, _vo, _all); o->oop_iterate_no_header(&oopCl); } @@ -2723,14 +2742,14 @@ public: HeapWord* t = hr->top(); HeapWord* p = _g1h->top_at_mark_start(hr, _vo); _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" " - "TAMS: "PTR_FORMAT, b, e, t, p); + "TAMS: " PTR_FORMAT, p2i(b), p2i(e), p2i(t), p2i(p)); _out->cr(); HeapWord* from = b; HeapWord* to = t; if (to > from) { - _out->print_cr("Objects in ["PTR_FORMAT", "PTR_FORMAT"]", from, to); + _out->print_cr("Objects in [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(from), p2i(to)); _out->cr(); PrintReachableObjectClosure ocl(_out, _vo, _all, hr); hr->object_iterate_mem_careful(MemRegion(from, to), &ocl); @@ -2846,7 +2865,7 @@ ConcurrentMark::claim_region(uint worker_id) { gclog_or_tty->print_cr("[%u] curr_region = "PTR_FORMAT" " "["PTR_FORMAT", "PTR_FORMAT"), " "limit = "PTR_FORMAT, - worker_id, curr_region, bottom, end, limit); + worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit)); } // Is the gap between reading the finger and doing the CAS too long? @@ -2860,13 +2879,13 @@ ConcurrentMark::claim_region(uint worker_id) { if (verbose_low()) { gclog_or_tty->print_cr("[%u] we were successful with region = " - PTR_FORMAT, worker_id, curr_region); + PTR_FORMAT, worker_id, p2i(curr_region)); } if (limit > bottom) { if (verbose_low()) { gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is not empty, " - "returning it ", worker_id, curr_region); + "returning it ", worker_id, p2i(curr_region)); } return curr_region; } else { @@ -2874,7 +2893,7 @@ ConcurrentMark::claim_region(uint worker_id) { "the region limit should be at bottom"); if (verbose_low()) { gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is empty, " - "returning NULL", worker_id, curr_region); + "returning NULL", worker_id, p2i(curr_region)); } // we return NULL and the caller should try calling // claim_region() again. @@ -2886,7 +2905,7 @@ ConcurrentMark::claim_region(uint worker_id) { gclog_or_tty->print_cr("[%u] somebody else moved the finger, " "global finger = "PTR_FORMAT", " "our finger = "PTR_FORMAT, - worker_id, _finger, finger); + worker_id, p2i(_finger), p2i(finger)); } // read it again @@ -2925,7 +2944,7 @@ private: void do_object_work(oop obj) { guarantee(!_g1h->obj_in_cs(obj), err_msg("obj: "PTR_FORMAT" in CSet, phase: %s, info: %d", - (void*) obj, phase_str(), _info)); + p2i((void*) obj), phase_str(), _info)); } public: @@ -3004,7 +3023,7 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks, HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger); guarantee(global_finger == global_hr->bottom(), err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT, - global_finger, HR_FORMAT_PARAMS(global_hr))); + p2i(global_finger), HR_FORMAT_PARAMS(global_hr))); } // Verify the task fingers @@ -3018,7 +3037,7 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks, guarantee(task_finger == task_hr->bottom() || !task_hr->in_collection_set(), err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT, - task_finger, HR_FORMAT_PARAMS(task_hr))); + p2i(task_finger), HR_FORMAT_PARAMS(task_hr))); } } } @@ -3062,7 +3081,7 @@ class AggregateCountDataHRClosure: public HeapRegionClosure { err_msg("Preconditions not met - " "start: "PTR_FORMAT", limit: "PTR_FORMAT", " "top: "PTR_FORMAT", end: "PTR_FORMAT, - start, limit, hr->top(), hr->end())); + p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end()))); assert(hr->next_marked_bytes() == 0, "Precondition"); @@ -3240,6 +3259,8 @@ void ConcurrentMark::abort() { for (uint i = 0; i < _max_worker_id; ++i) { _tasks[i]->clear_region_fields(); } + _first_overflow_barrier_sync.abort(); + _second_overflow_barrier_sync.abort(); _has_aborted = true; SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); @@ -3303,7 +3324,7 @@ void ConcurrentMark::print_worker_threads_on(outputStream* st) const { void ConcurrentMark::print_on_error(outputStream* st) const { st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT, - _prevMarkBitMap, _nextMarkBitMap); + p2i(_prevMarkBitMap), p2i(_nextMarkBitMap)); _prevMarkBitMap->print_on_error(st, " Prev Bits: "); _nextMarkBitMap->print_on_error(st, " Next Bits: "); } @@ -3336,11 +3357,11 @@ bool ConcurrentMark::containing_cards_are_marked(void* start, // for debugging purposes void ConcurrentMark::print_finger() { gclog_or_tty->print_cr("heap ["PTR_FORMAT", "PTR_FORMAT"), global finger = "PTR_FORMAT, - _heap_start, _heap_end, _finger); + p2i(_heap_start), p2i(_heap_end), p2i(_finger)); for (uint i = 0; i < _max_worker_id; ++i) { - gclog_or_tty->print(" %u: "PTR_FORMAT, i, _tasks[i]->finger()); + gclog_or_tty->print(" %u: " PTR_FORMAT, i, p2i(_tasks[i]->finger())); } - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); } #endif @@ -3349,7 +3370,7 @@ void CMTask::scan_object(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] we're scanning object "PTR_FORMAT, - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } size_t obj_size = obj->size(); @@ -3428,7 +3449,7 @@ void CMTask::setup_for_region(HeapRegion* hr) { if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] setting up for region "PTR_FORMAT, - _worker_id, hr); + _worker_id, p2i(hr)); } _curr_region = hr; @@ -3445,7 +3466,7 @@ void CMTask::update_region_limit() { if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] found an empty region " "["PTR_FORMAT", "PTR_FORMAT")", - _worker_id, bottom, limit); + _worker_id, p2i(bottom), p2i(limit)); } // The region was collected underneath our feet. // We set the finger to bottom to ensure that the bitmap @@ -3477,7 +3498,7 @@ void CMTask::giveup_current_region() { assert(_curr_region != NULL, "invariant"); if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] giving up region "PTR_FORMAT, - _worker_id, _curr_region); + _worker_id, p2i(_curr_region)); } clear_region_fields(); } @@ -3768,7 +3789,7 @@ void CMTask::drain_local_queue(bool partially) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] popped "PTR_FORMAT, _worker_id, - (void*) obj); + p2i((void*) obj)); } assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" ); @@ -4153,7 +4174,7 @@ void CMTask::do_marking_step(double time_target_ms, gclog_or_tty->print_cr("[%u] we're scanning part " "["PTR_FORMAT", "PTR_FORMAT") " "of region "HR_FORMAT, - _worker_id, _finger, _region_limit, + _worker_id, p2i(_finger), p2i(_region_limit), HR_FORMAT_PARAMS(_curr_region)); } @@ -4240,7 +4261,7 @@ void CMTask::do_marking_step(double time_target_ms, if (_cm->verbose_low()) { gclog_or_tty->print_cr("[%u] we successfully claimed " "region "PTR_FORMAT, - _worker_id, claimed_region); + _worker_id, p2i(claimed_region)); } setup_for_region(claimed_region); @@ -4301,7 +4322,7 @@ void CMTask::do_marking_step(double time_target_ms, if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) { if (_cm->verbose_medium()) { gclog_or_tty->print_cr("[%u] stolen "PTR_FORMAT" successfully", - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } statsOnly( ++_steals ); @@ -4549,8 +4570,8 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name) G1PPRL_SUM_ADDR_FORMAT("committed") G1PPRL_SUM_ADDR_FORMAT("reserved") G1PPRL_SUM_BYTE_FORMAT("region-size"), - g1_committed.start(), g1_committed.end(), - g1_reserved.start(), g1_reserved.end(), + p2i(g1_committed.start()), p2i(g1_committed.end()), + p2i(g1_reserved.start()), p2i(g1_reserved.end()), HeapRegion::GrainBytes); _out->print_cr(G1PPRL_LINE_PREFIX); _out->print_cr(G1PPRL_LINE_PREFIX @@ -4667,7 +4688,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) { G1PPRL_DOUBLE_FORMAT G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT, - type, bottom, end, + type, p2i(bottom), p2i(end), used_bytes, prev_live_bytes, next_live_bytes, gc_eff, remset_bytes, strong_code_roots_bytes); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 21327485863..9d049a2a255 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -542,8 +542,12 @@ protected: // frequently. HeapRegion* claim_region(uint worker_id); - // It determines whether we've run out of regions to scan - bool out_of_regions() { return _finger == _heap_end; } + // It determines whether we've run out of regions to scan. Note that + // the finger can point past the heap end in case the heap was expanded + // to satisfy an allocation without doing a GC. This is fine, because all + // objects in those regions will be considered live anyway because of + // SATB guarantees (i.e. their TAMS will be equal to bottom). + bool out_of_regions() { return _finger >= _heap_end; } // Returns the task with the given id CMTask* task(int id) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp index e4ca5ecee5e..12ba5683ed8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -277,7 +277,7 @@ inline void CMTask::push(oop obj) { assert(_nextMarkBitMap->isMarked(objAddr), "invariant"); if (_cm->verbose_high()) { - gclog_or_tty->print_cr("[%u] pushing "PTR_FORMAT, _worker_id, (void*) obj); + gclog_or_tty->print_cr("[%u] pushing " PTR_FORMAT, _worker_id, p2i((void*) obj)); } if (!_task_queue->push(obj)) { @@ -317,7 +317,7 @@ inline void CMTask::push(oop obj) { inline void CMTask::deal_with_reference(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT, - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } ++_refs_reached; @@ -334,7 +334,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (!hr->obj_allocated_since_next_marking(obj)) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked", - _worker_id, (void*) obj); + _worker_id, p2i((void*) obj)); } // we need to mark it first @@ -349,7 +349,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (_finger != NULL && objAddr < _finger) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), " - "pushing it", _worker_id, _finger); + "pushing it", _worker_id, p2i(_finger)); } push(obj); } else if (_curr_region != NULL && objAddr < _region_limit) { @@ -367,7 +367,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] below the global finger " "("PTR_FORMAT"), pushing it", - _worker_id, global_finger); + _worker_id, p2i(global_finger)); } push(obj); } else { @@ -382,7 +382,7 @@ inline void CMTask::deal_with_reference(oop obj) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] below the global finger " "("PTR_FORMAT"), pushing it", - _worker_id, global_finger); + _worker_id, p2i(global_finger)); } push(obj); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp index 58a76c1dd26..a0d994738fd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,7 +143,7 @@ HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size, void G1AllocRegion::fill_in_ext_msg(ar_ext_msg* msg, const char* message) { msg->append("[%s] %s c: %u b: %s r: "PTR_FORMAT" u: "SIZE_FORMAT, _name, message, _count, BOOL_TO_STR(_bot_updates), - _alloc_region, _used_bytes_before); + p2i(_alloc_region), _used_bytes_before); } void G1AllocRegion::init() { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp index 3f6e040bf54..050490dbbef 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -184,7 +184,7 @@ public: class ar_ext_msg : public err_msg { public: - ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("") { + ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("%s", "") { alloc_region->fill_in_ext_msg(this, message); } }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp index d5851a6d467..8c5bef77122 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public: REGION_SIZE_IN_WORDS * HeapWordSize); // Check address calculation (bounds) assert(array.bottom_address_mapped() == fake_heap, - err_msg("bottom mapped address should be "PTR_FORMAT", but is "PTR_FORMAT, fake_heap, array.bottom_address_mapped())); + err_msg("bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped()))); assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be"); int* bottom = array.address_mapped_to(fake_heap); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp index b0b7a76e1fe..f7ec3e39f2d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ protected: void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) { assert(base != NULL, "just checking"); assert(length > 0, "just checking"); - assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %zd, larger than word size?", shift_by)); + assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %u, larger than word size?", shift_by)); _base = base; _length = length; _biased_base = base - (bias * elem_size); @@ -71,10 +71,10 @@ protected: err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes)); assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, - mapping_granularity_in_bytes, bottom)); + mapping_granularity_in_bytes, p2i(bottom))); assert((uintptr_t)end % mapping_granularity_in_bytes == 0, err_msg("end mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, - mapping_granularity_in_bytes, end)); + mapping_granularity_in_bytes, p2i(end))); size_t num_target_elems = pointer_delta(end, bottom, mapping_granularity_in_bytes); idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp index 9777c17b5a8..14d0126e224 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "runtime/java.hpp" #include "services/memTracker.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ////////////////////////////////////////////////////////////////////// // G1BlockOffsetSharedArray ////////////////////////////////////////////////////////////////////// diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp index ba664ee5275..56dca4d26f8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ public: virtual void set_bottom(HeapWord* new_bottom) { assert(new_bottom <= _end, err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")", - new_bottom, _end)); + p2i(new_bottom), p2i(_end))); _bottom = new_bottom; resize(pointer_delta(_end, _bottom)); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp index d300f56255f..5ae3bc1cdeb 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const { assert(pc >= (char*)_reserved.start() && pc < (char*)_reserved.end(), err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")", - p, (char*)_reserved.start(), (char*)_reserved.end())); + p2i(p), p2i(_reserved.start()), p2i(_reserved.end()))); size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char)); size_t result = delta >> LogN; check_index(result, "bad index from address"); @@ -65,7 +65,7 @@ G1BlockOffsetSharedArray::address_for_index(size_t index) const { err_msg("bad address from index result " PTR_FORMAT " _reserved.start() " PTR_FORMAT " _reserved.end() " PTR_FORMAT, - result, _reserved.start(), _reserved.end())); + p2i(result), p2i(_reserved.start()), p2i(_reserved.end()))); return result; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index ccb7c3f10b3..9fff9604ff2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "services/memTracker.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) { if (has_count_table()) { assert(from_card_num >= 0 && from_card_num < _committed_max_card_num, diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp index 129b3b0d232..ef08479f60a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,10 +77,10 @@ class G1CardCounts: public CHeapObj { err_msg("Invalid card pointer: " "card_ptr: " PTR_FORMAT ", " "_ct_bot: " PTR_FORMAT, - card_ptr, _ct_bot)); + p2i(card_ptr), p2i(_ct_bot))); size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte)); assert(card_num >= 0 && card_num < _committed_max_card_num, - err_msg("card pointer out of range: " PTR_FORMAT, card_ptr)); + err_msg("card pointer out of range: " PTR_FORMAT, p2i(card_ptr))); return card_num; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp index 1130278fa91..fbe7095f75c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp @@ -28,6 +28,8 @@ #include "gc_implementation/g1/g1CodeCacheRemSet.hpp" #include "memory/iterator.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + G1CodeRootChunk::G1CodeRootChunk() : _top(NULL), _next(NULL), _prev(NULL) { _top = bottom(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 46feeea2841..060ffb0b4a6 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -22,7 +22,13 @@ * */ +#if !defined(__clang_major__) && defined(__GNUC__) +// FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information. +#define ATTRIBUTE_PRINTF(x,y) +#endif + #include "precompiled.hpp" +#include "classfile/stringTable.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "gc_implementation/g1/bufferingOopClosure.hpp" @@ -56,6 +62,7 @@ #include "memory/referenceProcessor.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.pcgc.inline.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/vmThread.hpp" #include "utilities/globalDefinitions.hpp" @@ -370,7 +377,7 @@ void YoungList::print() { } } - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); } void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) @@ -3470,7 +3477,7 @@ void G1CollectedHeap::verify(bool silent, VerifyOption vo) { // help us track down what went wrong. This is why we call // print_extended_on() instead of print_on(). print_extended_on(gclog_or_tty); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); #ifndef PRODUCT if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { concurrent_mark()->print_reachable("at-verification-failure", @@ -3664,7 +3671,7 @@ public: PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { gclog_or_tty->cr(); gclog_or_tty->print_cr("========================================"); - gclog_or_tty->print_cr(msg); + gclog_or_tty->print_cr("%s", msg); gclog_or_tty->cr(); } @@ -5395,7 +5402,7 @@ public: if (_g1h->is_in_g1_reserved(p)) { _par_scan_state->push_on_queue(p); } else { - assert(!ClassLoaderDataGraph::contains((address)p), + assert(!Metaspace::contains((const void*)p), err_msg("Otherwise need to call _copy_metadata_obj_cl->do_oop(p) " PTR_FORMAT, p)); _copy_non_heap_obj_cl->do_oop(p); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp index b308d4a00dd..42a5931815b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ G1CollectedHeap::heap_region_containing_raw(const T addr) const { assert(addr != NULL, "invariant"); assert(_g1_reserved.contains((const void*) addr), err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")", - (void*)addr, _g1_reserved.start(), _g1_reserved.end())); + p2i((void*)addr), p2i(_g1_reserved.start()), p2i(_g1_reserved.end()))); return _hrs.addr_to_region((HeapWord*) addr); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index a0b40d4dbf1..89b6f3fa616 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,11 @@ * */ +#ifndef __clang_major__ +// FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information. +#define ATTRIBUTE_PRINTF(x,y) +#endif + #include "precompiled.hpp" #include "gc_implementation/g1/concurrentG1Refine.hpp" #include "gc_implementation/g1/concurrentMark.hpp" @@ -965,7 +970,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, Evacua #ifndef PRODUCT if (G1YoungSurvRateVerbose) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); _short_lived_surv_rate_group->print(); // do that for any other surv rate groups too } @@ -2222,11 +2227,11 @@ void TraceGen0TimeData::print() const { gclog_or_tty->print_cr("ALL PAUSES"); print_summary_sd(" Total", &_total); - gclog_or_tty->print_cr(""); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); + gclog_or_tty->cr(); gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num); gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("EVACUATION PAUSES"); @@ -2246,7 +2251,7 @@ void TraceGen0TimeData::print() const { print_summary(" Clear CT", &_clear_ct); print_summary(" Other", &_other); } - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("MISC"); print_summary_sd(" Stop World", &_all_stop_world_times_ms); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp index c4c3432ad43..8e361b63638 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp @@ -39,7 +39,7 @@ private: int _indent_level; int _cur; - void vappend(const char* format, va_list ap) { + void vappend(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0) { int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap); if (res != -1) { _cur += res; @@ -63,14 +63,14 @@ public: } #endif - void append(const char* format, ...) { + void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { va_list ap; va_start(ap, format); vappend(format, ap); va_end(ap); } - void append_and_print_cr(const char* format, ...) { + void append_and_print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { va_list ap; va_start(ap, format); vappend(format, ap); @@ -80,6 +80,8 @@ public: } }; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED template void WorkerDataArray::print(int level, const char* title) { if (_length == 1) { @@ -109,7 +111,7 @@ void WorkerDataArray::print(int level, const char* title) { } if (G1Log::finest()) { - buf.append_and_print_cr(""); + buf.append_and_print_cr("%s", ""); } double avg = (double)sum / (double)_length; @@ -129,6 +131,7 @@ void WorkerDataArray::print(int level, const char* title) { } buf.append_and_print_cr("]"); } +PRAGMA_DIAG_POP #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp index 56a1a3be8a3..8139048ef23 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HRPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "gc_implementation/g1/heapRegion.hpp" #include "utilities/ostream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + const char* G1HRPrinter::action_name(ActionType action) { switch(action) { case Alloc: return "ALLOC"; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp index 1fa7639729c..48c024d7470 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "gc_implementation/g1/g1RemSet.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" +#include "runtime/prefetch.inline.hpp" /* * This really ought to be an inline function, but apparently the C++ @@ -114,7 +115,7 @@ inline void G1CMOopClosure::do_oop_nv(T* p) { if (_cm->verbose_high()) { gclog_or_tty->print_cr("[%u] we're looking at location " "*"PTR_FORMAT" = "PTR_FORMAT, - _task->worker_id(), p, (void*) obj); + _task->worker_id(), p2i(p), p2i((void*) obj)); } _task->deal_with_reference(obj); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 58212625c82..69b17c56702 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/intHisto.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define CARD_REPEAT_HISTO 0 #if CARD_REPEAT_HISTO diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index 756ea3e233b..e741a0f7951 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -96,7 +96,15 @@ void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) { jbyte *const first = byte_for(mr.start()); jbyte *const last = byte_after(mr.last()); - memset(first, g1_young_gen, last - first); + // Below we may use an explicit loop instead of memset() because on + // certain platforms memset() can give concurrent readers phantom zeros. + if (UseMemSetInBOT) { + memset(first, g1_young_gen, last - first); + } else { + for (jbyte* i = first; i < last; i++) { + *i = g1_young_gen; + } + } } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 57feb98db2e..c12e3fe840c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -32,9 +32,12 @@ #include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" +#include "memory/space.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/orderAccess.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + int HeapRegion::LogOfHRGrainBytes = 0; int HeapRegion::LogOfHRGrainWords = 0; size_t HeapRegion::GrainBytes = 0; @@ -827,7 +830,7 @@ public: Mutex::_no_safepoint_check_flag); if (!_failures) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("----------"); } if (!_g1h->is_in_closed_subset(obj)) { @@ -882,7 +885,7 @@ public: Mutex::_no_safepoint_check_flag); if (!_failures) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("----------"); } gclog_or_tty->print_cr("Missing rem set entry:"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index b10f32674cc..25ffe1c8264 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ class nmethod; (_hr_)->startsHumongous() ? "HS" : \ (_hr_)->continuesHumongous() ? "HC" : \ !(_hr_)->is_empty() ? "O" : "F", \ - (_hr_)->bottom(), (_hr_)->top(), (_hr_)->end() + p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end()) // sentinel value for hrs_index #define G1_NULL_HRS_INDEX ((uint) -1) @@ -550,7 +550,7 @@ class HeapRegion: public G1OffsetTableContigSpace { (containing_set != NULL && _containing_set == NULL), err_msg("containing_set: "PTR_FORMAT" " "_containing_set: "PTR_FORMAT, - containing_set, _containing_set)); + p2i(containing_set), p2i(_containing_set))); _containing_set = containing_set; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp index 016e7b0109d..382a3fb32ec 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @@ -36,6 +36,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class PerRegionTable: public CHeapObj { friend class OtherRegionsTable; friend class HeapRegionRemSetIterator; @@ -1218,7 +1220,7 @@ void HeapRegionRemSet::print_recorded() { while (cur_evnt < _n_recorded_events && i == cur_evnt_ind) { gclog_or_tty->print("Event: "); print_event(gclog_or_tty, cur_evnt_kind); - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); cur_evnt++; if (cur_evnt < MaxRecordedEvents) { cur_evnt_kind = _recorded_events[cur_evnt]; diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp index 62638a8f9b3..04f48e60550 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ void HeapRegionSeq::verify_optional() { guarantee(hr != NULL, err_msg("invariant: i: %u", i)); guarantee(hr->bottom() == prev_end, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, - i, HR_FORMAT_PARAMS(hr), prev_end)); + i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); guarantee(hr->hrs_index() == i, err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); if (i < length()) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp index 429457a488f..4028b7a4a5d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,9 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { assert(addr < heap_end(), - err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, addr, heap_end())); + err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end()))); assert(addr >= heap_bottom(), - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom())); + err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom()))); HeapRegion* hr = _regions.get_by_address(addr); assert(hr != NULL, "invariant"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp index 6ec03d5ceae..fa5ab14287e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp @@ -26,6 +26,8 @@ #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + uint FreeRegionList::_unrealistically_long_length = 0; void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp index c54fc784719..222fc694f4c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp @@ -162,7 +162,7 @@ public: // diagnosing failures. class hrs_ext_msg : public hrs_err_msg { public: - hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") { + hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("%s","") { set->fill_in_ext_msg(this, message); } }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp index 7930e581b98..8a0e42ea4e5 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "runtime/thread.hpp" #include "runtime/vmThread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void ObjPtrQueue::flush() { // The buffer might contain refs into the CSet. We have to filter it // first before we flush it, otherwise we might end up with an diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp index 11f30c36283..fe33cef7d28 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,23 +194,16 @@ bool RSHashTable::add_card(RegionIdx_t region_ind, CardIdx_t card_index) { } bool RSHashTable::get_cards(RegionIdx_t region_ind, CardIdx_t* cards) { - int ind = (int) (region_ind & capacity_mask()); - int cur_ind = _buckets[ind]; - SparsePRTEntry* cur; - while (cur_ind != NullEntry && - (cur = entry(cur_ind))->r_ind() != region_ind) { - cur_ind = cur->next_index(); + SparsePRTEntry* entry = get_entry(region_ind); + if (entry == NULL) { + return false; } - - if (cur_ind == NullEntry) return false; // Otherwise... - assert(cur->r_ind() == region_ind, "Postcondition of loop + test above."); - assert(cur->num_valid_cards() > 0, "Inv"); - cur->copy_cards(cards); + entry->copy_cards(cards); return true; } -SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) { +SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) const { int ind = (int) (region_ind & capacity_mask()); int cur_ind = _buckets[ind]; SparsePRTEntry* cur; @@ -246,28 +239,9 @@ bool RSHashTable::delete_entry(RegionIdx_t region_ind) { return true; } -SparsePRTEntry* -RSHashTable::entry_for_region_ind(RegionIdx_t region_ind) const { - assert(occupied_entries() < capacity(), "Precondition"); - int ind = (int) (region_ind & capacity_mask()); - int cur_ind = _buckets[ind]; - SparsePRTEntry* cur; - while (cur_ind != NullEntry && - (cur = entry(cur_ind))->r_ind() != region_ind) { - cur_ind = cur->next_index(); - } - - if (cur_ind != NullEntry) { - assert(cur->r_ind() == region_ind, "Loop postcondition + test"); - return cur; - } else { - return NULL; - } -} - SparsePRTEntry* RSHashTable::entry_for_region_ind_create(RegionIdx_t region_ind) { - SparsePRTEntry* res = entry_for_region_ind(region_ind); + SparsePRTEntry* res = get_entry(region_ind); if (res == NULL) { int new_ind = alloc_entry(); assert(0 <= new_ind && (size_t)new_ind < capacity(), "There should be room."); @@ -365,7 +339,7 @@ bool RSHashTableIter::has_next(size_t& card_index) { } bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const { - SparsePRTEntry* e = entry_for_region_ind(region_index); + SparsePRTEntry* e = get_entry(region_index); return (e != NULL && e->contains_card(card_index)); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp index 6094837d35a..a534ceca5f1 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,12 +119,6 @@ class RSHashTable : public CHeapObj { int _free_region; int _free_list; - // Requires that the caller hold a lock preventing parallel modifying - // operations, and that the the table be less than completely full. If - // an entry for "region_ind" is already in the table, finds it and - // returns its address; otherwise returns "NULL." - SparsePRTEntry* entry_for_region_ind(RegionIdx_t region_ind) const; - // Requires that the caller hold a lock preventing parallel modifying // operations, and that the the table be less than completely full. If // an entry for "region_ind" is already in the table, finds it and @@ -158,7 +152,7 @@ public: void add_entry(SparsePRTEntry* e); - SparsePRTEntry* get_entry(RegionIdx_t region_id); + SparsePRTEntry* get_entry(RegionIdx_t region_id) const; void clear(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp index 49e4e01fa9e..3121c9c664e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "gc_implementation/g1/survRateGroup.hpp" #include "memory/allocation.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + SurvRateGroup::SurvRateGroup(G1CollectorPolicy* g1p, const char* name, size_t summary_surv_rates_len) : @@ -202,7 +204,7 @@ SurvRateGroup::print_surv_rate_summary() { if (length == 0) return; - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1); gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); gclog_or_tty->print_cr(" ---------------------------------------------------------"); diff --git a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp index 6d0e1a2243c..9b39c289900 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -259,22 +259,22 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, requested_eden_size, requested_survivor_size); gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - eden()->bottom(), - eden()->end(), + p2i(eden()->bottom()), + p2i(eden()->end()), pointer_delta(eden()->end(), eden()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - from()->bottom(), - from()->end(), + p2i(from()->bottom()), + p2i(from()->end()), pointer_delta(from()->end(), from()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - to()->bottom(), - to()->end(), + p2i(to()->bottom()), + p2i(to()->end()), pointer_delta( to()->end(), to()->bottom(), sizeof(char))); @@ -382,18 +382,18 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); } } else { @@ -473,18 +473,18 @@ void ASParNewGeneration::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); } } diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp index 3a03b93a56f..c1033579cf5 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ #include "runtime/virtualspace.hpp" #include "runtime/vmThread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, OopsInGenClosure* cl, CardTableRS* ct, diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 41c7bb827d8..2661e1280b6 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/workgroup.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable:4355 ) // 'this' : used in base member initializer list diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp index 383a579bec9..2a3e3207195 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,12 +79,12 @@ inline void ParScanClosure::do_oop_work(T* p, if ((HeapWord*)obj < _boundary) { #ifndef PRODUCT if (_g->to()->is_in_reserved(obj)) { - tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p); + tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p2i(p)); GenCollectedHeap* gch = (GenCollectedHeap*)Universe::heap(); Space* sp = gch->space_containing(p); oop obj = oop(sp->block_start(p)); assert((HeapWord*)obj < (HeapWord*)p, "Error"); - tty->print_cr("Object: " PTR_FORMAT, (void *)obj); + tty->print_cr("Object: " PTR_FORMAT, p2i((void *)obj)); tty->print_cr("-------"); obj->print(); tty->print_cr("-----"); @@ -110,7 +110,7 @@ inline void ParScanClosure::do_oop_work(T* p, if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarded ", - new_obj->klass()->internal_name(), p, (void *)obj, (void *)new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp index f403a3a3a62..d711104e459 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,22 +252,22 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, requested_eden_size, requested_survivor_size); gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - eden_space()->bottom(), - eden_space()->end(), + p2i(eden_space()->bottom()), + p2i(eden_space()->end()), pointer_delta(eden_space()->end(), eden_space()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - from_space()->bottom(), - from_space()->end(), + p2i(from_space()->bottom()), + p2i(from_space()->end()), pointer_delta(from_space()->end(), from_space()->bottom(), sizeof(char))); gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, - to_space()->bottom(), - to_space()->end(), + p2i(to_space()->bottom()), + p2i(to_space()->end()), pointer_delta( to_space()->end(), to_space()->bottom(), sizeof(char))); @@ -373,18 +373,18 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); } } else { @@ -427,18 +427,18 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - eden_start, - eden_end, + p2i(eden_start), + p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - to_start, - to_end, + p2i(to_start), + p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - from_start, - from_end, + p2i(from_start), + p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp index b49ccb05c1e..a2a6b55a27c 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "gc_implementation/parallelScavenge/psYoungGen.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" +#include "runtime/prefetch.inline.hpp" // Checks an individual oop for missing precise marks. Mark // may be either dirty or newgen. @@ -478,23 +479,23 @@ void CardTableExtension::resize_covered_region_by_end(int changed_region, gclog_or_tty->print_cr(" " " _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT, - ind, _covered[ind].start(), - ind, _covered[ind].last()); + ind, p2i(_covered[ind].start()), + ind, p2i(_covered[ind].last())); gclog_or_tty->print_cr(" " " _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT, - ind, _committed[ind].start(), - ind, _committed[ind].last()); + ind, p2i(_committed[ind].start()), + ind, p2i(_committed[ind].last())); gclog_or_tty->print_cr(" " " byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT, - byte_for(_covered[ind].start()), - byte_for(_covered[ind].last())); + p2i(byte_for(_covered[ind].start())), + p2i(byte_for(_covered[ind].last()))); gclog_or_tty->print_cr(" " " addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT, - addr_for((jbyte*) _committed[ind].start()), - addr_for((jbyte*) _committed[ind].last())); + p2i(addr_for((jbyte*) _committed[ind].start())), + p2i(addr_for((jbyte*) _committed[ind].last()))); } debug_only(verify_guard();) } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp index ac7a1a31e45..5aecfb2a984 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // // GCTask // diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp index ec2e28f5674..ec5ac692ebd 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ #include "runtime/os.hpp" #include "runtime/thread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + GCTaskThread::GCTaskThread(GCTaskManager* manager, uint which, uint processor_id) : diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp index 32f7eed82cb..8d0153d485d 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,7 +155,7 @@ public: static inline idx_t bits_required(MemRegion covered_region); void print_on_error(outputStream* st) const { - st->print_cr("Marking Bits: (ParMarkBitMap*) " PTR_FORMAT, this); + st->print_cr("Marking Bits: (ParMarkBitMap*) " PTR_FORMAT, p2i(this)); _beg_bits.print_on_error(st, " Begin Bits: "); _end_bits.print_on_error(st, " End Bits: "); } @@ -390,9 +390,9 @@ inline void ParMarkBitMap::verify_bit(idx_t bit) const { inline void ParMarkBitMap::verify_addr(HeapWord* addr) const { // Allow one past the last valid address; useful for loop bounds. assert(addr >= region_start(), - err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, addr, region_start())); + err_msg("addr too small, addr: " PTR_FORMAT " region start: " PTR_FORMAT, p2i(addr), p2i(region_start()))); assert(addr <= region_end(), - err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, addr, region_end())); + err_msg("addr too big, addr: " PTR_FORMAT " region end: " PTR_FORMAT, p2i(addr), p2i(region_end()))); } #endif // #ifdef ASSERT diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 9ebdb841dfd..5a2f4e79d95 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -373,7 +373,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate( if ((result == NULL) && (QueuedAllocationWarningCount > 0) && (loop_count % QueuedAllocationWarningCount == 0)) { warning("ParallelScavengeHeap::mem_allocate retries %d times \n\t" - " size=%d", loop_count, size); + " size=" SIZE_FORMAT, loop_count, size); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp index 47a7b90d984..1c646fe3e1d 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ inline bool ParallelScavengeHeap::is_in_young(oop p) { const void* loc = (void*) p; bool result = ((HeapWord*)p) >= young_gen()->reserved().start(); assert(result == young_gen()->is_in_reserved(p), - err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, (void*)p)); + err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, p2i((void*)p))); return result; } #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_INLINE_HPP diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp index 10932e6b9e6..5037c207c62 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ #include "runtime/vmThread.hpp" #include "services/management.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // // ThreadRootsMarkingTask // diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp index f28b7458c6d..229b9dd3cfa 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size, size_t init_promo_size, size_t init_survivor_size, @@ -1033,7 +1035,7 @@ size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint( "AdaptiveSizePolicy::adjust_promo_for_footprint " "adjusting tenured gen for footprint. " "starting promo size " SIZE_FORMAT - " reduced promo size " SIZE_FORMAT, + " reduced promo size " SIZE_FORMAT " promo delta " SIZE_FORMAT, desired_promo_size, reduced_size, change ); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index cdfc31911ee..19eaf27aae5 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -1,5 +1,6 @@ + /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" @@ -54,6 +55,8 @@ #include "utilities/events.hpp" #include "utilities/stack.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + elapsedTimer PSMarkSweep::_accumulated_time; jlong PSMarkSweep::_time_of_last_gc = 0; CollectorCounters* PSMarkSweep::_counters = NULL; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp index ee43825614b..dc79821cb37 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp @@ -32,6 +32,7 @@ #include "gc_implementation/shared/markSweep.inline.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" +#include "runtime/prefetch.inline.hpp" PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp index 8ffdb0fbb37..8ef5abefdef 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + inline const char* PSOldGen::select_name() { return UseParallelOldGC ? "ParOldGen" : "PSOldGen"; } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index e93f612e4bd..de4c8bcdfd6 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" @@ -62,6 +62,8 @@ #include +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // All sizes are in HeapWords. const size_t ParallelCompactData::Log2RegionSize = 16; // 64K words const size_t ParallelCompactData::RegionSize = (size_t)1 << Log2RegionSize; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp index 01b404eac55..93446fdbfa0 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PaddedEnd* PSPromotionManager::_manager_array = NULL; OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; PSOldGen* PSPromotionManager::_old_gen = NULL; @@ -136,7 +138,7 @@ PSPromotionManager::print_stats() { } const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); - for (uint i = 0; i < hlines; ++i) tty->print_cr(pm_stats_hdr[i]); + for (uint i = 0; i < hlines; ++i) tty->print_cr("%s", pm_stats_hdr[i]); for (uint i = 0; i < ParallelGCThreads + 1; ++i) { manager_array(i)->print_local_stats(i); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp index 2a45c240c9f..356c2585168 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -226,7 +226,7 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) { if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring", - new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index de18bd00d05..81510c905a1 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,7 +24,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" @@ -56,6 +57,7 @@ #include "services/memoryService.hpp" #include "utilities/stack.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC HeapWord* PSScavenge::_to_space_top_before_gc = NULL; int PSScavenge::_consecutive_skipped_scavenges = 0; @@ -833,7 +835,7 @@ void PSScavenge::initialize() { if (AlwaysTenure || NeverTenure) { assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1, - err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is ", MaxTenuringThreshold)); + err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is %d", (int) MaxTenuringThreshold)); _tenuring_threshold = MaxTenuringThreshold; } else { // We want to smooth out our startup times for the AdaptiveSizePolicy diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp index 3b8447988cb..8030aad21b9 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm, if (TraceScavenge && o->is_forwarded()) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarding", - new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size()); } #endif @@ -180,7 +180,7 @@ class PSScavengeKlassClosure: public KlassClosure { if (TraceScavenge) { ResourceMark rm; gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s", - klass, + p2i(klass), klass->external_name(), klass->has_modified_oops() ? "true" : "false"); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp index 90672fba061..910a29c5259 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ # include "os_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // PSVirtualSpace PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) : diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp index 1ea30b4027f..b5902a23381 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PSYoungGen::PSYoungGen(size_t initial_size, size_t min_size, size_t max_size) : diff --git a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp index 2fe4de9c30e..634d0a5ddc5 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp @@ -84,7 +84,7 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { if (AlwaysTenure || NeverTenure) { assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1, - err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is ", MaxTenuringThreshold)); + err_msg("MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is " UINTX_FORMAT, MaxTenuringThreshold)); result = MaxTenuringThreshold; } else { size_t total = 0; @@ -106,7 +106,7 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { gclog_or_tty->cr(); gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold " UINTX_FORMAT " (max threshold " UINTX_FORMAT ")", - desired_survivor_size*oopSize, result, MaxTenuringThreshold); + desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold); } size_t total = 0; @@ -115,8 +115,8 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { total += sizes[age]; if (sizes[age] > 0) { if (PrintTenuringDistribution) { - gclog_or_tty->print_cr("- age %3u: %10ld bytes, %10ld total", - age, sizes[age]*oopSize, total*oopSize); + gclog_or_tty->print_cr("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total", + age, sizes[age]*oopSize, total*oopSize); } } if (UsePerfData) { diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index d2282df167e..9459efbdefd 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { assert(demand >= 0, err_msg("Demand (" SSIZE_FORMAT ") should be non-negative for " PTR_FORMAT " (size=" SIZE_FORMAT ")", - demand, this, count)); + demand, p2i(this), count)); // Defensive: adjust for imprecision in event counting if (demand < 0) { demand = 0; diff --git a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp index b1563ac8686..477680727ba 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ void ImmutableSpace::print_short() const { void ImmutableSpace::print() const { print_short(); - tty->print_cr(" [%#-6lx,%#-6lx)", bottom(), end()); + tty->print_cr(" [" INTPTR_FORMAT_W(#-6) "," INTPTR_FORMAT_W(#-6) ")", p2i(bottom()), p2i(end())); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp index b4bc3f9aea5..07cbb23de4a 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "oops/objArrayKlass.inline.hpp" #include "oops/oop.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + uint MarkSweep::_total_invocations = 0; Stack MarkSweep::_marking_stack; diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp index 20a7a6aa789..8590e850b60 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ #include "oops/oop.inline.hpp" #include "runtime/thread.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) { _lgrp_spaces = new (ResourceObj::C_HEAP, mtGC) GrowableArray(0, true); _page_size = os::vm_page_size(); diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp index 7e5b5a81125..17a3ecbc14a 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #include "runtime/thread.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) { assert(MutableSpace::alignment() >= 0 && MutableSpace::alignment() % os::vm_page_size() == 0, diff --git a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp index 2198a86aff6..01781705f93 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ #include "oops/oop.inline.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) : _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL), _end(NULL), _hard_end(NULL), diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp index c2b42873a7c..15e38aa1ba1 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include "memory/space.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Catch-all file for utility classes #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 4b33afd66b7..1304092002e 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -599,12 +599,12 @@ void CollectedHeap::test_is_in() { assert(heap_start >= ((uintptr_t)NULL + epsilon), "sanity"); void* before_heap = (void*)(heap_start - epsilon); assert(!heap->is_in(before_heap), - err_msg("before_heap: " PTR_FORMAT " is unexpectedly in the heap", before_heap)); + err_msg("before_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(before_heap))); // Test that a pointer to after the heap end is reported as outside the heap. assert(heap_end <= ((uintptr_t)-1 - epsilon), "sanity"); void* after_heap = (void*)(heap_end + epsilon); assert(!heap->is_in(after_heap), - err_msg("after_heap: " PTR_FORMAT " is unexpectedly in the heap", after_heap)); + err_msg("after_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(after_heap))); } #endif diff --git a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp index 36867113eff..4600413dc5b 100644 --- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,7 +213,7 @@ void print_oop(oop value, outputStream* st) { st->print_cr(" %s", buf); } } else { - st->print_cr(" " PTR_FORMAT, (void *)value); + st->print_cr(" " INTPTR_FORMAT, p2i((void *)value)); } } @@ -282,7 +282,7 @@ bool BytecodePrinter::check_cp_cache_index(int i, int& cp_index, outputStream* s if (i >= 0 && i < climit) { cp_index = cache->entry_at(i)->constant_pool_index(); } else { - st->print_cr(" not in CP[*]?", i); + st->print_cr("%d not in CP[*]?", i); return false; } return true; @@ -297,7 +297,7 @@ bool BytecodePrinter::check_obj_index(int i, int& cp_index, outputStream* st) { cp_index = constants->object_to_cp_index(i); return true; } else { - st->print_cr(" not in OBJ[*]?", i); + st->print_cr("%d not in OBJ[*]?", i); return false; } } @@ -321,7 +321,7 @@ void BytecodePrinter::print_constant(int i, outputStream* st) { if (tag.is_int()) { st->print_cr(" " INT32_FORMAT, constants->int_at(i)); } else if (tag.is_long()) { - st->print_cr(" " INT64_FORMAT, constants->long_at(i)); + st->print_cr(" " INT64_FORMAT, (int64_t)(constants->long_at(i))); } else if (tag.is_float()) { st->print_cr(" %f", constants->float_at(i)); } else if (tag.is_double()) { @@ -340,7 +340,7 @@ void BytecodePrinter::print_constant(int i, outputStream* st) { } else if (tag.is_method_handle()) { int kind = constants->method_handle_ref_kind_at(i); int i2 = constants->method_handle_index_at(i); - st->print(" ", kind, i2); + st->print(" ", kind, i2); print_field_or_method(-i, i2, st); } else { st->print_cr(" bad tag=%d at %d", tag.value(), i); @@ -389,6 +389,7 @@ void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) } +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void BytecodePrinter::print_attributes(int bci, outputStream* st) { // Show attributes of pre-rewritten codes Bytecodes::Code code = Bytecodes::java_code(raw_code()); @@ -515,7 +516,10 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) { int idx = ll - lo; const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" : ", %d:" INT32_FORMAT " (delta: %d)"; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(format, ll, dest[idx], dest[idx]-bci); +PRAGMA_DIAG_POP } st->cr(); } @@ -535,7 +539,10 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) { for (int ll = 0; ll < len; ll++, first = false) { const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT : ", " INT32_FORMAT ":" INT32_FORMAT ; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(format, key[ll], dest[ll]); +PRAGMA_DIAG_POP } st->cr(); } diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp index 60246e9013d..7ce4bdbb3ec 100644 --- a/hotspot/src/share/vm/interpreter/interpreter.cpp +++ b/hotspot/src/share/vm/interpreter/interpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,7 @@ void InterpreterCodelet::print_on(outputStream* st) const { if (description() != NULL) st->print("%s ", description()); if (bytecode() >= 0 ) st->print("%d %s ", bytecode(), Bytecodes::name(bytecode())); st->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "] %d bytes", - code_begin(), code_end(), code_size()); + p2i(code_begin()), p2i(code_end()), code_size()); if (PrintInterpreter) { st->cr(); diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 0e1c129038d..0f79ab5072f 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,8 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class UnlockFlagSaver { private: JavaThread* _thread; @@ -1265,8 +1267,10 @@ IRT_END // This is a support of the JVMTI PopFrame interface. // Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument // and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters. -// The dmh argument is a reference to a DirectMethoHandle that has a member name field. -IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh, +// The member_name argument is a saved reference (in local#0) to the member_name. +// For backward compatibility with some JDK versions (7, 8) it can also be a direct method handle. +// FIXME: remove DMH case after j.l.i.InvokerBytecodeGenerator code shape is updated. +IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address member_name, Method* method, address bcp)) Bytecodes::Code code = Bytecodes::code_at(method, bcp); if (code != Bytecodes::_invokestatic) { @@ -1278,8 +1282,12 @@ IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, Symbol* mname = cpool->name_ref_at(cp_index); if (MethodHandles::has_member_arg(cname, mname)) { - oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh); - thread->set_vm_result(member_name); + oop member_name_oop = (oop) member_name; + if (java_lang_invoke_DirectMethodHandle::is_instance(member_name_oop)) { + // FIXME: remove after j.l.i.InvokerBytecodeGenerator code shape is updated. + member_name_oop = java_lang_invoke_DirectMethodHandle::member(member_name_oop); + } + thread->set_vm_result(member_name_oop); } IRT_END #endif // INCLUDE_JVMTI diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index a0f204c6eb2..d732cb2eec5 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -950,7 +950,6 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method // reflection implementation, not just those associated with // sun/reflect/SerializationConstructorAccessor. bool is_reflect = JDK_Version::is_gte_jdk14x_version() && - UseNewReflection && klass_to_check->is_subclass_of( SystemDictionary::reflect_MagicAccessorImpl_klass()); @@ -1626,7 +1625,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result, THREAD); if (HAS_PENDING_EXCEPTION) { if (TraceMethodHandles) { - tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION); + tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); PENDING_EXCEPTION->print(); } if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp index 34f3edc17f0..79e2bba8bad 100644 --- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp +++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "runtime/handles.inline.hpp" #include "runtime/signature.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class OopMapCacheEntry: private InterpreterOopMap { friend class InterpreterOopMap; friend class OopMapForCacheEntry; diff --git a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp index e3e89e8eed9..66eb63eafb6 100644 --- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,7 @@ void EntryPoint::print() { tty->print("["); for (int i = 0; i < number_of_states; i++) { if (i > 0) tty->print(", "); - tty->print(INTPTR_FORMAT, _entry[i]); + tty->print(INTPTR_FORMAT, p2i(_entry[i])); } tty->print("]"); } diff --git a/hotspot/src/share/vm/libadt/dict.cpp b/hotspot/src/share/vm/libadt/dict.cpp index 29c16bb41e0..bbed6795e65 100644 --- a/hotspot/src/share/vm/libadt/dict.cpp +++ b/hotspot/src/share/vm/libadt/dict.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,29 +24,19 @@ #include "precompiled.hpp" #include "libadt/dict.hpp" -#include "memory/allocation.inline.hpp" -#include "memory/resourceArea.hpp" -#include "runtime/thread.hpp" // Dictionaries - An Abstract Data Type // %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" -//IMPLEMENTATION -// #include "dict.hpp" - #include -// The iostream is not needed and it gets confused for gcc by the -// define of bool. -// -// #include +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC //------------------------------data----------------------------------------- // String hash tables #define MAXID 20 -static byte initflag = 0; // True after 1st initialization +static uint8_t initflag = 0; // True after 1st initialization static const char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6}; static short xsum[MAXID]; @@ -281,7 +271,7 @@ void *Dict::operator [](const void *key) const { // CmpDict compares two dictionaries; they must have the same keys (their // keys must match using CmpKey) and they must have the same values (pointer // comparison). If so 1 is returned, if not 0 is returned. -int32 Dict::operator ==(const Dict &d2) const { +int32_t Dict::operator ==(const Dict &d2) const { if( _cnt != d2._cnt ) return 0; if( _hash != d2._hash ) return 0; if( _cmp != d2._cmp ) return 0; @@ -318,7 +308,7 @@ void Dict::print() { // C text shows excellent spreading of values for any size hash table. int hashstr(const void *t) { register char c, k = 0; - register int32 sum = 0; + register int32_t sum = 0; register const char *s = (const char *)t; while( ((c = *s++) != '\0') && (k < MAXID-1) ) { // Get characters till null or MAXID-1 @@ -332,11 +322,7 @@ int hashstr(const void *t) { // Slimey cheap hash function; no guaranteed performance. Better than the // default for pointers, especially on MS-DOS machines. int hashptr(const void *key) { -#ifdef __TURBOC__ - return ((intptr_t)key >> 16); -#else // __TURBOC__ - return ((intptr_t)key >> 2); -#endif + return ((intptr_t)key >> 2); } // Slimey cheap hash function; no guaranteed performance. @@ -345,12 +331,12 @@ int hashkey(const void *key) { } //------------------------------Key Comparator Functions--------------------- -int32 cmpstr(const void *k1, const void *k2) { +int32_t cmpstr(const void *k1, const void *k2) { return strcmp((const char *)k1,(const char *)k2); } // Cheap key comparator. -int32 cmpkey(const void *key1, const void *key2) { +int32_t cmpkey(const void *key1, const void *key2) { if (key1 == key2) return 0; intptr_t delta = (intptr_t)key1 - (intptr_t)key2; if (delta > 0) return 1; diff --git a/hotspot/src/share/vm/libadt/dict.hpp b/hotspot/src/share/vm/libadt/dict.hpp index dad45832de7..e3098dcc66c 100644 --- a/hotspot/src/share/vm/libadt/dict.hpp +++ b/hotspot/src/share/vm/libadt/dict.hpp @@ -25,11 +25,12 @@ #ifndef SHARE_VM_LIBADT_DICT_HPP #define SHARE_VM_LIBADT_DICT_HPP -#include "libadt/port.hpp" - // Dictionaries - An Abstract Data Type -//INTERFACE -class ostream; + +#include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/thread.hpp" + class Dict; // These dictionaries define a key-value mapping. They can be inserted to, @@ -38,7 +39,7 @@ class Dict; // key comparison routine determines if two keys are equal or not. A hash // function can be provided; if it's not provided the key itself is used // instead. A nice string hash function is included. -typedef int32 (*CmpKey)(const void *key1, const void *key2); +typedef int32_t (*CmpKey)(const void *key1, const void *key2); typedef int (*Hash)(const void *key); typedef void (*FuncDict)(const void *key, const void *val, Dict *d); @@ -47,7 +48,7 @@ class Dict : public ResourceObj { // Dictionary structure class Arena *_arena; // Where to draw storage from class bucket *_bin; // Hash table is array of buckets uint _size; // Size (# of slots) in hash table - uint32 _cnt; // Number of key-value pairs in hash table + uint32_t _cnt; // Number of key-value pairs in hash table const Hash _hash; // Hashing function const CmpKey _cmp; // Key comparison function void doubhash( void ); // Double hash table size @@ -67,7 +68,7 @@ class Dict : public ResourceObj { // Dictionary structure void Clear(); // Return # of key-value pairs in dict - uint32 Size(void) const { return _cnt; } + uint32_t Size(void) const { return _cnt; } // Insert inserts the given key-value pair into the dictionary. The prior // value of the key is returned; NULL if the key was not previously defined. @@ -81,7 +82,7 @@ class Dict : public ResourceObj { // Dictionary structure // == compares two dictionaries; they must have the same keys (their keys // must match using CmpKey) and they must have the same values (pointer // comparison). If so 1 is returned, if not 0 is returned. - int32 operator ==(const Dict &d) const; // Compare dictionaries for equal + int32_t operator ==(const Dict &d) const; // Compare dictionaries for equal // Print out the dictionary contents as key-value pairs void print(); @@ -96,9 +97,9 @@ int hashptr(const void *key); int hashkey(const void *key); // Key comparators -int32 cmpstr(const void *k1, const void *k2); +int32_t cmpstr(const void *k1, const void *k2); // Slimey cheap key comparator. -int32 cmpkey(const void *key1, const void *key2); +int32_t cmpkey(const void *key1, const void *key2); //------------------------------Iteration-------------------------------------- // The class of dictionary iterators. Fails in the presences of modifications diff --git a/hotspot/src/share/vm/libadt/port.cpp b/hotspot/src/share/vm/libadt/port.cpp deleted file mode 100644 index 165b301846d..00000000000 --- a/hotspot/src/share/vm/libadt/port.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "libadt/port.hpp" - -// Code for portable compiling - -#ifdef __GNUC__ -#pragma implementation -#endif - -// %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" - -// This is only used if turboc is used and it causes problems with -// gcc. -#ifdef __TURBOC__ -#include -#endif - -#include - -//------------------------------gcd-------------------------------------------- -// Greatest common divisor -uint32 gcd( register uint32 x, register uint32 y ) -{ - register uint32 tmp; - while( x ) { // While not zero - tmp = x; // Hold onto smaller x value - x = y % x; // Compute modulus; since y>=x, 0 <= mod < x - y = tmp; // y = old x - } - return y; -} - -//----------------------------------------------------------------------------- -// Find first 1, or return 32 if empty -int ff1( uint32 mask ) -{ - unsigned i, n = 0; - - for( i=1, n=0; i; i<<=1, n++) - if( mask&i ) return n; - return 32; -} - -//----------------------------------------------------------------------------- -// Find highest 1, or return 32 if empty -int fh1( uint32 mask ) -{ - unsigned i, n = 0; - - for( i=((uint32)1<<31), n=31; i; i>>=1, n--) - if( mask&i ) return n; - return 32; -} - -//------------------------------rotate32--------------------------------------- -// Rotate 32bits. Postive rotates left (bits move toward high-order bit), -// negative rotates right. -uint32 rotate32( register uint32 x, register int32 cnt ) -{ - if( cnt >= 0 ) { // Positive rotates left - cnt &= 31; // Mask off extra shift bits - } else { // Negative rotates right - cnt = (-cnt)&31; // Flip sign; mask extra shift bits - cnt = 32-cnt; // Rotate right by big left rotation - } - return (x << cnt) | (x >> (32-cnt)); -} - -/* Disabled - we have another log2 in the system. - This function doesn't work if used as substitute - for the existing log2. Keep around until we have - verified all uses of log2 do the correct thing! -//------------------------------log2------------------------------------------- -// Log base 2. Might also be called 'count leading zeros'. Log2(x) returns -// an l such that (1L<= 0 ) // While high bit is clear - sx <<= 1, l--; // Shift bits left, count down log2 - return l; -} -*/ - -//------------------------------print------------------------------------------ -// Print a pointer without modifying the contents -#ifdef __TURBOC__ -ostream &ostream::operator << (const void *ptr) -{ - return (*this) << "0x" << hex << (uint)ptr << dec; -} -#else -/*ostream &operator << (ostream &os, const void *ptr) -{ - return os << "0x" << hex << (uint)ptr << dec; -}*/ -#endif diff --git a/hotspot/src/share/vm/libadt/port.hpp b/hotspot/src/share/vm/libadt/port.hpp deleted file mode 100644 index 358ab3021c1..00000000000 --- a/hotspot/src/share/vm/libadt/port.hpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_LIBADT_PORT_HPP -#define SHARE_VM_LIBADT_PORT_HPP - -#include "utilities/top.hpp" - -// Typedefs for portable compiling - -#if defined(__GNUC__) - -#define INTERFACE #pragma interface -#define IMPLEMENTATION #pragma implementation -//INTERFACE -#include -#include -#include - -// Access to the C++ class virtual function pointer -// Put the class in the macro -typedef void *VPTR; -// G++ puts it at the end of the base class -#define ACCESS_VPTR(class) VPTR&vptr(){return*(VPTR*)((char*)this+sizeof(class)-sizeof(void*));} - -#elif defined(__TURBOC__) - -#include -#include -extern "C" int stricmp(const char *, const char *); -inline void bcopy(const void *s, void *d, int l) { memmove(d,s,l); } -inline void bzero(void *p, int l) { memset(p,0,l); } -inline int bcmp(const void *s, const void *d, int l) { return memcmp(s,d,l); } -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } -//strcasecmp moved to globalDefinitions_visCPP.hpp -//inline int strcasecmp(const char *s1, const char *s2) { return stricmp(s1,s2); } -inline long abs( long x ) { return x < 0 ? -x : x; } -// Access to the C++ class virtual function pointer -// Put the class in the macro -typedef void near *VPTR; -// BorlandC puts it up front -#define ACCESS_VPTR(class) VPTR&vptr(){return*(VPTR*)this;} - -#elif defined(__hpux) - -#define INTERFACE -#define IMPLEMENTATION -#define signed -#include -#include -inline long min( long a, long b) { return a < b ? a : b; } -inline long max( long a, long b) { return a > b ? a : b; } -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } -inline long abs( long x ) { return x < 0 ? -x : x; } - -#elif defined(__MOTO__) -// Motorola's mcc -#define INTERFACE -#define IMPLEMENTATION -#include -#include -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } - -#elif defined(_AIX) -// IBM's xlC compiler -#define INTERFACE -#define IMPLEMENTATION -#include -#include - -#elif defined(_MSC_VER) -// Microsoft Visual C++ -//#define INTERFACE -#define IMPLEMENTATION -#include -#undef small -//strcasecmp moved to globalDefinitions_visCPP.hpp -//inline int strcasecmp(const char *s1, const char *s2) { return stricmp(s1,s2); } - - -#elif defined(SPARC_WORKS) - -#define INTERFACE -#define IMPLEMENTATION - -#include -#include -#include - -#elif defined(SOLARIS) - -#define INTERFACE -#define IMPLEMENTATION - -#include -#include -#include - - -#elif defined(__TANDEM) - -// This case is for the Tandem Business Unit of Compaq Computer Corporation. -// The Tandem case must precede the AT&T case, -// because the Tandem c89 compiler also defines __cplusplus. - -#include "port_tandem.hpp" - -#elif defined(__cplusplus) -// AT&Ts cfront -#define INTERFACE -#define IMPLEMENTATION -#include -#define signed -// #include -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } - -#else // All other machines - -#define signed -extern "C" void bcopy(void *b1, void *b2, int len); -inline int min( int a, int b) { return a < b ? a : b; } -inline int max( int a, int b) { return a > b ? a : b; } - -#endif - -//----------------------------------------------------------------------------- -// Safer memory allocations -#ifdef SAFE_MEMORY -#define malloc(size) safe_malloc(__FILE__,__LINE__,size) -#define free(ptr) safe_free(__FILE__,__LINE__,ptr) -#define realloc(ptr,size) safe_realloc(__FILE__,__LINE__,ptr,size) -#define calloc(nitems,size) safe_calloc(__FILE__,__LINE__,nitems,size) -#define strdup(ptr) safe_strdup(__FILE__,__LINE__,ptr) -extern void *safe_malloc (const char *file, unsigned line, unsigned size); -extern void safe_free (const char *file, unsigned line, void *ptr); -extern void *safe_calloc (const char *file, unsigned line, unsigned nitems, unsigned size); -extern void *safe_realloc(const char *file, unsigned line, void *ptr, unsigned size); -extern char *safe_strdup (const char *file, unsigned line, const char *src); -inline void *operator new( size_t size ) throw() { return malloc(size); } -inline void operator delete( void *ptr ) { free(ptr); } -#endif - -//----------------------------------------------------------------------------- -// And now, the bit-size-specified integer sizes -typedef signed char int8; -typedef unsigned char uint8; -typedef unsigned char byte; - -// All uses of *int16 changed to 32-bit to speed up compiler on Intel -//typedef signed short int16; // Exactly 16bits signed -//typedef unsigned short uint16; // Exactly 16bits unsigned -//const unsigned int min_uint16 = 0x0000; // smallest uint16 -//const unsigned int max_uint16 = 0xFFFF; // largest uint16 - -typedef unsigned int uint; // When you need a fast >=16bit unsigned value -/*typedef int int; */ // When you need a fast >=16bit value -const unsigned int max_uint = (uint)-1; -typedef int32_t int32; // Exactly 32bits signed -typedef uint32_t uint32; // Exactly 32bits unsigned - -// Bit-sized floating point and long thingies -#ifndef __TANDEM -// Do not define these for Tandem, because they conflict with typedefs in softieee.h. -typedef float float32; // 32-bit float -typedef double float64; // 64-bit float -#endif // __TANDEM - -typedef jlong int64; // Java long for my 64-bit type -typedef julong uint64; // Java long for my 64-bit type - -//----------------------------------------------------------------------------- -// Nice constants -uint32 gcd( uint32 x, uint32 y ); -int ff1( uint32 mask ); -int fh1( uint32 mask ); -uint32 rotate32( uint32 x, int32 cnt ); - - -//----------------------------------------------------------------------------- -extern uint32 heap_totalmem; // Current total memory allocation -extern uint32 heap_highwater; // Highwater mark to date for memory usage - -#endif // SHARE_VM_LIBADT_PORT_HPP diff --git a/hotspot/src/share/vm/libadt/set.cpp b/hotspot/src/share/vm/libadt/set.cpp index 7364795ed70..d2e1a68a03b 100644 --- a/hotspot/src/share/vm/libadt/set.cpp +++ b/hotspot/src/share/vm/libadt/set.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,20 +28,11 @@ // Sets - An Abstract Data Type -// %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" -//IMPLEMENTATION -// #include "set.hpp" - #include #include #include #include -// Not needed and it causes terouble for gcc. -// -// #include - //-------------------------Virtual Functions----------------------------------- // These functions MUST be implemented by the inheriting class. class SparseSet; @@ -116,7 +107,7 @@ char *Set::setstr() const void Set::print() const { char *printable_set = setstr(); - tty->print_cr(printable_set); + tty->print_cr("%s", printable_set); FreeHeap(printable_set); } diff --git a/hotspot/src/share/vm/libadt/set.hpp b/hotspot/src/share/vm/libadt/set.hpp index f3b3533eb87..3c66e561566 100644 --- a/hotspot/src/share/vm/libadt/set.hpp +++ b/hotspot/src/share/vm/libadt/set.hpp @@ -25,13 +25,10 @@ #ifndef SHARE_VM_LIBADT_SET_HPP #define SHARE_VM_LIBADT_SET_HPP -#include "libadt/port.hpp" #include "memory/allocation.hpp" // Sets - An Abstract Data Type -//INTERFACE - class SparseSet; class VectorSet; class ListSet; diff --git a/hotspot/src/share/vm/libadt/vectset.cpp b/hotspot/src/share/vm/libadt/vectset.cpp index ab80afef681..256b0a9a1a9 100644 --- a/hotspot/src/share/vm/libadt/vectset.cpp +++ b/hotspot/src/share/vm/libadt/vectset.cpp @@ -28,15 +28,10 @@ // Vector Sets - An Abstract Data Type -// %%%%% includes not needed with AVM framework - Ungar -// #include "port.hpp" -//IMPLEMENTATION -// #include "vectset.hpp" - // BitsInByte is a lookup table which tells the number of bits that // are in the looked-up number. It is very useful in VectorSet_Size. -uint8 bitsInByte[256] = { +uint8_t bitsInByte[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, @@ -59,7 +54,7 @@ uint8 bitsInByte[256] = { // Create a new, empty Set. VectorSet::VectorSet(Arena *arena) : Set(arena) { size = 2; // Small initial size - data = (uint32 *)_set_arena->Amalloc(size*sizeof(uint32)); + data = (uint32_t *)_set_arena->Amalloc(size*sizeof(uint32_t)); data[0] = 0; // No elements data[1] = 0; } @@ -85,8 +80,8 @@ Set &VectorSet::operator = (const Set &set) void VectorSet::slamin(const VectorSet& s) { size = s.size; // Use new size - data = (uint32*)s._set_arena->Amalloc(size*sizeof(uint32)); // Make array of required size - memcpy( data, s.data, size*sizeof(uint32) ); // Fill the array + data = (uint32_t*)s._set_arena->Amalloc(size*sizeof(uint32_t)); // Make array of required size + memcpy( data, s.data, size*sizeof(uint32_t) ); // Fill the array } //------------------------------grow------------------------------------------- @@ -96,8 +91,8 @@ void VectorSet::grow( uint newsize ) newsize = (newsize+31) >> 5; // Convert to longwords uint x = size; while( x < newsize ) x <<= 1; - data = (uint32 *)_set_arena->Arealloc(data, size*sizeof(uint32), x*sizeof(uint32)); - memset((char *)(data + size), 0, (x - size)*sizeof(uint32)); + data = (uint32_t *)_set_arena->Arealloc(data, size*sizeof(uint32_t), x*sizeof(uint32_t)); + memset((char *)(data + size), 0, (x - size)*sizeof(uint32_t)); size = x; } @@ -106,7 +101,7 @@ void VectorSet::grow( uint newsize ) Set &VectorSet::operator <<= (uint elem) { register uint word = elem >> 5; // Get the longword offset - register uint32 mask = 1L << (elem & 31); // Get bit mask + register uint32_t mask = 1L << (elem & 31); // Get bit mask if( word >= size ) // Need to grow set? grow(elem+1); // Then grow it @@ -121,7 +116,7 @@ Set &VectorSet::operator >>= (uint elem) register uint word = elem >> 5; // Get the longword offset if( word >= size ) // Beyond the last? return *this; // Then it's clear & return clear - register uint32 mask = 1L << (elem & 31); // Get bit mask + register uint32_t mask = 1L << (elem & 31); // Get bit mask data[word] &= ~mask; // Clear bit return *this; } @@ -132,8 +127,8 @@ VectorSet &VectorSet::operator &= (const VectorSet &s) { // NOTE: The intersection is never any larger than the smallest set. if( s.size < size ) size = s.size; // Get smaller size - register uint32 *u1 = data; // Pointer to the destination data - register uint32 *u2 = s.data; // Pointer to the source data + register uint32_t *u1 = data; // Pointer to the destination data + register uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i> 5; // Get the longword offset if( word >= size ) // Beyond the last? return 0; // Then it's clear - register uint32 mask = 1L << (elem & 31); // Get bit mask + register uint32_t mask = 1L << (elem & 31); // Get bit mask return ((data[word] & mask))!=0; // Return the sense of the bit } @@ -305,7 +300,7 @@ uint VectorSet::getelem(void) const for( i=0; i>=1 ); return (i<<5)+j; @@ -316,11 +311,11 @@ uint VectorSet::getelem(void) const void VectorSet::Clear(void) { if( size > 100 ) { // Reclaim storage only if huge - FREE_RESOURCE_ARRAY(uint32,data,size); + FREE_RESOURCE_ARRAY(uint32_t,data,size); size = 2; // Small initial size - data = NEW_RESOURCE_ARRAY(uint32,size); + data = NEW_RESOURCE_ARRAY(uint32_t,size); } - memset( data, 0, size*sizeof(uint32) ); + memset( data, 0, size*sizeof(uint32_t) ); } //------------------------------Size------------------------------------------- @@ -328,8 +323,8 @@ void VectorSet::Clear(void) uint VectorSet::Size(void) const { uint sum = 0; // Cumulative size so far. - uint8 *currByte = (uint8*)data; - for( uint32 i = 0; i < (size<<2); i++) // While have bytes to process + uint8_t* currByte = (uint8_t*) data; + for( uint32_t i = 0; i < (size<<2); i++) // While have bytes to process sum += bitsInByte[*currByte++]; // Add bits in current byte to size. return sum; } @@ -343,7 +338,7 @@ void VectorSet::Sort(void) //------------------------------hash------------------------------------------- int VectorSet::hash() const { - uint32 _xor = 0; + uint32_t _xor = 0; uint lim = ((size<4)?size:4); for( uint i = 0; i < lim; i++ ) _xor ^= data[i]; diff --git a/hotspot/src/share/vm/libadt/vectset.hpp b/hotspot/src/share/vm/libadt/vectset.hpp index 552fdd17bee..d94ce44d35f 100644 --- a/hotspot/src/share/vm/libadt/vectset.hpp +++ b/hotspot/src/share/vm/libadt/vectset.hpp @@ -47,7 +47,7 @@ class VectorSet : public Set { friend class VectorSetI; // Friendly iterator class protected: uint size; // Size of data IN LONGWORDS (32bits) - uint32 *data; // The data, bit packed + uint32_t* data; // The data, bit packed void slamin( const VectorSet& s ); // Initialize one set with another int compare(const VectorSet &s) const; // Compare set contents @@ -99,7 +99,7 @@ public: void Sort(void); // Sort before iterating int hash() const; // Hash function void Reset(void) { // Reset a set - memset( data, 0, size*sizeof(uint32) ); + memset( data, 0, size*sizeof(uint32_t) ); } /* Removed for MCC BUG @@ -108,7 +108,7 @@ public: // Expose internals for speed-critical fast iterators uint word_size() const { return size; } - uint32 *EXPOSE() const { return data; } + uint32_t* EXPOSE() const { return data; } // Fast inlined "test and set". Replaces the idiom: // if( visited[idx] ) return; @@ -120,8 +120,8 @@ public: uint word = elem >> 5; // Get the longword offset if( word >= size ) // Beyond the last? return test_set_grow(elem); // Then grow; set; return 0; - uint32 mask = 1L << (elem & 31); // Get bit mask - uint32 datum = data[word] & mask;// Get bit + uint32_t mask = 1L << (elem & 31); // Get bit mask + uint32_t datum = data[word] & mask;// Get bit data[word] |= mask; // Set bit return datum; // Return bit } @@ -134,7 +134,7 @@ public: int test( uint elem ) const { uint word = elem >> 5; // Get the longword offset if( word >= size ) return 0; // Beyond the last? - uint32 mask = 1L << (elem & 31); // Get bit mask + uint32_t mask = 1L << (elem & 31); // Get bit mask return data[word] & mask; // Get bit } @@ -144,7 +144,7 @@ public: if( word >= size ) { // Beyond the last? test_set_grow(elem); // Then grow and set } else { - uint32 mask = 1L << (elem & 31); // Get bit mask + uint32_t mask = 1L << (elem & 31); // Get bit mask data[word] |= mask; // Set bit } } @@ -164,7 +164,7 @@ class VectorSetI : public StackObj { friend class VectorSet; const VectorSet *s; uint i, j; - uint32 mask; + uint32_t mask; uint next(void); public: diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index 9fece9b4ef4..2a3f4135617 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,11 +75,11 @@ bool MetaspaceObj::is_shared() const { } bool MetaspaceObj::is_metaspace_object() const { - return ClassLoaderDataGraph::contains((void*)this); + return Metaspace::contains((void*)this); } void MetaspaceObj::print_address_on(outputStream* st) const { - st->print(" {"INTPTR_FORMAT"}", this); + st->print(" {" INTPTR_FORMAT "}", p2i(this)); } void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) throw() { @@ -142,7 +142,7 @@ void ResourceObj::operator delete [](void* p) { void ResourceObj::set_allocation_type(address res, allocation_type type) { // Set allocation type in the resource object uintptr_t allocation = (uintptr_t)res; - assert((allocation & allocation_mask) == 0, err_msg("address should be aligned to 4 bytes at least: " PTR_FORMAT, res)); + assert((allocation & allocation_mask) == 0, err_msg("address should be aligned to 4 bytes at least: " INTPTR_FORMAT, p2i(res))); assert(type <= allocation_mask, "incorrect allocation type"); ResourceObj* resobj = (ResourceObj *)res; resobj->_allocation_t[0] = ~(allocation + type); @@ -179,7 +179,7 @@ ResourceObj::ResourceObj() { // default constructor // Operator new() was called and type was set. assert(!allocated_on_stack(), err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); + p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); } else { // Operator new() was not called. // Assume that it is embedded or stack object. @@ -193,7 +193,7 @@ ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor // Note: garbage may resembles valid value. assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); + p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); set_allocation_type((address)this, STACK_OR_EMBEDDED); _allocation_t[1] = 0; // Zap verification value } @@ -202,7 +202,7 @@ ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assi // Used in InlineTree::ok_to_inline() for WarmCallInfo. assert(allocated_on_stack(), err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); + p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1])); // Keep current _allocation_t value; return *this; } @@ -218,13 +218,13 @@ ResourceObj::~ResourceObj() { void trace_heap_malloc(size_t size, const char* name, void* p) { // A lock is not needed here - tty uses a lock internally - tty->print_cr("Heap malloc " INTPTR_FORMAT " " SIZE_FORMAT " %s", p, size, name == NULL ? "" : name); + tty->print_cr("Heap malloc " INTPTR_FORMAT " " SIZE_FORMAT " %s", p2i(p), size, name == NULL ? "" : name); } void trace_heap_free(void* p) { // A lock is not needed here - tty uses a lock internally - tty->print_cr("Heap free " INTPTR_FORMAT, p); + tty->print_cr("Heap free " INTPTR_FORMAT, p2i(p)); } //-------------------------------------------------------------------------------------- @@ -686,50 +686,67 @@ void* Arena::internal_malloc_4(size_t x) { // a memory leak. Use CHeapObj as the base class of such objects to make it explicit // that they're allocated on the C heap. // Commented out in product version to avoid conflicts with third-party C++ native code. -// On certain platforms, such as Mac OS X (Darwin), in debug version, new is being called -// from jdk source and causing data corruption. Such as -// Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair -// define ALLOW_OPERATOR_NEW_USAGE for platform on which global operator new allowed. // -#ifndef ALLOW_OPERATOR_NEW_USAGE -void* operator new(size_t size) throw() { - assert(false, "Should not call global operator new"); +// In C++98/03 the throwing new operators are defined with the following signature: +// +// void* operator new(std::size_tsize) throw(std::bad_alloc); +// void* operator new[](std::size_tsize) throw(std::bad_alloc); +// +// while all the other (non-throwing) new and delete operators are defined with an empty +// throw clause (i.e. "operator delete(void* p) throw()") which means that they do not +// throw any exceptions (see section 18.4 of the C++ standard). +// +// In the new C++11/14 standard, the signature of the throwing new operators was changed +// by completely omitting the throw clause (which effectively means they could throw any +// exception) while all the other new/delete operators where changed to have a 'nothrow' +// clause instead of an empty throw clause. +// +// Unfortunately, the support for exception specifications among C++ compilers is still +// very fragile. While some more strict compilers like AIX xlC or HP aCC reject to +// override the default throwing new operator with a user operator with an empty throw() +// clause, the MS Visual C++ compiler warns for every non-empty throw clause like +// throw(std::bad_alloc) that it will ignore the exception specification. The following +// operator definitions have been checked to correctly work with all currently supported +// compilers and they should be upwards compatible with C++11/14. Therefore +// PLEASE BE CAREFUL if you change the signature of the following operators! + +void* operator new(size_t size) /* throw(std::bad_alloc) */ { + fatal("Should not call global operator new"); return 0; } -void* operator new [](size_t size) throw() { - assert(false, "Should not call global operator new[]"); +void* operator new [](size_t size) /* throw(std::bad_alloc) */ { + fatal("Should not call global operator new[]"); return 0; } void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { - assert(false, "Should not call global operator new"); + fatal("Should not call global operator new"); return 0; } void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() { - assert(false, "Should not call global operator new[]"); + fatal("Should not call global operator new[]"); return 0; } -void operator delete(void* p) { - assert(false, "Should not call global delete"); +void operator delete(void* p) throw() { + fatal("Should not call global delete"); } -void operator delete [](void* p) { - assert(false, "Should not call global delete []"); +void operator delete [](void* p) throw() { + fatal("Should not call global delete []"); } -#endif // ALLOW_OPERATOR_NEW_USAGE void AllocatedObj::print() const { print_on(tty); } void AllocatedObj::print_value() const { print_value_on(tty); } void AllocatedObj::print_on(outputStream* st) const { - st->print_cr("AllocatedObj(" INTPTR_FORMAT ")", this); + st->print_cr("AllocatedObj(" INTPTR_FORMAT ")", p2i(this)); } void AllocatedObj::print_value_on(outputStream* st) const { - st->print("AllocatedObj(" INTPTR_FORMAT ")", this); + st->print("AllocatedObj(" INTPTR_FORMAT ")", p2i(this)); } julong Arena::_bytes_allocated = 0; diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index ac716bb01e2..60435e63c1d 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -1318,7 +1318,7 @@ class PrintFreeListsClosure : public AscendTreeCensusClosurehead(); fc != NULL; fc = fc->next()) { _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", - fc, (HeapWord*)fc + sz, + p2i(fc), p2i((HeapWord*)fc + sz), fc->cantCoalesce() ? "\t CC" : ""); } } diff --git a/hotspot/src/share/vm/memory/blockOffsetTable.cpp b/hotspot/src/share/vm/memory/blockOffsetTable.cpp index 7a54e147790..d64aff67dd7 100644 --- a/hotspot/src/share/vm/memory/blockOffsetTable.cpp +++ b/hotspot/src/share/vm/memory/blockOffsetTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,12 +59,12 @@ BlockOffsetSharedArray::BlockOffsetSharedArray(MemRegion reserved, " rs.base(): " INTPTR_FORMAT " rs.size(): " INTPTR_FORMAT " rs end(): " INTPTR_FORMAT, - rs.base(), rs.size(), rs.base() + rs.size()); + p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size())); gclog_or_tty->print_cr(" " " _vs.low_boundary(): " INTPTR_FORMAT " _vs.high_boundary(): " INTPTR_FORMAT, - _vs.low_boundary(), - _vs.high_boundary()); + p2i(_vs.low_boundary()), + p2i(_vs.high_boundary())); } } @@ -537,10 +537,10 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( q -= (N_words * n_cards_back); assert(q >= _sp->bottom(), err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT, - q, _sp->bottom())); + p2i(q), p2i(_sp->bottom()))); assert(q < _sp->end(), err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT, - q, _sp->end())); + p2i(q), p2i(_sp->end()))); index -= n_cards_back; offset = _array->offset_array(index); } @@ -549,10 +549,10 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( q -= offset; assert(q >= _sp->bottom(), err_msg("q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT, - q, _sp->bottom())); + p2i(q), p2i(_sp->bottom()))); assert(q < _sp->end(), err_msg("q = " PTR_FORMAT " crossed above end = " PTR_FORMAT, - q, _sp->end())); + p2i(q), p2i(_sp->end()))); HeapWord* n = q; while (n <= addr) { @@ -563,14 +563,14 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT"," " while querying blk_start(" PTR_FORMAT ")" " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")", - n, last, addr, _sp->bottom(), _sp->end())); + p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end()))); } assert(q <= addr, err_msg("wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")", - q, addr)); + p2i(q), p2i(addr))); assert(addr <= n, err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", - addr, n)); + p2i(addr), p2i(n))); return q; } diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index 4b54a404457..f5ff6aad2c1 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,11 +138,11 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, gclog_or_tty->print_cr(" " " &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT, - &_byte_map[0], - &_byte_map[_last_valid_index]); + p2i(&_byte_map[0]), + p2i(&_byte_map[_last_valid_index])); gclog_or_tty->print_cr(" " " byte_map_base: " INTPTR_FORMAT, - byte_map_base); + p2i(byte_map_base)); } } @@ -392,23 +392,23 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { gclog_or_tty->print_cr(" " " _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT, - ind, _covered[ind].start(), - ind, _covered[ind].last()); + ind, p2i(_covered[ind].start()), + ind, p2i(_covered[ind].last())); gclog_or_tty->print_cr(" " " _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT, - ind, _committed[ind].start(), - ind, _committed[ind].last()); + ind, p2i(_committed[ind].start()), + ind, p2i(_committed[ind].last())); gclog_or_tty->print_cr(" " " byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT, - byte_for(_covered[ind].start()), - byte_for(_covered[ind].last())); + p2i(byte_for(_covered[ind].start())), + p2i(byte_for(_covered[ind].last()))); gclog_or_tty->print_cr(" " " addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT, - addr_for((jbyte*) _committed[ind].start()), - addr_for((jbyte*) _committed[ind].last())); + p2i(addr_for((jbyte*) _committed[ind].start())), + p2i(addr_for((jbyte*) _committed[ind].last()))); } // Touch the last card of the covered region to show that it // is committed (or SEGV). @@ -657,14 +657,14 @@ void CardTableModRefBS::verify_region(MemRegion mr, if (failed) { if (!failures) { tty->cr(); - tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]", start, end); + tty->print_cr("== CT verification failed: [" INTPTR_FORMAT "," INTPTR_FORMAT "]", p2i(start), p2i(end)); tty->print_cr("== %sexpecting value: %d", (val_equals) ? "" : "not ", val); failures = true; } tty->print_cr("== card "PTR_FORMAT" ["PTR_FORMAT","PTR_FORMAT"], " - "val: %d", curr, addr_for(curr), - (HeapWord*) (((size_t) addr_for(curr)) + card_size), + "val: %d", p2i(curr), p2i(addr_for(curr)), + p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)), (int) curr_val); } } @@ -682,7 +682,7 @@ void CardTableModRefBS::verify_dirty_region(MemRegion mr) { void CardTableModRefBS::print_on(outputStream* st) const { st->print_cr("Card table byte_map: [" INTPTR_FORMAT "," INTPTR_FORMAT "] byte_map_base: " INTPTR_FORMAT, - _byte_map, _byte_map + _byte_map_size, byte_map_base); + p2i(_byte_map), p2i(_byte_map + _byte_map_size), p2i(byte_map_base)); } bool CardTableModRefBSForCTRS::card_will_be_scanned(jbyte cv) { diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp index 1aa5b41ab14..5e72b4640f9 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,7 +155,7 @@ class CardTableModRefBS: public ModRefBarrierSet { assert(_whole_heap.contains(p), err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of " " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", - p, _whole_heap.start(), _whole_heap.end())); + p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()))); jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift]; assert(result >= _byte_map && result < _byte_map + _byte_map_size, "out of bounds accessor for card marking array"); @@ -431,7 +431,7 @@ public: assert(_whole_heap.contains(result), err_msg("Returning result = "PTR_FORMAT" out of bounds of " " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", - result, _whole_heap.start(), _whole_heap.end())); + p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()))); return result; } @@ -440,7 +440,7 @@ public: assert(_whole_heap.contains(p), err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of " " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", - p, _whole_heap.start(), _whole_heap.end())); + p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()))); return byte_for(p) - _byte_map; } diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index d79b4b92ec8..56af890a421 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -288,14 +288,14 @@ void CardTableRS::younger_refs_in_space_iterate(Space* sp, err_msg("Did you forget to call save_marks()? " "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in " "[" PTR_FORMAT ", " PTR_FORMAT ")", - urasm.start(), urasm.end(), ur.start(), ur.end())); + p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()))); // In the case of CMS+ParNew, issue a warning if (!ur.contains(urasm)) { assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above"); warning("CMS+ParNew: Did you forget to call save_marks()? " "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in " "[" PTR_FORMAT ", " PTR_FORMAT ")", - urasm.start(), urasm.end(), ur.start(), ur.end()); + p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end())); MemRegion ur2 = sp->used_region(); MemRegion urasm2 = sp->used_region_at_save_marks(); if (!ur.equals(ur2)) { @@ -349,12 +349,12 @@ protected: assert(jp >= _begin && jp < _end, err_msg("Error: jp " PTR_FORMAT " should be within " "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")", - jp, _begin, _end)); + p2i(jp), p2i(_begin), p2i(_end))); oop obj = oopDesc::load_decode_heap_oop(p); guarantee(obj == NULL || (HeapWord*)obj >= _boundary, err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on " "clean card crosses boundary" PTR_FORMAT, - (HeapWord*)obj, jp, _boundary)); + p2i((HeapWord*)obj), p2i(jp), p2i(_boundary))); } public: @@ -362,10 +362,10 @@ public: _boundary(b), _begin(begin), _end(end) { assert(b <= begin, err_msg("Error: boundary " PTR_FORMAT " should be at or below begin " PTR_FORMAT, - b, begin)); + p2i(b), p2i(begin))); assert(begin <= end, err_msg("Error: begin " PTR_FORMAT " should be strictly below end " PTR_FORMAT, - begin, end)); + p2i(begin), p2i(end))); } virtual void do_oop(oop* p) { VerifyCleanCardClosure::do_oop_work(p); } diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 69d39e4d431..6d822a4b9e9 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -736,7 +736,7 @@ HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, if ((QueuedAllocationWarningCount > 0) && (try_count % QueuedAllocationWarningCount == 0)) { warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t" - " size=%d %s", try_count, size, is_tlab ? "(TLAB)" : ""); + " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : ""); } } } @@ -903,7 +903,7 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation( if ((QueuedAllocationWarningCount > 0) && (loop_count % QueuedAllocationWarningCount == 0)) { warning("satisfy_failed_metadata_allocation() retries %d times \n\t" - " size=%d", loop_count, word_size); + " size=" SIZE_FORMAT, loop_count, word_size); } } while (true); // Until a GC is done } diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index 000be1f8bf3..bf51090df12 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,11 +42,14 @@ #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/stack.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // // DefNewGeneration functions. diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 1420c279036..47527f21e9f 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ #define O_BINARY 0 // otherwise do nothing. #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC extern address JVM_FunctionAtStart(); extern address JVM_FunctionAtEnd(); diff --git a/hotspot/src/share/vm/memory/gcLocker.cpp b/hotspot/src/share/vm/memory/gcLocker.cpp index fc267ad84f1..96742637939 100644 --- a/hotspot/src/share/vm/memory/gcLocker.cpp +++ b/hotspot/src/share/vm/memory/gcLocker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ void GC_locker::verify_critical_count() { tty->print_cr("critical counts don't match: %d != %d", _jni_lock_count, count); for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { if (thr->in_critical()) { - tty->print_cr(INTPTR_FORMAT " in_critical %d", thr, thr->in_critical()); + tty->print_cr(INTPTR_FORMAT " in_critical %d", p2i(thr), thr->in_critical()); } } } diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index f3b2a8ec885..0f75d779d2a 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -794,7 +794,7 @@ void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, bool GenCollectedHeap::is_in_young(oop p) { bool result = ((HeapWord*)p) < _gens[_n_gens - 1]->reserved().start(); assert(result == _gens[0]->is_in_reserved(p), - err_msg("incorrect test - result=%d, p=" PTR_FORMAT, result, (void*)p)); + err_msg("incorrect test - result=%d, p=" INTPTR_FORMAT, result, p2i((void*)p))); return result; } @@ -1067,7 +1067,7 @@ void GenCollectedHeap::verify(bool silent, VerifyOption option /* ignored */) { for (int i = _n_gens-1; i >= 0; i--) { Generation* g = _gens[i]; if (!silent) { - gclog_or_tty->print(g->name()); + gclog_or_tty->print("%s", g->name()); gclog_or_tty->print(" "); } g->verify(); @@ -1270,7 +1270,7 @@ jlong GenCollectedHeap::millis_since_last_gc() { // back a time later than 'now'. jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);) + NOT_PRODUCT(warning("time warp: "INT64_FORMAT, (int64_t) retVal);) return 0; } return retVal; diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index 80a35d10e2c..64d7c3eaa61 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" diff --git a/hotspot/src/share/vm/memory/genOopClosures.hpp b/hotspot/src/share/vm/memory/genOopClosures.hpp index 1f24b2b3cab..977fcb34cf4 100644 --- a/hotspot/src/share/vm/memory/genOopClosures.hpp +++ b/hotspot/src/share/vm/memory/genOopClosures.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -193,7 +193,7 @@ class VerifyOopClosure: public OopClosure { protected: template inline void do_oop_work(T* p) { oop obj = oopDesc::load_decode_heap_oop(p); - guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj)); + guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj))); } public: virtual void do_oop(oop* p); diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp index 5d3ad791473..0c121503a17 100644 --- a/hotspot/src/share/vm/memory/generation.cpp +++ b/hotspot/src/share/vm/memory/generation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + Generation::Generation(ReservedSpace rs, size_t initial_size, int level) : _level(level), _ref_processor(NULL) { diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp index f44f0245c36..de60d23f197 100644 --- a/hotspot/src/share/vm/memory/generation.hpp +++ b/hotspot/src/share/vm/memory/generation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -422,7 +422,7 @@ class Generation: public CHeapObj { // have to guard against non-monotonicity. NOT_PRODUCT( if (now < _time_of_last_gc) { - warning("time warp: "INT64_FORMAT" to "INT64_FORMAT, _time_of_last_gc, now); + warning("time warp: "INT64_FORMAT" to "INT64_FORMAT, (int64_t)_time_of_last_gc, (int64_t)now); } ) return _time_of_last_gc; diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp index bf65c882cd6..7a4c6fc8752 100644 --- a/hotspot/src/share/vm/memory/heapInspection.cpp +++ b/hotspot/src/share/vm/memory/heapInspection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // HeapInspection int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) { @@ -270,6 +272,7 @@ bool KlassInfoHisto::is_selected(const char *col_name) { return true; } +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void KlassInfoHisto::print_title(outputStream* st, bool csv_format, bool selected[], int width_table[], const char *name_table[]) { @@ -282,7 +285,10 @@ void KlassInfoHisto::print_title(outputStream* st, bool csv_format, } else { st->print("Index Super"); for (int c=0; cprint(str_fmt(width_table[c]), name_table[c]);} +PRAGMA_DIAG_POP } st->print(" ClassName"); } @@ -395,12 +401,18 @@ void KlassInfoHisto::print_class_stats(outputStream* st, case KlassSizeStats::_index_inst_size: case KlassSizeStats::_index_inst_count: case KlassSizeStats::_index_method_count: +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(str_fmt(width_table[c]), "-"); +PRAGMA_DIAG_POP break; default: { double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(perc_fmt(width_table[c]), perc); +PRAGMA_DIAG_POP } } } diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp index 8cdd4ccdf65..b305f08fdb3 100644 --- a/hotspot/src/share/vm/memory/heapInspection.hpp +++ b/hotspot/src/share/vm/memory/heapInspection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -295,6 +295,9 @@ class KlassInfoHisto : public StackObj { // returns a format string to print a julong with the given width. E.g, // printf(num_fmt(6), julong(10)) would print out the number 10 with 4 // leading spaces. +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED + static void print_julong(outputStream* st, int width, julong n) { int num_spaces = width - julong_width(n); if (num_spaces > 0) { @@ -302,6 +305,7 @@ class KlassInfoHisto : public StackObj { } st->print(JULONG_FORMAT, n); } +PRAGMA_DIAG_POP static char* perc_fmt(int width) { static char buf[32]; diff --git a/hotspot/src/share/vm/memory/metachunk.cpp b/hotspot/src/share/vm/memory/metachunk.cpp index 81a1f8f8224..6cb6625b186 100644 --- a/hotspot/src/share/vm/memory/metachunk.cpp +++ b/hotspot/src/share/vm/memory/metachunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "utilities/copy.hpp" #include "utilities/debug.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + class VirtualSpaceNode; const size_t metadata_chunk_initialize = 0xf7f7f7f7; diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 0ace09a0735..cd5fceff2d0 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,8 @@ #include "utilities/copy.hpp" #include "utilities/debug.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + typedef BinaryTreeDictionary > BlockTreeDictionary; typedef BinaryTreeDictionary > ChunkTreeDictionary; @@ -314,6 +316,8 @@ class VirtualSpaceNode : public CHeapObj { MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } + bool contains(const void* ptr) { return ptr >= low() && ptr < high(); } + size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; } size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; } @@ -555,6 +559,8 @@ class VirtualSpaceList : public CHeapObj { void inc_virtual_space_count(); void dec_virtual_space_count(); + bool contains(const void* ptr); + // Unlink empty VirtualSpaceNodes and free it. void purge(ChunkManager* chunk_manager); @@ -639,8 +645,6 @@ class SpaceManager : public CHeapObj { // Accessors Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } void set_chunks_in_use(ChunkIndex index, Metachunk* v) { - // ensure lock-free iteration sees fully initialized node - OrderAccess::storestore(); _chunks_in_use[index] = v; } @@ -755,8 +759,6 @@ class SpaceManager : public CHeapObj { void print_on(outputStream* st) const; void locked_print_chunks_in_use_on(outputStream* st) const; - bool contains(const void *ptr); - void verify(); void verify_chunk_size(Metachunk* chunk); NOT_PRODUCT(void mangle_freed_chunks();) @@ -1076,6 +1078,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) { // nodes with a 0 container_count. Remove Metachunks in // the node from their respective freelists. void VirtualSpaceList::purge(ChunkManager* chunk_manager) { + assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work"); assert_lock_strong(SpaceManager::expand_lock()); // Don't use a VirtualSpaceListIterator because this // list is being changed and a straightforward use of an iterator is not safe. @@ -1109,8 +1112,8 @@ void VirtualSpaceList::purge(ChunkManager* chunk_manager) { } #ifdef ASSERT if (purged_vsl != NULL) { - // List should be stable enough to use an iterator here. - VirtualSpaceListIterator iter(virtual_space_list()); + // List should be stable enough to use an iterator here. + VirtualSpaceListIterator iter(virtual_space_list()); while (iter.repeat()) { VirtualSpaceNode* vsl = iter.get_next(); assert(vsl != purged_vsl, "Purge of vsl failed"); @@ -1119,6 +1122,23 @@ void VirtualSpaceList::purge(ChunkManager* chunk_manager) { #endif } + +// This function looks at the mmap regions in the metaspace without locking. +// The chunks are added with store ordering and not deleted except for at +// unloading time during a safepoint. +bool VirtualSpaceList::contains(const void* ptr) { + // List should be stable enough to use an iterator here because removing virtual + // space nodes is only allowed at a safepoint. + VirtualSpaceListIterator iter(virtual_space_list()); + while (iter.repeat()) { + VirtualSpaceNode* vsn = iter.get_next(); + if (vsn->contains(ptr)) { + return true; + } + } + return false; +} + void VirtualSpaceList::retire_current_virtual_space() { assert_lock_strong(SpaceManager::expand_lock()); @@ -1208,6 +1228,8 @@ bool VirtualSpaceList::create_new_virtual_space(size_t vs_word_size) { } else { assert(new_entry->reserved_words() == vs_word_size, "Reserved memory size differs from requested memory size"); + // ensure lock-free iteration sees fully initialized node + OrderAccess::storestore(); link_vs(new_entry); return true; } @@ -1961,7 +1983,7 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { st->print_cr(" free " SIZE_FORMAT, chunk->free_word_size()); } else { - st->print_cr(""); + st->cr(); } } @@ -2245,7 +2267,7 @@ SpaceManager::~SpaceManager() { humongous_chunks = next_humongous_chunks; } if (TraceMetadataChunkAllocation && Verbose) { - gclog_or_tty->print_cr(""); + gclog_or_tty->cr(); gclog_or_tty->print_cr("updated dictionary count %d %s", chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex)); @@ -2432,21 +2454,6 @@ MetaWord* SpaceManager::allocate_work(size_t word_size) { return result; } -// This function looks at the chunks in the metaspace without locking. -// The chunks are added with store ordering and not deleted except for at -// unloading time. -bool SpaceManager::contains(const void *ptr) { - for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) - { - Metachunk* curr = chunks_in_use(i); - while (curr != NULL) { - if (curr->contains(ptr)) return true; - curr = curr->next(); - } - } - return false; -} - void SpaceManager::verify() { // If there are blocks in the dictionary, then // verification of chunks does not work since @@ -3088,7 +3095,7 @@ void Metaspace::ergo_initialize() { void Metaspace::global_initialize() { // Initialize the alignment for shared spaces. - int max_alignment = os::vm_page_size(); + int max_alignment = os::vm_allocation_granularity(); size_t cds_total = 0; MetaspaceShared::set_max_alignment(max_alignment); @@ -3536,11 +3543,15 @@ void Metaspace::print_on(outputStream* out) const { } bool Metaspace::contains(const void* ptr) { - if (vsm()->contains(ptr)) return true; - if (using_class_space()) { - return class_vsm()->contains(ptr); + if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(ptr)) { + return true; } - return false; + + if (using_class_space() && get_space_list(ClassType)->contains(ptr)) { + return true; + } + + return get_space_list(NonClassType)->contains(ptr); } void Metaspace::verify() { @@ -3785,5 +3796,4 @@ void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } - #endif diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 1beddef8e6b..22e21b80d3d 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,7 +232,8 @@ class Metaspace : public CHeapObj { MetaWord* expand_and_allocate(size_t size, MetadataType mdtype); - bool contains(const void* ptr); + static bool contains(const void* ptr); + void dump(outputStream* const out) const; // Free empty virtualspaces diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index ef4572824f7..fc303f050a8 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ #include "runtime/vmThread.hpp" #include "utilities/hashtable.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC int MetaspaceShared::_max_alignment = 0; @@ -337,13 +338,14 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all int all_rw_count = 0; int all_rw_bytes = 0; - const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f"; +// To make fmt_stats be a syntactic constant (for format warnings), use #define. +#define fmt_stats "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f" const char *sep = "--------------------+---------------------------+---------------------------+--------------------------"; const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %"; tty->print_cr("Detailed metadata info (rw includes md and mc):"); - tty->print_cr(hdr); - tty->print_cr(sep); + tty->print_cr("%s", hdr); + tty->print_cr("%s", sep); for (int type = 0; type < int(_number_of_types); type ++) { const char *name = type_name((Type)type); int ro_count = _counts[RO][type]; @@ -357,7 +359,7 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all double rw_perc = 100.0 * double(rw_bytes) / double(rw_all); double perc = 100.0 * double(bytes) / double(ro_all + rw_all); - tty->print_cr(fmt, name, + tty->print_cr(fmt_stats, name, ro_count, ro_bytes, ro_perc, rw_count, rw_bytes, rw_perc, count, bytes, perc); @@ -375,14 +377,15 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all); double all_perc = 100.0 * double(all_bytes) / double(ro_all + rw_all); - tty->print_cr(sep); - tty->print_cr(fmt, "Total", + tty->print_cr("%s", sep); + tty->print_cr(fmt_stats, "Total", all_ro_count, all_ro_bytes, all_ro_perc, all_rw_count, all_rw_bytes, all_rw_perc, all_count, all_bytes, all_perc); assert(all_ro_bytes == ro_all, "everything should have been counted"); assert(all_rw_bytes == rw_all, "everything should have been counted"); +#undef fmt_stats } // Populate the shared space. @@ -514,7 +517,8 @@ void VM_PopulateDumpSharedSpace::doit() { md_top = wc.get_top(); // Print shared spaces all the time - const char* fmt = "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " PTR_FORMAT; +// To make fmt_space be a syntactic constant (for format warnings), use #define. +#define fmt_space "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " INTPTR_FORMAT Metaspace* ro_space = _loader_data->ro_metaspace(); Metaspace* rw_space = _loader_data->rw_metaspace(); @@ -545,10 +549,10 @@ void VM_PopulateDumpSharedSpace::doit() { const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0; const double total_u_perc = total_bytes / double(total_alloced) * 100.0; - tty->print_cr(fmt, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom()); - tty->print_cr(fmt, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom()); - tty->print_cr(fmt, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low); - tty->print_cr(fmt, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low); + tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom()); + tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom()); + tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low); + tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low); tty->print_cr("total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]", total_bytes, total_alloced, total_u_perc); @@ -603,6 +607,7 @@ void VM_PopulateDumpSharedSpace::doit() { dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes)); } +#undef fmt_space } static void link_shared_classes(Klass* obj, TRAPS) { diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp index 72a43d85df3..2a87b4b65b6 100644 --- a/hotspot/src/share/vm/memory/referenceProcessor.cpp +++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "runtime/java.hpp" #include "runtime/jniHandles.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; bool ReferenceProcessor::_pending_list_uses_discovered_field = false; diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp index b59635c9f33..77011f7a166 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.cpp +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_interface/collectedHeap.inline.hpp" @@ -35,6 +35,8 @@ #include "utilities/copy.hpp" #include "utilities/workgroup.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + SharedHeap* SharedHeap::_sh; // The set of potentially parallel tasks in strong root scanning. diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 8bff19441d9..ae29692a62b 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,12 +37,15 @@ #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" #include "runtime/java.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/safepoint.hpp" #include "utilities/copy.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top, HeapWord* top_obj) { if (top_obj != NULL) { diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp index 2e0ebcb09b4..4c2974dcdab 100644 --- a/hotspot/src/share/vm/memory/space.hpp +++ b/hotspot/src/share/vm/memory/space.hpp @@ -33,24 +33,8 @@ #include "memory/watermark.hpp" #include "oops/markOop.hpp" #include "runtime/mutexLocker.hpp" -#include "runtime/prefetch.hpp" #include "utilities/macros.hpp" #include "utilities/workgroup.hpp" -#ifdef TARGET_OS_FAMILY_linux -# include "os_linux.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_solaris -# include "os_solaris.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_windows -# include "os_windows.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_aix -# include "os_aix.inline.hpp" -#endif -#ifdef TARGET_OS_FAMILY_bsd -# include "os_bsd.inline.hpp" -#endif // A space is an abstraction for the "storage units" backing // up the generation abstraction. It includes specific @@ -468,272 +452,6 @@ protected: size_t word_len); }; -#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ - /* Compute the new addresses for the live objects and store it in the mark \ - * Used by universe::mark_sweep_phase2() \ - */ \ - HeapWord* compact_top; /* This is where we are currently compacting to. */ \ - \ - /* We're sure to be here before any objects are compacted into this \ - * space, so this is a good time to initialize this: \ - */ \ - set_compaction_top(bottom()); \ - \ - if (cp->space == NULL) { \ - assert(cp->gen != NULL, "need a generation"); \ - assert(cp->threshold == NULL, "just checking"); \ - assert(cp->gen->first_compaction_space() == this, "just checking"); \ - cp->space = cp->gen->first_compaction_space(); \ - compact_top = cp->space->bottom(); \ - cp->space->set_compaction_top(compact_top); \ - cp->threshold = cp->space->initialize_threshold(); \ - } else { \ - compact_top = cp->space->compaction_top(); \ - } \ - \ - /* We allow some amount of garbage towards the bottom of the space, so \ - * we don't start compacting before there is a significant gain to be made.\ - * Occasionally, we want to ensure a full compaction, which is determined \ - * by the MarkSweepAlwaysCompactCount parameter. \ - */ \ - uint invocations = MarkSweep::total_invocations(); \ - bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \ - \ - size_t allowed_deadspace = 0; \ - if (skip_dead) { \ - const size_t ratio = allowed_dead_ratio(); \ - allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \ - } \ - \ - HeapWord* q = bottom(); \ - HeapWord* t = scan_limit(); \ - \ - HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \ - live object. */ \ - HeapWord* first_dead = end();/* The first dead object. */ \ - LiveRange* liveRange = NULL; /* The current live range, recorded in the \ - first header of preceding free area. */ \ - _first_dead = first_dead; \ - \ - const intx interval = PrefetchScanIntervalInBytes; \ - \ - while (q < t) { \ - assert(!block_is_obj(q) || \ - oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \ - oop(q)->mark()->has_bias_pattern(), \ - "these are the only valid states during a mark sweep"); \ - if (block_is_obj(q) && oop(q)->is_gc_marked()) { \ - /* prefetch beyond q */ \ - Prefetch::write(q, interval); \ - size_t size = block_size(q); \ - compact_top = cp->space->forward(oop(q), size, cp, compact_top); \ - q += size; \ - end_of_live = q; \ - } else { \ - /* run over all the contiguous dead objects */ \ - HeapWord* end = q; \ - do { \ - /* prefetch beyond end */ \ - Prefetch::write(end, interval); \ - end += block_size(end); \ - } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\ - \ - /* see if we might want to pretend this object is alive so that \ - * we don't have to compact quite as often. \ - */ \ - if (allowed_deadspace > 0 && q == compact_top) { \ - size_t sz = pointer_delta(end, q); \ - if (insert_deadspace(allowed_deadspace, q, sz)) { \ - compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \ - q = end; \ - end_of_live = end; \ - continue; \ - } \ - } \ - \ - /* otherwise, it really is a free region. */ \ - \ - /* for the previous LiveRange, record the end of the live objects. */ \ - if (liveRange) { \ - liveRange->set_end(q); \ - } \ - \ - /* record the current LiveRange object. \ - * liveRange->start() is overlaid on the mark word. \ - */ \ - liveRange = (LiveRange*)q; \ - liveRange->set_start(end); \ - liveRange->set_end(end); \ - \ - /* see if this is the first dead region. */ \ - if (q < first_dead) { \ - first_dead = q; \ - } \ - \ - /* move on to the next object */ \ - q = end; \ - } \ - } \ - \ - assert(q == t, "just checking"); \ - if (liveRange != NULL) { \ - liveRange->set_end(q); \ - } \ - _end_of_live = end_of_live; \ - if (end_of_live < first_dead) { \ - first_dead = end_of_live; \ - } \ - _first_dead = first_dead; \ - \ - /* save the compaction_top of the compaction space. */ \ - cp->space->set_compaction_top(compact_top); \ -} - -#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \ - /* adjust all the interior pointers to point at the new locations of objects \ - * Used by MarkSweep::mark_sweep_phase3() */ \ - \ - HeapWord* q = bottom(); \ - HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \ - \ - assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \ - \ - if (q < t && _first_dead > q && \ - !oop(q)->is_gc_marked()) { \ - /* we have a chunk of the space which hasn't moved and we've \ - * reinitialized the mark word during the previous pass, so we can't \ - * use is_gc_marked for the traversal. */ \ - HeapWord* end = _first_dead; \ - \ - while (q < end) { \ - /* I originally tried to conjoin "block_start(q) == q" to the \ - * assertion below, but that doesn't work, because you can't \ - * accurately traverse previous objects to get to the current one \ - * after their pointers have been \ - * updated, until the actual compaction is done. dld, 4/00 */ \ - assert(block_is_obj(q), \ - "should be at block boundaries, and should be looking at objs"); \ - \ - /* point all the oops to the new location */ \ - size_t size = oop(q)->adjust_pointers(); \ - size = adjust_obj_size(size); \ - \ - q += size; \ - } \ - \ - if (_first_dead == t) { \ - q = t; \ - } else { \ - /* $$$ This is funky. Using this to read the previously written \ - * LiveRange. See also use below. */ \ - q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \ - } \ - } \ - \ - const intx interval = PrefetchScanIntervalInBytes; \ - \ - debug_only(HeapWord* prev_q = NULL); \ - while (q < t) { \ - /* prefetch beyond q */ \ - Prefetch::write(q, interval); \ - if (oop(q)->is_gc_marked()) { \ - /* q is alive */ \ - /* point all the oops to the new location */ \ - size_t size = oop(q)->adjust_pointers(); \ - size = adjust_obj_size(size); \ - debug_only(prev_q = q); \ - q += size; \ - } else { \ - /* q is not a live object, so its mark should point at the next \ - * live object */ \ - debug_only(prev_q = q); \ - q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ - assert(q > prev_q, "we should be moving forward through memory"); \ - } \ - } \ - \ - assert(q == t, "just checking"); \ -} - -#define SCAN_AND_COMPACT(obj_size) { \ - /* Copy all live objects to their new location \ - * Used by MarkSweep::mark_sweep_phase4() */ \ - \ - HeapWord* q = bottom(); \ - HeapWord* const t = _end_of_live; \ - debug_only(HeapWord* prev_q = NULL); \ - \ - if (q < t && _first_dead > q && \ - !oop(q)->is_gc_marked()) { \ - debug_only( \ - /* we have a chunk of the space which hasn't moved and we've reinitialized \ - * the mark word during the previous pass, so we can't use is_gc_marked for \ - * the traversal. */ \ - HeapWord* const end = _first_dead; \ - \ - while (q < end) { \ - size_t size = obj_size(q); \ - assert(!oop(q)->is_gc_marked(), \ - "should be unmarked (special dense prefix handling)"); \ - debug_only(prev_q = q); \ - q += size; \ - } \ - ) /* debug_only */ \ - \ - if (_first_dead == t) { \ - q = t; \ - } else { \ - /* $$$ Funky */ \ - q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \ - } \ - } \ - \ - const intx scan_interval = PrefetchScanIntervalInBytes; \ - const intx copy_interval = PrefetchCopyIntervalInBytes; \ - while (q < t) { \ - if (!oop(q)->is_gc_marked()) { \ - /* mark is pointer to next marked oop */ \ - debug_only(prev_q = q); \ - q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ - assert(q > prev_q, "we should be moving forward through memory"); \ - } else { \ - /* prefetch beyond q */ \ - Prefetch::read(q, scan_interval); \ - \ - /* size and destination */ \ - size_t size = obj_size(q); \ - HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ - \ - /* prefetch beyond compaction_top */ \ - Prefetch::write(compaction_top, copy_interval); \ - \ - /* copy object and reinit its mark */ \ - assert(q != compaction_top, "everything in this pass should be moving"); \ - Copy::aligned_conjoint_words(q, compaction_top, size); \ - oop(compaction_top)->init_mark(); \ - assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ - \ - debug_only(prev_q = q); \ - q += size; \ - } \ - } \ - \ - /* Let's remember if we were empty before we did the compaction. */ \ - bool was_empty = used_region().is_empty(); \ - /* Reset space after compaction is complete */ \ - reset_after_compaction(); \ - /* We do this clear, below, since it has overloaded meanings for some */ \ - /* space subtypes. For example, OffsetTableContigSpace's that were */ \ - /* compacted into will have had their offset table thresholds updated */ \ - /* continuously, but those that weren't need to have their thresholds */ \ - /* re-initialized. Also mangles unused area for debugging. */ \ - if (used_region().is_empty()) { \ - if (!was_empty) clear(SpaceDecorator::Mangle); \ - } else { \ - if (ZapUnusedHeapArea) mangle_unused_area(); \ - } \ -} - class GenSpaceMangler; // A space in which the free area is contiguous. It therefore supports diff --git a/hotspot/src/share/vm/memory/space.inline.hpp b/hotspot/src/share/vm/memory/space.inline.hpp index 1d600e2a1aa..007cebd16e6 100644 --- a/hotspot/src/share/vm/memory/space.inline.hpp +++ b/hotspot/src/share/vm/memory/space.inline.hpp @@ -28,12 +28,279 @@ #include "gc_interface/collectedHeap.hpp" #include "memory/space.hpp" #include "memory/universe.hpp" +#include "runtime/prefetch.inline.hpp" #include "runtime/safepoint.hpp" inline HeapWord* Space::block_start(const void* p) { return block_start_const(p); } +#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ + /* Compute the new addresses for the live objects and store it in the mark \ + * Used by universe::mark_sweep_phase2() \ + */ \ + HeapWord* compact_top; /* This is where we are currently compacting to. */ \ + \ + /* We're sure to be here before any objects are compacted into this \ + * space, so this is a good time to initialize this: \ + */ \ + set_compaction_top(bottom()); \ + \ + if (cp->space == NULL) { \ + assert(cp->gen != NULL, "need a generation"); \ + assert(cp->threshold == NULL, "just checking"); \ + assert(cp->gen->first_compaction_space() == this, "just checking"); \ + cp->space = cp->gen->first_compaction_space(); \ + compact_top = cp->space->bottom(); \ + cp->space->set_compaction_top(compact_top); \ + cp->threshold = cp->space->initialize_threshold(); \ + } else { \ + compact_top = cp->space->compaction_top(); \ + } \ + \ + /* We allow some amount of garbage towards the bottom of the space, so \ + * we don't start compacting before there is a significant gain to be made.\ + * Occasionally, we want to ensure a full compaction, which is determined \ + * by the MarkSweepAlwaysCompactCount parameter. \ + */ \ + uint invocations = MarkSweep::total_invocations(); \ + bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \ + \ + size_t allowed_deadspace = 0; \ + if (skip_dead) { \ + const size_t ratio = allowed_dead_ratio(); \ + allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \ + } \ + \ + HeapWord* q = bottom(); \ + HeapWord* t = scan_limit(); \ + \ + HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \ + live object. */ \ + HeapWord* first_dead = end();/* The first dead object. */ \ + LiveRange* liveRange = NULL; /* The current live range, recorded in the \ + first header of preceding free area. */ \ + _first_dead = first_dead; \ + \ + const intx interval = PrefetchScanIntervalInBytes; \ + \ + while (q < t) { \ + assert(!block_is_obj(q) || \ + oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \ + oop(q)->mark()->has_bias_pattern(), \ + "these are the only valid states during a mark sweep"); \ + if (block_is_obj(q) && oop(q)->is_gc_marked()) { \ + /* prefetch beyond q */ \ + Prefetch::write(q, interval); \ + size_t size = block_size(q); \ + compact_top = cp->space->forward(oop(q), size, cp, compact_top); \ + q += size; \ + end_of_live = q; \ + } else { \ + /* run over all the contiguous dead objects */ \ + HeapWord* end = q; \ + do { \ + /* prefetch beyond end */ \ + Prefetch::write(end, interval); \ + end += block_size(end); \ + } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\ + \ + /* see if we might want to pretend this object is alive so that \ + * we don't have to compact quite as often. \ + */ \ + if (allowed_deadspace > 0 && q == compact_top) { \ + size_t sz = pointer_delta(end, q); \ + if (insert_deadspace(allowed_deadspace, q, sz)) { \ + compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \ + q = end; \ + end_of_live = end; \ + continue; \ + } \ + } \ + \ + /* otherwise, it really is a free region. */ \ + \ + /* for the previous LiveRange, record the end of the live objects. */ \ + if (liveRange) { \ + liveRange->set_end(q); \ + } \ + \ + /* record the current LiveRange object. \ + * liveRange->start() is overlaid on the mark word. \ + */ \ + liveRange = (LiveRange*)q; \ + liveRange->set_start(end); \ + liveRange->set_end(end); \ + \ + /* see if this is the first dead region. */ \ + if (q < first_dead) { \ + first_dead = q; \ + } \ + \ + /* move on to the next object */ \ + q = end; \ + } \ + } \ + \ + assert(q == t, "just checking"); \ + if (liveRange != NULL) { \ + liveRange->set_end(q); \ + } \ + _end_of_live = end_of_live; \ + if (end_of_live < first_dead) { \ + first_dead = end_of_live; \ + } \ + _first_dead = first_dead; \ + \ + /* save the compaction_top of the compaction space. */ \ + cp->space->set_compaction_top(compact_top); \ +} + +#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \ + /* adjust all the interior pointers to point at the new locations of objects \ + * Used by MarkSweep::mark_sweep_phase3() */ \ + \ + HeapWord* q = bottom(); \ + HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \ + \ + assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \ + \ + if (q < t && _first_dead > q && \ + !oop(q)->is_gc_marked()) { \ + /* we have a chunk of the space which hasn't moved and we've \ + * reinitialized the mark word during the previous pass, so we can't \ + * use is_gc_marked for the traversal. */ \ + HeapWord* end = _first_dead; \ + \ + while (q < end) { \ + /* I originally tried to conjoin "block_start(q) == q" to the \ + * assertion below, but that doesn't work, because you can't \ + * accurately traverse previous objects to get to the current one \ + * after their pointers have been \ + * updated, until the actual compaction is done. dld, 4/00 */ \ + assert(block_is_obj(q), \ + "should be at block boundaries, and should be looking at objs"); \ + \ + /* point all the oops to the new location */ \ + size_t size = oop(q)->adjust_pointers(); \ + size = adjust_obj_size(size); \ + \ + q += size; \ + } \ + \ + if (_first_dead == t) { \ + q = t; \ + } else { \ + /* $$$ This is funky. Using this to read the previously written \ + * LiveRange. See also use below. */ \ + q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \ + } \ + } \ + \ + const intx interval = PrefetchScanIntervalInBytes; \ + \ + debug_only(HeapWord* prev_q = NULL); \ + while (q < t) { \ + /* prefetch beyond q */ \ + Prefetch::write(q, interval); \ + if (oop(q)->is_gc_marked()) { \ + /* q is alive */ \ + /* point all the oops to the new location */ \ + size_t size = oop(q)->adjust_pointers(); \ + size = adjust_obj_size(size); \ + debug_only(prev_q = q); \ + q += size; \ + } else { \ + /* q is not a live object, so its mark should point at the next \ + * live object */ \ + debug_only(prev_q = q); \ + q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ + assert(q > prev_q, "we should be moving forward through memory"); \ + } \ + } \ + \ + assert(q == t, "just checking"); \ +} + +#define SCAN_AND_COMPACT(obj_size) { \ + /* Copy all live objects to their new location \ + * Used by MarkSweep::mark_sweep_phase4() */ \ + \ + HeapWord* q = bottom(); \ + HeapWord* const t = _end_of_live; \ + debug_only(HeapWord* prev_q = NULL); \ + \ + if (q < t && _first_dead > q && \ + !oop(q)->is_gc_marked()) { \ + debug_only( \ + /* we have a chunk of the space which hasn't moved and we've reinitialized \ + * the mark word during the previous pass, so we can't use is_gc_marked for \ + * the traversal. */ \ + HeapWord* const end = _first_dead; \ + \ + while (q < end) { \ + size_t size = obj_size(q); \ + assert(!oop(q)->is_gc_marked(), \ + "should be unmarked (special dense prefix handling)"); \ + debug_only(prev_q = q); \ + q += size; \ + } \ + ) /* debug_only */ \ + \ + if (_first_dead == t) { \ + q = t; \ + } else { \ + /* $$$ Funky */ \ + q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \ + } \ + } \ + \ + const intx scan_interval = PrefetchScanIntervalInBytes; \ + const intx copy_interval = PrefetchCopyIntervalInBytes; \ + while (q < t) { \ + if (!oop(q)->is_gc_marked()) { \ + /* mark is pointer to next marked oop */ \ + debug_only(prev_q = q); \ + q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ + assert(q > prev_q, "we should be moving forward through memory"); \ + } else { \ + /* prefetch beyond q */ \ + Prefetch::read(q, scan_interval); \ + \ + /* size and destination */ \ + size_t size = obj_size(q); \ + HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ + \ + /* prefetch beyond compaction_top */ \ + Prefetch::write(compaction_top, copy_interval); \ + \ + /* copy object and reinit its mark */ \ + assert(q != compaction_top, "everything in this pass should be moving"); \ + Copy::aligned_conjoint_words(q, compaction_top, size); \ + oop(compaction_top)->init_mark(); \ + assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ + \ + debug_only(prev_q = q); \ + q += size; \ + } \ + } \ + \ + /* Let's remember if we were empty before we did the compaction. */ \ + bool was_empty = used_region().is_empty(); \ + /* Reset space after compaction is complete */ \ + reset_after_compaction(); \ + /* We do this clear, below, since it has overloaded meanings for some */ \ + /* space subtypes. For example, OffsetTableContigSpace's that were */ \ + /* compacted into will have had their offset table thresholds updated */ \ + /* continuously, but those that weren't need to have their thresholds */ \ + /* re-initialized. Also mangles unused area for debugging. */ \ + if (used_region().is_empty()) { \ + if (!was_empty) clear(SpaceDecorator::Mangle); \ + } else { \ + if (ZapUnusedHeapArea) mangle_unused_area(); \ + } \ +} + inline HeapWord* OffsetTableContigSpace::allocate(size_t size) { HeapWord* res = ContiguousSpace::allocate(size); if (res != NULL) { diff --git a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp index 715e6214c9b..b59cfd80d39 100644 --- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp +++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Thread-Local Edens support // static member initialization diff --git a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp index ea803157300..cf3fefbfe3a 100644 --- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp +++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ void ThreadLocalAllocBuffer::record_slow_allocation(size_t obj_size) { " obj: "SIZE_FORMAT " free: "SIZE_FORMAT " waste: "SIZE_FORMAT"\n", - "slow", thrd, thrd->osthread()->thread_id(), + "slow", p2i(thrd), thrd->osthread()->thread_id(), obj_size, free(), refill_waste_limit()); } } diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 63c7c005d44..0250f1a1b8d 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" @@ -78,6 +78,8 @@ #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Known objects Klass* Universe::_boolArrayKlassObj = NULL; Klass* Universe::_byteArrayKlassObj = NULL; @@ -1348,7 +1350,7 @@ void Universe::verify(VerifyOption option, const char* prefix, bool silent) { HandleMark hm; // Handles created during verification can be zapped _verify_count++; - if (!silent) gclog_or_tty->print(prefix); + if (!silent) gclog_or_tty->print("%s", prefix); if (!silent) gclog_or_tty->print("[Verifying "); if (!silent) gclog_or_tty->print("threads "); Threads::verify(); diff --git a/hotspot/src/share/vm/oops/annotations.cpp b/hotspot/src/share/vm/oops/annotations.cpp index 1eb3afbb740..776b8606b66 100644 --- a/hotspot/src/share/vm/oops/annotations.cpp +++ b/hotspot/src/share/vm/oops/annotations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ typeArrayOop Annotations::make_java_array(AnnotationArray* annotations, TRAPS) { void Annotations::print_value_on(outputStream* st) const { - st->print("Anotations(" INTPTR_FORMAT ")", this); + st->print("Anotations(" INTPTR_FORMAT ")", p2i(this)); } #if INCLUDE_SERVICES diff --git a/hotspot/src/share/vm/oops/constMethod.cpp b/hotspot/src/share/vm/oops/constMethod.cpp index 4c0720908f7..ea51a2c02c4 100644 --- a/hotspot/src/share/vm/oops/constMethod.cpp +++ b/hotspot/src/share/vm/oops/constMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -388,8 +388,8 @@ void ConstMethod::copy_annotations_from(ConstMethod* cm) { void ConstMethod::print_on(outputStream* st) const { ResourceMark rm; assert(is_constMethod(), "must be constMethod"); - st->print_cr(internal_name()); - st->print(" - method: " INTPTR_FORMAT " ", (address)method()); + st->print_cr("%s", internal_name()); + st->print(" - method: " INTPTR_FORMAT " ", p2i((address)method())); method()->print_value_on(st); st->cr(); if (has_stackmap_table()) { st->print(" - stackmap data: "); diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index bd2ee585149..b45fe508a64 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -26,7 +26,7 @@ #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" #include "classfile/metadataOnStackMark.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "interpreter/linkResolver.hpp" @@ -42,6 +42,8 @@ #include "runtime/signature.hpp" #include "runtime/vframe.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { // Tags are RW but comment below applies to tags also. Array* tags = MetadataFactory::new_writeable_array(loader_data, length, 0, CHECK_NULL); @@ -1892,7 +1894,7 @@ void ConstantPool::preload_and_initialize_all_classes(ConstantPool* obj, TRAPS) void ConstantPool::print_on(outputStream* st) const { assert(is_constantPool(), "must be constantPool"); - st->print_cr(internal_name()); + st->print_cr("%s", internal_name()); if (flags() != 0) { st->print(" - flags: 0x%x", flags()); if (has_preresolution()) st->print(" has_preresolution"); diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index cdd3cef4ad1..527b771fd68 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -39,8 +39,9 @@ # include "gc_implementation/parallelScavenge/psPromotionManager.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC -// Implememtation of ConstantPoolCacheEntry +// Implementation of ConstantPoolCacheEntry void ConstantPoolCacheEntry::initialize_entry(int index) { assert(0 < index && index < 0x10000, "sanity check"); @@ -497,9 +498,10 @@ bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { // _f1 == NULL || !_f1->is_method() are OK here return true; } - // return false if _f1 refers to an old or an obsolete method + // return false if _f1 refers to a non-deleted old or obsolete method return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && - !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete()); + (f1_as_method()->is_deleted() || + (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); } bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) { @@ -668,7 +670,7 @@ void ConstantPoolCache::dump_cache() { void ConstantPoolCache::print_on(outputStream* st) const { assert(is_constantPoolCache(), "obj must be constant pool cache"); - st->print_cr(internal_name()); + st->print_cr("%s", internal_name()); // print constant pool cache entries for (int i = 0; i < length(); i++) entry_at(i)->print(st, i); } diff --git a/hotspot/src/share/vm/oops/generateOopMap.hpp b/hotspot/src/share/vm/oops/generateOopMap.hpp index ad0578c323a..48c49f443e9 100644 --- a/hotspot/src/share/vm/oops/generateOopMap.hpp +++ b/hotspot/src/share/vm/oops/generateOopMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -412,9 +412,9 @@ class GenerateOopMap VALUE_OBJ_CLASS_SPEC { int copy_cts (CellTypeState *dst, CellTypeState *src); // Error handling - void error_work (const char *format, va_list ap); - void report_error (const char *format, ...); - void verify_error (const char *format, ...); + void error_work (const char *format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void report_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3); + void verify_error (const char *format, ...) ATTRIBUTE_PRINTF(2, 3); bool got_error() { return _got_error; } // Create result set diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 84775407262..34907dd55a5 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -77,6 +77,8 @@ #include "c1/c1_Compiler.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef DTRACE_ENABLED @@ -1271,6 +1273,12 @@ bool InstanceKlass::find_field_from_offset(int offset, bool is_static, fieldDesc void InstanceKlass::methods_do(void f(Method* method)) { + // Methods aren't stable until they are loaded. This can be read outside + // a lock through the ClassLoaderData for profiling + if (!is_loaded()) { + return; + } + int len = methods()->length(); for (int index = 0; index < len; index++) { Method* m = methods()->at(index); @@ -2857,7 +2865,7 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"instance size: %d", size_helper()); st->cr(); st->print(BULLET"klass size: %d", size()); st->cr(); st->print(BULLET"access: "); access_flags().print_on(st); st->cr(); - st->print(BULLET"state: "); st->print_cr(state_names[_init_state]); + st->print(BULLET"state: "); st->print_cr("%s", state_names[_init_state]); st->print(BULLET"name: "); name()->print_value_on(st); st->cr(); st->print(BULLET"super: "); super()->print_value_on_maybe_null(st); st->cr(); st->print(BULLET"sub: "); diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp index f388980adc3..7340e5adc91 100644 --- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ #include "oops/oop.pcgc.inline.hpp" #endif // INCLUDE_ALL_GCS +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + template void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index 12e5b5ec708..d81dceb8f37 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -640,7 +640,7 @@ void Klass::verify_on(outputStream* st) { // This can be expensive, but it is worth checking that this klass is actually // in the CLD graph but not in production. - assert(ClassLoaderDataGraph::contains((address)this), "Should be"); + assert(Metaspace::contains((address)this), "Should be"); guarantee(this->is_klass(),"should be klass"); diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 6aac575cf11..06198fbb11c 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -555,36 +555,6 @@ class Klass : public Metadata { static void clean_weak_klass_links(BoolObjectClosure* is_alive); - // Prefetch within oop iterators. This is a macro because we - // can't guarantee that the compiler will inline it. In 64-bit - // it generally doesn't. Signature is - // - // static void prefetch_beyond(oop* const start, - // oop* const end, - // const intx foffset, - // const Prefetch::style pstyle); -#define prefetch_beyond(start, end, foffset, pstyle) { \ - const intx foffset_ = (foffset); \ - const Prefetch::style pstyle_ = (pstyle); \ - assert(foffset_ > 0, "prefetch beyond, not behind"); \ - if (pstyle_ != Prefetch::do_none) { \ - oop* ref = (start); \ - if (ref < (end)) { \ - switch (pstyle_) { \ - case Prefetch::do_read: \ - Prefetch::read(*ref, foffset_); \ - break; \ - case Prefetch::do_write: \ - Prefetch::write(*ref, foffset_); \ - break; \ - default: \ - ShouldNotReachHere(); \ - break; \ - } \ - } \ - } \ - } - // iterators virtual int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) = 0; virtual int oop_oop_iterate_v(oop obj, ExtendedOopClosure* blk) { diff --git a/hotspot/src/share/vm/oops/klass.inline.hpp b/hotspot/src/share/vm/oops/klass.inline.hpp index 841a4873a32..8b05c3c2945 100644 --- a/hotspot/src/share/vm/oops/klass.inline.hpp +++ b/hotspot/src/share/vm/oops/klass.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ inline Klass* Klass::decode_klass_not_null(narrowKlass v) { assert(!is_null(v), "narrow klass value can never be zero"); int shift = Universe::narrow_klass_shift(); Klass* result = (Klass*)(void*)((uintptr_t)Universe::narrow_klass_base() + ((uintptr_t)v << shift)); - assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); + assert(check_klass_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result))); return result; } diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index ad185c7f1a8..6d122de680a 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -39,6 +39,8 @@ #include "runtime/handles.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + inline InstanceKlass* klassVtable::ik() const { Klass* k = _klass(); assert(k->oop_is_instance(), "not an InstanceKlass"); diff --git a/hotspot/src/share/vm/oops/markOop.cpp b/hotspot/src/share/vm/oops/markOop.cpp index af722e7cf72..85dd5a06a65 100644 --- a/hotspot/src/share/vm/oops/markOop.cpp +++ b/hotspot/src/share/vm/oops/markOop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,11 @@ #include "oops/markOop.hpp" #include "runtime/thread.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void markOopDesc::print_on(outputStream* st) const { if (is_locked()) { - st->print("locked(0x%lx)->", value()); + st->print("locked(" INTPTR_FORMAT ")->", value()); markOop(*(markOop*)value())->print_on(st); } else { assert(is_unlocked() || has_bias_pattern(), "just checking"); diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 883ff487b26..01ef61f2386 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -56,6 +56,7 @@ #include "utilities/quickSort.hpp" #include "utilities/xmlstream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of Method @@ -1018,13 +1019,11 @@ bool Method::should_not_be_cached() const { * security related stack walks (like Reflection.getCallerClass). */ bool Method::is_ignored_by_security_stack_walk() const { - const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; - if (intrinsic_id() == vmIntrinsics::_invoke) { // This is Method.invoke() -- ignore it return true; } - if (use_new_reflection && + if (JDK_Version::is_gte_jdk14x_version() && method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { // This is an auxilary frame -- ignore it return true; @@ -1425,7 +1424,7 @@ class SignatureTypePrinter : public SignatureTypeNames { void type_name(const char* name) { if (_use_separator) _st->print(", "); - _st->print(name); + _st->print("%s", name); _use_separator = true; } @@ -1867,6 +1866,14 @@ void Method::clear_jmethod_ids(ClassLoaderData* loader_data) { loader_data->jmethod_ids()->clear_all_methods(); } +bool Method::has_method_vptr(const void* ptr) { + Method m; + // This assumes that the vtbl pointer is the first word of a C++ object. + // This assumption is also in universe.cpp patch_klass_vtble + void* vtbl2 = dereference_vptr((const void*)&m); + void* this_vtbl = dereference_vptr(ptr); + return vtbl2 == this_vtbl; +} // Check that this pointer is valid by checking that the vtbl pointer matches bool Method::is_valid_method() const { @@ -1875,12 +1882,7 @@ bool Method::is_valid_method() const { } else if (!is_metaspace_object()) { return false; } else { - Method m; - // This assumes that the vtbl pointer is the first word of a C++ object. - // This assumption is also in universe.cpp patch_klass_vtble - void* vtbl2 = dereference_vptr((void*)&m); - void* this_vtbl = dereference_vptr((void*)this); - return vtbl2 == this_vtbl; + return has_method_vptr((const void*)this); } } @@ -1898,7 +1900,7 @@ void Method::print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) void Method::print_on(outputStream* st) const { ResourceMark rm; assert(is_method(), "must be method"); - st->print_cr(internal_name()); + st->print_cr("%s", internal_name()); // get the effect of PrintOopAddress, always, for methods: st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)this); st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr(); @@ -1981,7 +1983,7 @@ void Method::print_on(outputStream* st) const { void Method::print_value_on(outputStream* st) const { assert(is_method(), "must be method"); - st->print(internal_name()); + st->print("%s", internal_name()); print_address_on(st); st->print(" "); name()->print_value_on(st); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 7d5afaec0b8..a2c36db39f4 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -200,10 +200,11 @@ class Method : public Metadata { // Tracking number of breakpoints, for fullspeed debugging. // Only mutated by VM thread. u2 number_of_breakpoints() const { - if (method_counters() == NULL) { + MethodCounters* mcs = method_counters(); + if (mcs == NULL) { return 0; } else { - return method_counters()->number_of_breakpoints(); + return mcs->number_of_breakpoints(); } } void incr_number_of_breakpoints(TRAPS) { @@ -220,8 +221,9 @@ class Method : public Metadata { } // Initialization only void clear_number_of_breakpoints() { - if (method_counters() != NULL) { - method_counters()->clear_number_of_breakpoints(); + MethodCounters* mcs = method_counters(); + if (mcs != NULL) { + mcs->clear_number_of_breakpoints(); } } @@ -268,10 +270,11 @@ class Method : public Metadata { } int interpreter_throwout_count() const { - if (method_counters() == NULL) { + MethodCounters* mcs = method_counters(); + if (mcs == NULL) { return 0; } else { - return method_counters()->interpreter_throwout_count(); + return mcs->interpreter_throwout_count(); } } @@ -346,31 +349,40 @@ class Method : public Metadata { return method_counters()->interpreter_invocation_count(); } } - void set_prev_event_count(int count, TRAPS) { - MethodCounters* mcs = get_method_counters(CHECK); + void set_prev_event_count(int count) { + MethodCounters* mcs = method_counters(); if (mcs != NULL) { mcs->set_interpreter_invocation_count(count); } } jlong prev_time() const { - return method_counters() == NULL ? 0 : method_counters()->prev_time(); + MethodCounters* mcs = method_counters(); + return mcs == NULL ? 0 : mcs->prev_time(); } - void set_prev_time(jlong time, TRAPS) { - MethodCounters* mcs = get_method_counters(CHECK); + void set_prev_time(jlong time) { + MethodCounters* mcs = method_counters(); if (mcs != NULL) { mcs->set_prev_time(time); } } float rate() const { - return method_counters() == NULL ? 0 : method_counters()->rate(); + MethodCounters* mcs = method_counters(); + return mcs == NULL ? 0 : mcs->rate(); } - void set_rate(float rate, TRAPS) { - MethodCounters* mcs = get_method_counters(CHECK); + void set_rate(float rate) { + MethodCounters* mcs = method_counters(); if (mcs != NULL) { mcs->set_rate(rate); } } #endif + int nmethod_age() const { + if (method_counters() == NULL) { + return INT_MAX; + } else { + return method_counters()->nmethod_age(); + } + } int invocation_count(); int backedge_count(); @@ -383,9 +395,12 @@ class Method : public Metadata { static MethodCounters* build_method_counters(Method* m, TRAPS); int interpreter_invocation_count() { - if (TieredCompilation) return invocation_count(); - else return (method_counters() == NULL) ? 0 : - method_counters()->interpreter_invocation_count(); + if (TieredCompilation) { + return invocation_count(); + } else { + MethodCounters* mcs = method_counters(); + return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count(); + } } int increment_interpreter_invocation_count(TRAPS) { if (TieredCompilation) ShouldNotReachHere(); @@ -669,6 +684,8 @@ class Method : public Metadata { void set_is_old() { _access_flags.set_is_old(); } bool is_obsolete() const { return access_flags().is_obsolete(); } void set_is_obsolete() { _access_flags.set_is_obsolete(); } + bool is_deleted() const { return access_flags().is_deleted(); } + void set_is_deleted() { _access_flags.set_is_deleted(); } bool on_stack() const { return access_flags().on_stack(); } void set_on_stack(const bool value); @@ -861,6 +878,7 @@ class Method : public Metadata { const char* internal_name() const { return "{method}"; } // Check for valid method pointer + static bool has_method_vptr(const void* ptr); bool is_valid_method() const; // Verify diff --git a/hotspot/src/share/vm/oops/methodCounters.cpp b/hotspot/src/share/vm/oops/methodCounters.cpp index 1ee8eb17001..91b05a7bcc8 100644 --- a/hotspot/src/share/vm/oops/methodCounters.cpp +++ b/hotspot/src/share/vm/oops/methodCounters.cpp @@ -34,4 +34,5 @@ void MethodCounters::clear_counters() { backedge_counter()->reset(); set_interpreter_throwout_count(0); set_interpreter_invocation_count(0); + set_nmethod_age(INT_MAX); } diff --git a/hotspot/src/share/vm/oops/methodCounters.hpp b/hotspot/src/share/vm/oops/methodCounters.hpp index 0a6c895b328..75b8c9e6e16 100644 --- a/hotspot/src/share/vm/oops/methodCounters.hpp +++ b/hotspot/src/share/vm/oops/methodCounters.hpp @@ -36,6 +36,15 @@ class MethodCounters: public MetaspaceObj { u2 _number_of_breakpoints; // fullspeed debugging support InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations + // NMethod age is a counter for warm methods detection in the code cache sweeper. + // The counter is reset by the sweeper and is decremented by some of the compiled + // code. The counter values are interpreted as follows: + // 1. (HotMethodDetection..INT_MAX] - initial value, no counters inserted + // 2. (1..HotMethodDetectionLimit) - the method is warm, the counter is used + // to figure out which methods can be flushed. + // 3. (INT_MIN..0] - method is hot and will deopt and get + // recompiled without the counters + int _nmethod_age; #ifdef TIERED float _rate; // Events (invocation and backedge counter increments) per millisecond @@ -44,7 +53,8 @@ class MethodCounters: public MetaspaceObj { MethodCounters() : _interpreter_invocation_count(0), _interpreter_throwout_count(0), - _number_of_breakpoints(0) + _number_of_breakpoints(0), + _nmethod_age(INT_MAX) #ifdef TIERED , _rate(0), _prev_time(0) @@ -52,6 +62,10 @@ class MethodCounters: public MetaspaceObj { { invocation_counter()->init(); backedge_counter()->init(); + + if (StressCodeAging) { + set_nmethod_age(HotMethodDetectionLimit); + } } public: @@ -104,6 +118,24 @@ class MethodCounters: public MetaspaceObj { InvocationCounter* invocation_counter() { return &_invocation_counter; } InvocationCounter* backedge_counter() { return &_backedge_counter; } + int nmethod_age() { + return _nmethod_age; + } + void set_nmethod_age(int age) { + _nmethod_age = age; + } + void reset_nmethod_age() { + set_nmethod_age(HotMethodDetectionLimit); + } + + static bool is_nmethod_hot(int age) { return age <= 0; } + static bool is_nmethod_warm(int age) { return age < HotMethodDetectionLimit; } + static bool is_nmethod_age_unset(int age) { return age > HotMethodDetectionLimit; } + + static ByteSize nmethod_age_offset() { + return byte_offset_of(MethodCounters, _nmethod_age); + } + static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(MethodCounters, _interpreter_invocation_count); } diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index 06d9dcb51bf..2975462fbbf 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ #include "runtime/handles.inline.hpp" #include "runtime/orderAccess.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // ================================================================== // DataLayout // @@ -127,7 +129,7 @@ void ProfileData::print_shared(outputStream* st, const char* name, const char* e st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap)); } if (extra != NULL) { - st->print(extra); + st->print("%s", extra); } int flags = data()->flags(); if (flags != 0) { @@ -635,7 +637,7 @@ bool ParametersTypeData::profiling_enabled() { } void ParametersTypeData::print_data_on(outputStream* st, const char* extra) const { - st->print("parameter types", extra); + st->print("parameter types"); // FIXME extra ignored? _parameters.print_data_on(st); } @@ -1128,6 +1130,7 @@ void MethodData::init() { _backedge_counter.init(); _invocation_counter_start = 0; _backedge_counter_start = 0; + _tenure_traps = 0; _num_loops = 0; _num_blocks = 0; _highest_comp_level = 0; diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index efd05cb5ade..be40bad175d 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -851,11 +851,10 @@ private: return _base_off + stack_slot_local_offset(i); } -protected: const int _number_of_entries; // offset of cell for type for entry i within ProfileData object - int type_offset(int i) const { + int type_offset_in_cells(int i) const { return _base_off + type_local_offset(i); } @@ -868,6 +867,8 @@ public: void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver); + int number_of_entries() const { return _number_of_entries; } + // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries static int stack_slot_local_offset(int i) { return i * per_arg_cell_count + stack_slot_entry; @@ -893,13 +894,13 @@ public: // type for entry i intptr_t type(int i) const { assert(i >= 0 && i < _number_of_entries, "oob"); - return _pd->intptr_at(type_offset(i)); + return _pd->intptr_at(type_offset_in_cells(i)); } // set type for entry i void set_type(int i, intptr_t k) { assert(i >= 0 && i < _number_of_entries, "oob"); - _pd->set_intptr_at(type_offset(i), k); + _pd->set_intptr_at(type_offset_in_cells(i), k); } static ByteSize per_arg_size() { @@ -907,7 +908,11 @@ public: } static int per_arg_count() { - return per_arg_cell_count ; + return per_arg_cell_count; + } + + ByteSize type_offset(int i) const { + return DataLayout::cell_offset(type_offset_in_cells(i)); } // GC support @@ -973,7 +978,7 @@ private: } static int argument_type_local_offset(int i) { - return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; + return header_cell_count() + TypeStackSlotEntries::type_local_offset(i); } public: @@ -1129,6 +1134,14 @@ public: return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); } + ByteSize argument_type_offset(int i) { + return _args.type_offset(i); + } + + ByteSize return_type_offset() { + return _ret.type_offset(); + } + // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { if (has_arguments()) { @@ -1436,6 +1449,14 @@ public: return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); } + ByteSize argument_type_offset(int i) { + return _args.type_offset(i); + } + + ByteSize return_type_offset() { + return _ret.type_offset(); + } + // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { ReceiverTypeData::clean_weak_klass_links(is_alive_closure); @@ -1926,7 +1947,7 @@ public: class SpeculativeTrapData : public ProfileData { protected: enum { - method_offset, + speculative_trap_method, speculative_trap_cell_count }; public: @@ -1946,11 +1967,15 @@ public: // Direct accessor Method* method() const { - return (Method*)intptr_at(method_offset); + return (Method*)intptr_at(speculative_trap_method); } void set_method(Method* m) { - set_intptr_at(method_offset, (intptr_t)m); + set_intptr_at(speculative_trap_method, (intptr_t)m); + } + + static ByteSize method_offset() { + return cell_offset(speculative_trap_method); } virtual void print_data_on(outputStream* st, const char* extra = NULL) const; @@ -2059,6 +2084,7 @@ private: // Counter values at the time profiling started. int _invocation_counter_start; int _backedge_counter_start; + uint _tenure_traps; #if INCLUDE_RTM_OPT // State of RTM code generation during compilation of the method @@ -2398,6 +2424,12 @@ public: method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); } } + uint tenure_traps() const { + return _tenure_traps; + } + void inc_tenure_traps() { + _tenure_traps += 1; + } // Return pointer to area dedicated to parameters in MDO ParametersTypeData* parameters_type_data() const { diff --git a/hotspot/src/share/vm/oops/oop.cpp b/hotspot/src/share/vm/oops/oop.cpp index 281188354a0..1be57811ede 100644 --- a/hotspot/src/share/vm/oops/oop.cpp +++ b/hotspot/src/share/vm/oops/oop.cpp @@ -30,6 +30,8 @@ #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + bool always_do_update_barrier = false; BarrierSet* oopDesc::_bs = NULL; diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index 7dd78ef8eb2..0dc0db8e946 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -211,7 +211,7 @@ inline oop oopDesc::decode_heap_oop_not_null(narrowOop v) { address base = Universe::narrow_oop_base(); int shift = Universe::narrow_oop_shift(); oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); - assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); + assert(check_obj_alignment(result), err_msg("address not aligned: " INTPTR_FORMAT, p2i((void*) result))); return result; } diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 3eaa2abcb7c..85598d636a3 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -339,7 +339,7 @@ void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const { st->print(" FRegPressure: %d",_freg_pressure); st->print(" FHRP Index: %d",_fhrp_index); } - st->print_cr(""); + st->cr(); } void Block::dump() const { @@ -1268,7 +1268,6 @@ void UnionFind::extend( uint from_idx, uint to_idx ) { } void UnionFind::reset( uint max ) { - assert( max <= max_uint, "Must fit within uint" ); // Force the Union-Find mapping to be at least this large extend(max,0); // Initialize to be the ID mapping. diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp index 10b69ceb17c..dced2e00f34 100644 --- a/hotspot/src/share/vm/opto/c2compiler.cpp +++ b/hotspot/src/share/vm/opto/c2compiler.cpp @@ -155,6 +155,9 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) { } } + // print inlining for last compilation only + C.dump_print_inlining(); + // No retry; just break the loop. break; } diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index ef1921a0077..249e0215c60 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -391,7 +391,7 @@ void LateInlineCallGenerator::do_late_inline() { } // Setup default node notes to be picked up by the inlining - Node_Notes* old_nn = C->default_node_notes(); + Node_Notes* old_nn = C->node_notes_at(call->_idx); if (old_nn != NULL) { Node_Notes* entry_nn = old_nn->clone(C); entry_nn->set_jvms(jvms); diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 1637741176d..b2cd166b4dd 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ const char * const ParmNode::names[TypeFunc::Parms+1] = { #ifndef PRODUCT void ParmNode::dump_spec(outputStream *st) const { if( _con < TypeFunc::Parms ) { - st->print(names[_con]); + st->print("%s", names[_con]); } else { st->print("Parm%d: ",_con-TypeFunc::Parms); // Verbose and WizardMode dump bottom_type for all nodes @@ -348,19 +348,19 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c break; case Type::AryPtr: case Type::InstPtr: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->isa_oopptr()->const_oop())); break; case Type::KlassPtr: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_klassptr()->klass()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_klassptr()->klass())); break; case Type::MetadataPtr: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_metadataptr()->metadata()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_metadataptr()->metadata())); break; case Type::NarrowOop: - st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop()); + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_oopptr()->const_oop())); break; case Type::RawPtr: - st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr()); + st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,p2i(t->is_rawptr())); break; case Type::DoubleCon: st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d); @@ -369,7 +369,7 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f); break; case Type::Long: - st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con()); + st->print(" %s%d]=#"INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con())); break; case Type::Half: case Type::Top: @@ -428,7 +428,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) for (i = 0; i < (uint)scobjs.length(); i++) { // Scalar replaced objects. - st->print_cr(""); + st->cr(); st->print(" # ScObj" INT32_FORMAT " ", i); SafePointScalarObjectNode* spobj = scobjs.at(i); ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass(); @@ -485,7 +485,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) st->print(" }"); } } - st->print_cr(""); + st->cr(); if (caller() != NULL) caller()->format(regalloc, n, st); } @@ -981,7 +981,7 @@ uint CallRuntimeNode::cmp( const Node &n ) const { #ifndef PRODUCT void CallRuntimeNode::dump_spec(outputStream *st) const { st->print("# "); - st->print(_name); + st->print("%s", _name); CallNode::dump_spec(st); } #endif @@ -999,7 +999,7 @@ void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_reg #ifndef PRODUCT void CallLeafNode::dump_spec(outputStream *st) const { st->print("# "); - st->print(_name); + st->print("%s", _name); CallNode::dump_spec(st); } #endif diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index 24328546fec..f6e2065e26d 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2020,25 +2020,25 @@ void PhaseChaitin::dump() const { tty->print_cr("new LRG"); } } - tty->print_cr(""); + tty->cr(); // Dump lo-degree list tty->print("Lo degree: "); for(uint i3 = _lo_degree; i3; i3 = lrgs(i3)._next ) tty->print("L%d ",i3); - tty->print_cr(""); + tty->cr(); // Dump lo-stk-degree list tty->print("Lo stk degree: "); for(uint i4 = _lo_stk_degree; i4; i4 = lrgs(i4)._next ) tty->print("L%d ",i4); - tty->print_cr(""); + tty->cr(); // Dump lo-degree list tty->print("Hi degree: "); for(uint i5 = _hi_degree; i5; i5 = lrgs(i5)._next ) tty->print("L%d ",i5); - tty->print_cr(""); + tty->cr(); } void PhaseChaitin::dump_degree_lists() const { @@ -2046,26 +2046,26 @@ void PhaseChaitin::dump_degree_lists() const { tty->print("Lo degree: "); for( uint i = _lo_degree; i; i = lrgs(i)._next ) tty->print("L%d ",i); - tty->print_cr(""); + tty->cr(); // Dump lo-stk-degree list tty->print("Lo stk degree: "); for(uint i2 = _lo_stk_degree; i2; i2 = lrgs(i2)._next ) tty->print("L%d ",i2); - tty->print_cr(""); + tty->cr(); // Dump lo-degree list tty->print("Hi degree: "); for(uint i3 = _hi_degree; i3; i3 = lrgs(i3)._next ) tty->print("L%d ",i3); - tty->print_cr(""); + tty->cr(); } void PhaseChaitin::dump_simplified() const { tty->print("Simplified: "); for( uint i = _simplified; i; i = lrgs(i)._next ) tty->print("L%d ",i); - tty->print_cr(""); + tty->cr(); } static char *print_reg( OptoReg::Name reg, const PhaseChaitin *pc, char *buf ) { @@ -2144,7 +2144,7 @@ void PhaseChaitin::dump_frame() const { } tty->print(" : parm %d: ", k); domain->field_at(k + TypeFunc::Parms)->dump(); - tty->print_cr(""); + tty->cr(); } } @@ -2166,7 +2166,7 @@ void PhaseChaitin::dump_frame() const { _matcher._parm_regs[j].second() == reg ) { tty->print("parm %d: ",j); domain->field_at(j + TypeFunc::Parms)->dump(); - tty->print_cr(""); + tty->cr(); break; } } diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index f11b5b1f416..99194cfe925 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -26,7 +26,6 @@ #define SHARE_VM_OPTO_CHAITIN_HPP #include "code/vmreg.hpp" -#include "libadt/port.hpp" #include "memory/resourceArea.hpp" #include "opto/connode.hpp" #include "opto/live.hpp" @@ -142,7 +141,7 @@ public: // Number of registers this live range uses when it colors private: - uint8 _num_regs; // 2 for Longs and Doubles, 1 for all else + uint8_t _num_regs; // 2 for Longs and Doubles, 1 for all else // except _num_regs is kill count for fat_proj public: int num_regs() const { return _num_regs; } @@ -151,7 +150,7 @@ public: private: // Number of physical registers this live range uses when it colors // Architecture and register-set dependent - uint8 _reg_pressure; + uint8_t _reg_pressure; public: void set_reg_pressure(int i) { _reg_pressure = i; } int reg_pressure() const { return _reg_pressure; } diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 7226a725a7c..9c05d1da889 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -672,6 +672,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _print_inlining_list(NULL), _print_inlining_stream(NULL), _print_inlining_idx(0), + _print_inlining_output(NULL), _preserve_jvm_state(0), _interpreter_frame_size(0) { C = this; @@ -978,6 +979,7 @@ Compile::Compile( ciEnv* ci_env, _print_inlining_list(NULL), _print_inlining_stream(NULL), _print_inlining_idx(0), + _print_inlining_output(NULL), _preserve_jvm_state(0), _allowed_reasons(0), _interpreter_frame_size(0) { @@ -1089,6 +1091,7 @@ void Compile::Init(int aliaslevel) { set_do_scheduling(OptoScheduling); set_do_count_invocations(false); set_do_method_data_update(false); + set_age_code(has_method() && method()->profile_aging()); set_rtm_state(NoRTM); // No RTM lock eliding by default #if INCLUDE_RTM_OPT if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) { @@ -2206,7 +2209,7 @@ void Compile::Optimize() { } // (End scope of igvn; run destructor if necessary for asserts.) - dump_inlining(); + process_print_inlining(); // A method with only infinite loops has no edges entering loops from root { NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) @@ -2424,7 +2427,7 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { starts_bundle = ' '; tty->print("\t"); delay->format(_regalloc, tty); - tty->print_cr(""); + tty->cr(); delay = NULL; } @@ -2438,12 +2441,12 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { if (pcs && n->_idx < pc_limit) tty->print_cr("%3.3x", pcs[n->_idx]); else - tty->print_cr(""); + tty->cr(); assert(cut_short || delay == NULL, "no unconditional delay branch"); } // End of per-block dump - tty->print_cr(""); + tty->cr(); if (cut_short) tty->print_cr("*** disassembly is cut short ***"); } @@ -3688,7 +3691,8 @@ void Compile::ConstantTable::emit(CodeBuffer& cb) { default: ShouldNotReachHere(); } assert(constant_addr, "consts section too small"); - assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg_res("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); + assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), + err_msg_res("must be: %d == %d", (int) (constant_addr - _masm.code()->consts()->start()), (int)(con.offset()))); } } @@ -3768,7 +3772,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n for (uint i = 0; i < n->outcnt(); i++) { address* constant_addr = &jump_table_base[i]; - assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i))); + assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i))); *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); } @@ -3866,7 +3870,7 @@ void Compile::print_inlining_assert_ready() { assert(!_print_inlining || _print_inlining_stream->size() == 0, "loosing data"); } -void Compile::dump_inlining() { +void Compile::process_print_inlining() { bool do_print_inlining = print_inlining() || print_intrinsics(); if (do_print_inlining || log() != NULL) { // Print inlining message for candidates that we couldn't inline @@ -3883,9 +3887,21 @@ void Compile::dump_inlining() { } } if (do_print_inlining) { + ResourceMark rm; + stringStream ss; for (int i = 0; i < _print_inlining_list->length(); i++) { - tty->print(_print_inlining_list->adr_at(i)->ss()->as_string()); + ss.print("%s", _print_inlining_list->adr_at(i)->ss()->as_string()); } + size_t end = ss.size(); + _print_inlining_output = NEW_ARENA_ARRAY(comp_arena(), char, end+1); + strncpy(_print_inlining_output, ss.base(), end+1); + _print_inlining_output[end] = 0; + } +} + +void Compile::dump_print_inlining() { + if (_print_inlining_output != NULL) { + tty->print_raw(_print_inlining_output); } } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 3d561556881..36ff03906f1 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ #include "compiler/compilerOracle.hpp" #include "compiler/compileBroker.hpp" #include "libadt/dict.hpp" -#include "libadt/port.hpp" #include "libadt/vectset.hpp" #include "memory/resourceArea.hpp" #include "opto/idealGraphPrinter.hpp" @@ -311,6 +310,7 @@ class Compile : public Phase { bool _do_freq_based_layout; // True if we intend to do frequency based block layout bool _do_count_invocations; // True if we generate code to count invocations bool _do_method_data_update; // True if we generate code to update MethodData*s + bool _age_code; // True if we need to profile code age (decrement the aging counter) int _AliasLevel; // Locally-adjusted version of AliasLevel flag. bool _print_assembly; // True if we should dump assembly code for this compilation bool _print_inlining; // True if we should print inlining for this compilation @@ -420,6 +420,7 @@ class Compile : public Phase { stringStream* _print_inlining_stream; GrowableArray* _print_inlining_list; int _print_inlining_idx; + char* _print_inlining_output; // Only keep nodes in the expensive node list that need to be optimized void cleanup_expensive_nodes(PhaseIterGVN &igvn); @@ -459,7 +460,7 @@ class Compile : public Phase { void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) { stringStream ss; CompileTask::print_inlining(&ss, method, inline_level, bci, msg); - print_inlining_stream()->print(ss.as_string()); + print_inlining_stream()->print("%s", ss.as_string()); } void log_late_inline(CallGenerator* cg); @@ -584,7 +585,9 @@ class Compile : public Phase { void set_do_count_invocations(bool z){ _do_count_invocations = z; } bool do_method_data_update() const { return _do_method_data_update; } void set_do_method_data_update(bool z) { _do_method_data_update = z; } - int AliasLevel() const { return _AliasLevel; } + bool age_code() const { return _age_code; } + void set_age_code(bool z) { _age_code = z; } + int AliasLevel() const { return _AliasLevel; } bool print_assembly() const { return _print_assembly; } void set_print_assembly(bool z) { _print_assembly = z; } bool print_inlining() const { return _print_inlining; } @@ -915,7 +918,8 @@ class Compile : public Phase { void remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful); - void dump_inlining(); + void process_print_inlining(); + void dump_print_inlining(); bool over_inlining_cutoff() const { if (!inlining_incrementally()) { diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp index f577c8b5125..40bd21fbc4c 100644 --- a/hotspot/src/share/vm/opto/divnode.cpp +++ b/hotspot/src/share/vm/opto/divnode.cpp @@ -514,7 +514,7 @@ const Type *DivINode::Value( PhaseTransform *phase ) const { int widen = MAX2(i1->_widen, i2->_widen); if( i2->is_con() && i2->get_con() != 0 ) { - int32 d = i2->get_con(); // Divisor + int32_t d = i2->get_con(); // Divisor jint lo, hi; if( d >= 0 ) { lo = i1->_lo/d; @@ -536,7 +536,7 @@ const Type *DivINode::Value( PhaseTransform *phase ) const { // If the dividend is a constant if( i1->is_con() ) { - int32 d = i1->get_con(); + int32_t d = i1->get_con(); if( d < 0 ) { if( d == min_jint ) { // (-min_jint) == min_jint == (min_jint / -1) diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index d806d0acf22..2c48e604497 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMeth out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count); stringStream ss; prof_klass->name()->print_symbol_on(&ss); - out->print(ss.as_string()); + out->print("%s", ss.as_string()); out->cr(); } } @@ -364,7 +364,7 @@ bool Compile::should_delay_string_inlining(ciMethod* call_method, JVMState* jvms bool Compile::should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms) { if (eliminate_boxing() && call_method->is_boxing_method()) { set_has_boxed_value(true); - return true; + return aggressive_unboxing(); } return false; } diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp index a7fa0532763..0be96ad7f71 100644 --- a/hotspot/src/share/vm/opto/domgraph.cpp +++ b/hotspot/src/share/vm/opto/domgraph.cpp @@ -397,8 +397,9 @@ void PhaseIdealLoop::Dominators() { ntarjan[i]._control = NULL; // Store the DFS order for the main loop + const uint fill_value = max_juint; uint *dfsorder = NEW_RESOURCE_ARRAY(uint,C->unique()+1); - memset(dfsorder, max_uint, (C->unique()+1) * sizeof(uint)); + memset(dfsorder, fill_value, (C->unique()+1) * sizeof(uint)); // Tarjan's algorithm, almost verbatim: // Step 1: @@ -419,7 +420,7 @@ void PhaseIdealLoop::Dominators() { if( whead->in(j) == NULL || !whead->in(j)->is_CFG() ) continue; // Only process control nodes uint b = dfsorder[whead->in(j)->_idx]; - if(b == max_uint) continue; + if(b == fill_value) continue; NTarjan *vx = &ntarjan[b]; NTarjan *u = vx->EVAL(); if( u->_semi < w->_semi ) diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index fcfb3880e19..4aa770d5af5 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2014,7 +2014,7 @@ void CFGLoop::dump() const { tty->print("%s: %d trip_count: %6.0f freq: %6.0f\n", _depth == 0 ? "Method" : "Loop", _id, trip_count(), _freq); for (int i = 0; i < _depth; i++) tty->print(" "); - tty->print(" members:", _id); + tty->print(" members:"); int k = 0; for (int i = 0; i < _members.length(); i++) { if (k++ >= 6) { diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 851b70d3f8f..b222526c620 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,7 +155,7 @@ IdealGraphPrinter::IdealGraphPrinter() { } else { // It would be nice if we could shut down cleanly but it should // be an error if we can't connect to the visualizer. - fatal(err_msg_res("Couldn't connect to visualizer at %s:%d", + fatal(err_msg_res("Couldn't connect to visualizer at %s:" INTX_FORMAT, PrintIdealGraphAddress, PrintIdealGraphPort)); } } @@ -195,7 +195,7 @@ IdealGraphPrinter::~IdealGraphPrinter() { void IdealGraphPrinter::begin_elem(const char *s) { - _xml->begin_elem(s); + _xml->begin_elem("%s", s); } void IdealGraphPrinter::end_elem() { @@ -203,7 +203,7 @@ void IdealGraphPrinter::end_elem() { } void IdealGraphPrinter::begin_head(const char *s) { - _xml->begin_head(s); + _xml->begin_head("%s", s); } void IdealGraphPrinter::end_head() { @@ -223,7 +223,7 @@ void IdealGraphPrinter::print_attr(const char *name, const char *val) { } void IdealGraphPrinter::head(const char *name) { - _xml->head(name); + _xml->head("%s", name); } void IdealGraphPrinter::tail(const char *name) { @@ -231,7 +231,7 @@ void IdealGraphPrinter::tail(const char *name) { } void IdealGraphPrinter::text(const char *s) { - _xml->text(s); + _xml->text("%s", s); } void IdealGraphPrinter::print_prop(const char *name, int val) { @@ -359,7 +359,7 @@ void IdealGraphPrinter::end_method() { void IdealGraphPrinter::print_indent() { tty->print_cr("printing ident %d", _depth); for (int i = 0; i < _depth; i++) { - _xml->print(INDENT); + _xml->print("%s", INDENT); } } diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index 825a7a25533..59c407aaeeb 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -256,7 +256,7 @@ void PhaseIFG::stats() const { for( i = 0; i < _maxlrg*2; i++ ) if( h_cnt[i] ) tty->print("%d/%d ",i,h_cnt[i]); - tty->print_cr(""); + tty->cr(); } void PhaseIFG::verify( const PhaseChaitin *pc ) const { diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 1c9dbb70839..587c3b8c864 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -673,7 +673,7 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj // / Region // Node* IfNode::fold_compares(PhaseGVN* phase) { - if (!phase->C->eliminate_boxing() || Opcode() != Op_If) return NULL; + if (Opcode() != Op_If) return NULL; Node* this_cmp = in(1)->in(1); if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI && diff --git a/hotspot/src/share/vm/opto/indexSet.cpp b/hotspot/src/share/vm/opto/indexSet.cpp index 4ba99e72783..d2172d157b3 100644 --- a/hotspot/src/share/vm/opto/indexSet.cpp +++ b/hotspot/src/share/vm/opto/indexSet.cpp @@ -51,7 +51,7 @@ int IndexSet::_serial_count = 1; #endif // What is the first set bit in a 5 bit integer? -const byte IndexSetIterator::_first_bit[32] = { +const uint8_t IndexSetIterator::_first_bit[32] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, @@ -63,7 +63,7 @@ const byte IndexSetIterator::_first_bit[32] = { }; // What is the second set bit in a 5 bit integer? -const byte IndexSetIterator::_second_bit[32] = { +const uint8_t IndexSetIterator::_second_bit[32] = { 5, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, @@ -298,7 +298,7 @@ IndexSet::IndexSet (IndexSet *set) { set_block(i, &_empty_block); } else { BitBlock *new_block = alloc_block(); - memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block); + memcpy(new_block->words(), block->words(), sizeof(uint32_t) * words_per_block); set_block(i, new_block); } } diff --git a/hotspot/src/share/vm/opto/indexSet.hpp b/hotspot/src/share/vm/opto/indexSet.hpp index ef5aed18b67..366c9d5843b 100644 --- a/hotspot/src/share/vm/opto/indexSet.hpp +++ b/hotspot/src/share/vm/opto/indexSet.hpp @@ -106,12 +106,12 @@ class IndexSet : public ResourceObj { // is used by IndexSet to mainting this free list. union { - uint32 _words[words_per_block]; + uint32_t _words[words_per_block]; BitBlock *_next; } _data; // accessors - uint32 *words() { return _data._words; } + uint32_t* words() { return _data._words; } void set_next(BitBlock *next) { _data._next = next; } BitBlock *next() { return _data._next; } @@ -120,22 +120,22 @@ class IndexSet : public ResourceObj { // not assume that the block index has been masked out. void clear() { - memset(words(), 0, sizeof(uint32) * words_per_block); + memset(words(), 0, sizeof(uint32_t) * words_per_block); } bool member(uint element) { uint word_index = IndexSet::get_word_index(element); uint bit_index = IndexSet::get_bit_index(element); - return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0); + return ((words()[word_index] & (uint32_t)(0x1 << bit_index)) != 0); } bool insert(uint element) { uint word_index = IndexSet::get_word_index(element); uint bit_index = IndexSet::get_bit_index(element); - uint32 bit = (0x1 << bit_index); - uint32 before = words()[word_index]; + uint32_t bit = (0x1 << bit_index); + uint32_t before = words()[word_index]; words()[word_index] = before | bit; return ((before & bit) != 0); } @@ -144,8 +144,8 @@ class IndexSet : public ResourceObj { uint word_index = IndexSet::get_word_index(element); uint bit_index = IndexSet::get_bit_index(element); - uint32 bit = (0x1 << bit_index); - uint32 before = words()[word_index]; + uint32_t bit = (0x1 << bit_index); + uint32_t before = words()[word_index]; words()[word_index] = before & ~bit; return ((before & bit) != 0); } @@ -404,14 +404,14 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC { table_size = (1 << window_size) }; // For an integer of length window_size, what is the first set bit? - static const byte _first_bit[table_size]; + static const uint8_t _first_bit[table_size]; // For an integer of length window_size, what is the second set bit? - static const byte _second_bit[table_size]; + static const uint8_t _second_bit[table_size]; private: // The current word we are inspecting - uint32 _current; + uint32_t _current; // What element number are we currently on? uint _value; @@ -420,7 +420,7 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC { uint _next_word; // A pointer to the contents of the current block - uint32 *_words; + uint32_t *_words; // The index of the next block we will inspect uint _next_block; diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index bf2d365a9d3..5cf1188435a 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -420,7 +420,6 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { return NULL; case vmIntrinsics::_getCallerClass: - if (!UseNewReflection) return NULL; if (!InlineReflectionGetCallerClass) return NULL; if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL; break; diff --git a/hotspot/src/share/vm/opto/live.hpp b/hotspot/src/share/vm/opto/live.hpp index 343c5c6f727..9c779b2c2f0 100644 --- a/hotspot/src/share/vm/opto/live.hpp +++ b/hotspot/src/share/vm/opto/live.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_LIVE_HPP #define SHARE_VM_OPTO_LIVE_HPP -#include "libadt/port.hpp" #include "libadt/vectset.hpp" #include "opto/block.hpp" #include "opto/indexSet.hpp" diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp index 0e86e403473..aeb3ffad0d5 100644 --- a/hotspot/src/share/vm/opto/loopPredicate.cpp +++ b/hotspot/src/share/vm/opto/loopPredicate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -639,7 +639,7 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, if (TraceLoopPredicate) { predString->print_cr("print(predString->as_string()); + tty->print("%s", predString->as_string()); } return bol; } diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index 5436fd5f640..f11583a25b2 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3569,7 +3569,7 @@ void PhaseIdealLoop::build_loop_late_post( Node *n ) { #ifdef ASSERT void PhaseIdealLoop::dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA) { - tty->print_cr(msg); + tty->print_cr("%s", msg); tty->print("n: "); n->dump(); tty->print("early(n): "); early->dump(); if (n->in(0) != NULL && !n->in(0)->is_top() && diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index 59915ffed6f..5c962ae9981 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -339,11 +339,11 @@ public: Node_List _body; // Loop body for inner loops - uint8 _nest; // Nesting depth - uint8 _irreducible:1, // True if irreducible - _has_call:1, // True if has call safepoint - _has_sfpt:1, // True if has non-call safepoint - _rce_candidate:1; // True if candidate for range check elimination + uint8_t _nest; // Nesting depth + uint8_t _irreducible:1, // True if irreducible + _has_call:1, // True if has call safepoint + _has_sfpt:1, // True if has non-call safepoint + _rce_candidate:1; // True if candidate for range check elimination Node_List* _safepts; // List of safepoints in this loop Node_List* _required_safept; // A inner loop cannot delete these safepts; diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index 0e650639d0c..7cdf630e1dc 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2622,7 +2622,7 @@ void State::dump(int depth) { tty->print_cr("%s %d %s", ruleName[i], _cost[i], ruleName[_rule[i]] ); } - tty->print_cr(""); + tty->cr(); for( i=0; i<2; i++ ) if( _kids[i] ) diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 24b7c909923..1d908c5b577 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3981,7 +3981,7 @@ bool InitializeNode::stores_are_sane(PhaseTransform* phase) { intptr_t st_off = get_store_offset(st, phase); if (st_off < 0) continue; // ignore dead garbage if (last_off > st_off) { - tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off); + tty->print_cr("*** bad store offset at %d: " INTX_FORMAT " > " INTX_FORMAT, i, last_off, st_off); this->dump(2); assert(false, "ascending store offsets"); return false; diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp index 861149afca5..056d8c5043a 100644 --- a/hotspot/src/share/vm/opto/mulnode.cpp +++ b/hotspot/src/share/vm/opto/mulnode.cpp @@ -235,23 +235,23 @@ const Type *MulINode::mul_ring(const Type *t0, const Type *t1) const { const TypeInt *r1 = t1->is_int(); // Fetch endpoints of all ranges - int32 lo0 = r0->_lo; + int32_t lo0 = r0->_lo; double a = (double)lo0; - int32 hi0 = r0->_hi; + int32_t hi0 = r0->_hi; double b = (double)hi0; - int32 lo1 = r1->_lo; + int32_t lo1 = r1->_lo; double c = (double)lo1; - int32 hi1 = r1->_hi; + int32_t hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow - int32 A = lo0*lo1; + int32_t A = lo0*lo1; if( (double)A != a*c ) return TypeInt::INT; // Overflow? - int32 B = lo0*hi1; + int32_t B = lo0*hi1; if( (double)B != a*d ) return TypeInt::INT; // Overflow? - int32 C = hi0*lo1; + int32_t C = hi0*lo1; if( (double)C != b*c ) return TypeInt::INT; // Overflow? - int32 D = hi0*hi1; + int32_t D = hi0*hi1; if( (double)D != b*d ) return TypeInt::INT; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints @@ -1228,12 +1228,12 @@ const Type *URShiftINode::Value( PhaseTransform *phase ) const { // // const TypeInstPtr *o = t1->is_instptr(); // if( t1->singleton() ) - // return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift ); + // return TypeInt::make( ((uint32_t)o->const_oop() + o->_offset) >> shift ); // } // else if( t1->base() == Type::KlassPtr ) { // const TypeKlassPtr *o = t1->is_klassptr(); // if( t1->singleton() ) - // return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift ); + // return TypeInt::make( ((uint32_t)o->const_oop() + o->_offset) >> shift ); // } return TypeInt::INT; diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index 2064b07f451..cec7f0d517b 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1688,7 +1688,7 @@ void Node::dump(const char* suffix, outputStream *st) const { } } } - if (suffix) st->print(suffix); + if (suffix) st->print("%s", suffix); C->_in_dump_cnt--; } diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 0b51d04875d..67db16f154b 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_NODE_HPP #define SHARE_VM_OPTO_NODE_HPP -#include "libadt/port.hpp" #include "libadt/vectset.hpp" #include "opto/compile.hpp" #include "opto/type.hpp" diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index ede7534642d..d47912f208c 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -366,8 +366,8 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size // third inserts nops where needed. // Step one, perform a pessimistic sizing pass. - uint last_call_adr = max_uint; - uint last_avoid_back_to_back_adr = max_uint; + uint last_call_adr = max_juint; + uint last_avoid_back_to_back_adr = max_juint; uint nop_size = (new (this) MachNopNode())->size(_regalloc); for (uint i = 0; i < nblocks; i++) { // For all blocks Block* block = _cfg->get_block(i); @@ -479,7 +479,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size // Step two, replace eligible long jumps. bool progress = true; - uint last_may_be_short_branch_adr = max_uint; + uint last_may_be_short_branch_adr = max_juint; while (has_short_branch_candidate && progress) { progress = false; has_short_branch_candidate = false; diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index aae634a9563..e810c9d4d58 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -581,6 +581,7 @@ class Parse : public GraphKit { void jump_switch_ranges(Node* a, SwitchRange* lo, SwitchRange* hi, int depth = 0); bool create_jump_tables(Node* a, SwitchRange* lo, SwitchRange* hi); + void decrement_age(); // helper functions for methodData style profiling void test_counter_against_threshold(Node* cnt, int limit); void increment_and_test_invocation_counter(int limit); diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index 9d7bef8edbd..6fea7130786 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -568,6 +568,9 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Pars } else { set_map(entry_map); do_method_entry(); + if (depth() == 1 && C->age_code()) { + decrement_age(); + } } if (depth() == 1) { // Add check to deoptimize the nmethod if RTM state was changed @@ -611,7 +614,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Pars set_map(entry_map); do_exits(); - if (log) log->done("parse nodes='%d' live='%d' memory='%d'", + if (log) log->done("parse nodes='%d' live='%d' memory='" SIZE_FORMAT "'", C->unique(), C->live_nodes(), C->node_arena()->used()); } @@ -1395,7 +1398,7 @@ void Parse::do_one_block() { tty->print((( i < ns) ? " %d" : " %d(e)"), b->successor_at(i)->rpo()); } if (b->is_loop_head()) tty->print(" lphd"); - tty->print_cr(""); + tty->cr(); } assert(block()->is_merged(), "must be merged before being parsed"); @@ -2048,6 +2051,31 @@ void Parse::rtm_deopt() { #endif } +void Parse::decrement_age() { + MethodCounters* mc = method()->ensure_method_counters(); + if (mc == NULL) { + C->record_failure("Must have MCs"); + return; + } + assert(!is_osr_parse(), "Not doing this for OSRs"); + + // Set starting bci for uncommon trap. + set_parse_bci(0); + + const TypePtr* adr_type = TypeRawPtr::make((address)mc); + Node* mc_adr = makecon(adr_type); + Node* cnt_adr = basic_plus_adr(mc_adr, mc_adr, in_bytes(MethodCounters::nmethod_age_offset())); + Node* cnt = make_load(control(), cnt_adr, TypeInt::INT, T_INT, adr_type, MemNode::unordered); + Node* decr = _gvn.transform(new (C) SubINode(cnt, makecon(TypeInt::ONE))); + store_to_memory(control(), cnt_adr, decr, T_INT, adr_type, MemNode::unordered); + Node *chk = _gvn.transform(new (C) CmpINode(decr, makecon(TypeInt::ZERO))); + Node* tst = _gvn.transform(new (C) BoolNode(chk, BoolTest::gt)); + { BuildCutout unless(this, tst, PROB_ALWAYS); + uncommon_trap(Deoptimization::Reason_tenured, + Deoptimization::Action_make_not_entrant); + } +} + //------------------------------return_current--------------------------------- // Append current _map to _exit_return void Parse::return_current(Node* value) { diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index cce96328b9b..1f085a0223b 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -405,9 +405,9 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) bool needs_guard = false; int default_dest; - int64 total_outlier_size = 0; - int64 hi_size = ((int64)hi->hi()) - ((int64)hi->lo()) + 1; - int64 lo_size = ((int64)lo->hi()) - ((int64)lo->lo()) + 1; + int64_t total_outlier_size = 0; + int64_t hi_size = ((int64_t)hi->hi()) - ((int64_t)hi->lo()) + 1; + int64_t lo_size = ((int64_t)lo->hi()) - ((int64_t)lo->lo()) + 1; if (lo->dest() == hi->dest()) { total_outlier_size = hi_size + lo_size; @@ -429,7 +429,7 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) } // Find the total number of cases and ranges - int64 num_cases = ((int64)hi->hi()) - ((int64)lo->lo()) + 1; + int64_t num_cases = ((int64_t)hi->hi()) - ((int64_t)lo->lo()) + 1; int num_range = hi - lo + 1; // Don't create table if: too large, too small, or too sparse. @@ -473,7 +473,7 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) // These are the switch destinations hanging off the jumpnode int i = 0; for (SwitchRange* r = lo; r <= hi; r++) { - for (int64 j = r->lo(); j <= r->hi(); j++, i++) { + for (int64_t j = r->lo(); j <= r->hi(); j++, i++) { Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval))); { PreserveJVMState pjvms(this); @@ -628,7 +628,7 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, _method->print_short_name(); tty->print_cr(" switch decision tree"); tty->print_cr(" %d ranges (%d singletons), max_depth=%d, est_depth=%d", - hi-lo+1, nsing, _max_switch_depth, _est_switch_depth); + (int) (hi-lo+1), nsing, _max_switch_depth, _est_switch_depth); if (_max_switch_depth > _est_switch_depth) { tty->print_cr("******** BAD SWITCH DEPTH ********"); } @@ -636,7 +636,7 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, for( r = lo; r <= hi; r++ ) { r->print(); } - tty->print_cr(""); + tty->cr(); } #endif } diff --git a/hotspot/src/share/vm/opto/phase.hpp b/hotspot/src/share/vm/opto/phase.hpp index 08e9575640e..b06e3470df4 100644 --- a/hotspot/src/share/vm/opto/phase.hpp +++ b/hotspot/src/share/vm/opto/phase.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_PHASE_HPP #define SHARE_VM_OPTO_PHASE_HPP -#include "libadt/port.hpp" #include "runtime/timer.hpp" class Compile; diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 276fafcdbb5..4635342e678 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -958,10 +958,10 @@ void PhaseIterGVN::verify_PhaseIterGVN() { if (VerifyIterativeGVN && PrintOpto) { if (_verify_counter == _verify_full_passes) { tty->print_cr("VerifyIterativeGVN: %d transforms and verify passes", - _verify_full_passes); + (int) _verify_full_passes); } else { tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes", - _verify_counter, _verify_full_passes); + (int) _verify_counter, (int) _verify_full_passes); } } } @@ -1393,6 +1393,15 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) { _worklist.push(u); } } + // If changed AddI/SubI inputs, check CmpU for range check optimization. + if (use_op == Op_AddI || use_op == Op_SubI) { + for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { + Node* u = use->fast_out(i2); + if (u->is_Cmp() && (u->Opcode() == Op_CmpU)) { + _worklist.push(u); + } + } + } // If changed AddP inputs, check Stores for loop invariant if( use_op == Op_AddP ) { for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { diff --git a/hotspot/src/share/vm/opto/regmask.cpp b/hotspot/src/share/vm/opto/regmask.cpp index 07fddd151c3..a30678dadf2 100644 --- a/hotspot/src/share/vm/opto/regmask.cpp +++ b/hotspot/src/share/vm/opto/regmask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ //-------------Non-zero bit search methods used by RegMask--------------------- // Find lowest 1, or return 32 if empty -int find_lowest_bit( uint32 mask ) { +int find_lowest_bit( uint32_t mask ) { int n = 0; if( (mask & 0xffff) == 0 ) { mask >>= 16; @@ -80,7 +80,7 @@ int find_lowest_bit( uint32 mask ) { } // Find highest 1, or return 32 if empty -int find_hihghest_bit( uint32 mask ) { +int find_hihghest_bit( uint32_t mask ) { int n = 0; if( mask > 0xffff ) { mask >>= 16; @@ -116,7 +116,7 @@ void OptoReg::dump(int r, outputStream *st) { case Special: st->print("r---"); break; case Bad: st->print("rBAD"); break; default: - if (r < _last_Mach_Reg) st->print(Matcher::regName[r]); + if (r < _last_Mach_Reg) st->print("%s", Matcher::regName[r]); else st->print("rS%d",r); break; } @@ -395,7 +395,7 @@ bool RegMask::is_UP() const { //------------------------------Size------------------------------------------- // Compute size of register mask in bits uint RegMask::Size() const { - extern uint8 bitsInByte[256]; + extern uint8_t bitsInByte[256]; uint sum = 0; for( int i = 0; i < RM_SIZE; i++ ) sum += diff --git a/hotspot/src/share/vm/opto/regmask.hpp b/hotspot/src/share/vm/opto/regmask.hpp index 2ea6dfffdd3..ff0d0b96dc2 100644 --- a/hotspot/src/share/vm/opto/regmask.hpp +++ b/hotspot/src/share/vm/opto/regmask.hpp @@ -26,7 +26,6 @@ #define SHARE_VM_OPTO_REGMASK_HPP #include "code/vmreg.hpp" -#include "libadt/port.hpp" #include "opto/optoreg.hpp" #ifdef TARGET_ARCH_MODEL_x86_32 # include "adfiles/adGlobals_x86_32.hpp" @@ -68,9 +67,9 @@ //-------------Non-zero bit search methods used by RegMask--------------------- // Find lowest 1, or return 32 if empty -int find_lowest_bit( uint32 mask ); +int find_lowest_bit( uint32_t mask ); // Find highest 1, or return 32 if empty -int find_hihghest_bit( uint32 mask ); +int find_hihghest_bit( uint32_t mask ); //------------------------------RegMask---------------------------------------- // The ADL file describes how to print the machine-specific registers, as well diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index cabf1675735..1beaac7fd38 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -960,7 +960,7 @@ JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* r } else { // Receiver did not match any saved receiver and there is no empty row for it. // Increment total counter to indicate polymorphic case. - intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset())); + intptr_t* count_p = (intptr_t*)(((uint8_t*)(data)) + in_bytes(CounterData::count_offset())); *count_p += DataLayout::counter_increment; } JRT_END @@ -1393,7 +1393,7 @@ static void trace_exception(oop exception_oop, address exception_pc, const char* } else { tty->print(""); } - tty->print(" at " INTPTR_FORMAT, exception_pc); + tty->print(" at " INTPTR_FORMAT, p2i(exception_pc)); tty->print_cr("]"); } diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 469d4141e32..ae41bee47ae 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ Node *SubNode::Identity( PhaseTransform *phase ) { //------------------------------Value------------------------------------------ // A subtract node differences it's two inputs. -const Type *SubNode::Value( PhaseTransform *phase ) const { +const Type* SubNode::Value_common(PhaseTransform *phase) const { const Node* in1 = in(1); const Node* in2 = in(2); // Either input is TOP ==> the result is TOP @@ -97,6 +97,16 @@ const Type *SubNode::Value( PhaseTransform *phase ) const { if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) return bottom_type(); + return NULL; +} + +const Type* SubNode::Value(PhaseTransform *phase) const { + const Type* t = Value_common(phase); + if (t != NULL) { + return t; + } + const Type* t1 = phase->type(in(1)); + const Type* t2 = phase->type(in(2)); return sub(t1,t2); // Local flavor of type subtraction } @@ -242,8 +252,8 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ const Type *SubINode::sub( const Type *t1, const Type *t2 ) const { const TypeInt *r0 = t1->is_int(); // Handy access const TypeInt *r1 = t2->is_int(); - int32 lo = r0->_lo - r1->_hi; - int32 hi = r0->_hi - r1->_lo; + int32_t lo = r0->_lo - r1->_hi; + int32_t hi = r0->_hi - r1->_lo; // We next check for 32-bit overflow. // If that happens, we just assume all integers are possible. @@ -570,6 +580,81 @@ const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const { return TypeInt::CC; // else use worst case results } +const Type* CmpUNode::Value(PhaseTransform *phase) const { + const Type* t = SubNode::Value_common(phase); + if (t != NULL) { + return t; + } + const Node* in1 = in(1); + const Node* in2 = in(2); + const Type* t1 = phase->type(in1); + const Type* t2 = phase->type(in2); + assert(t1->isa_int(), "CmpU has only Int type inputs"); + if (t2 == TypeInt::INT) { // Compare to bottom? + return bottom_type(); + } + uint in1_op = in1->Opcode(); + if (in1_op == Op_AddI || in1_op == Op_SubI) { + // The problem rise when result of AddI(SubI) may overflow + // signed integer value. Let say the input type is + // [256, maxint] then +128 will create 2 ranges due to + // overflow: [minint, minint+127] and [384, maxint]. + // But C2 type system keep only 1 type range and as result + // it use general [minint, maxint] for this case which we + // can't optimize. + // + // Make 2 separate type ranges based on types of AddI(SubI) inputs + // and compare results of their compare. If results are the same + // CmpU node can be optimized. + const Node* in11 = in1->in(1); + const Node* in12 = in1->in(2); + const Type* t11 = (in11 == in1) ? Type::TOP : phase->type(in11); + const Type* t12 = (in12 == in1) ? Type::TOP : phase->type(in12); + // Skip cases when input types are top or bottom. + if ((t11 != Type::TOP) && (t11 != TypeInt::INT) && + (t12 != Type::TOP) && (t12 != TypeInt::INT)) { + const TypeInt *r0 = t11->is_int(); + const TypeInt *r1 = t12->is_int(); + jlong lo_r0 = r0->_lo; + jlong hi_r0 = r0->_hi; + jlong lo_r1 = r1->_lo; + jlong hi_r1 = r1->_hi; + if (in1_op == Op_SubI) { + jlong tmp = hi_r1; + hi_r1 = -lo_r1; + lo_r1 = -tmp; + // Note, for substructing [minint,x] type range + // long arithmetic provides correct overflow answer. + // The confusion come from the fact that in 32-bit + // -minint == minint but in 64-bit -minint == maxint+1. + } + jlong lo_long = lo_r0 + lo_r1; + jlong hi_long = hi_r0 + hi_r1; + int lo_tr1 = min_jint; + int hi_tr1 = (int)hi_long; + int lo_tr2 = (int)lo_long; + int hi_tr2 = max_jint; + bool underflow = lo_long != (jlong)lo_tr2; + bool overflow = hi_long != (jlong)hi_tr1; + // Use sub(t1, t2) when there is no overflow (one type range) + // or when both overflow and underflow (too complex). + if ((underflow != overflow) && (hi_tr1 < lo_tr2)) { + // Overflow only on one boundary, compare 2 separate type ranges. + int w = MAX2(r0->_widen, r1->_widen); // _widen does not matter here + const TypeInt* tr1 = TypeInt::make(lo_tr1, hi_tr1, w); + const TypeInt* tr2 = TypeInt::make(lo_tr2, hi_tr2, w); + const Type* cmp1 = sub(tr1, t2); + const Type* cmp2 = sub(tr2, t2); + if (cmp1 == cmp2) { + return cmp1; // Hit! + } + } + } + } + + return sub(t1, t2); // Local flavor of type subtraction +} + bool CmpUNode::is_index_range_check() const { // Check for the "(X ModI Y) CmpU Y" shape return (in(1)->Opcode() == Op_ModI && @@ -1065,7 +1150,7 @@ const Type *BoolTest::cc2logical( const Type *CC ) const { #ifndef PRODUCT void BoolTest::dump_on(outputStream *st) const { const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"}; - st->print(msg[_test]); + st->print("%s", msg[_test]); } #endif diff --git a/hotspot/src/share/vm/opto/subnode.hpp b/hotspot/src/share/vm/opto/subnode.hpp index 56ee308d982..da5d7e378cd 100644 --- a/hotspot/src/share/vm/opto/subnode.hpp +++ b/hotspot/src/share/vm/opto/subnode.hpp @@ -50,6 +50,7 @@ public: // Compute a new Type for this node. Basically we just do the pre-check, // then call the virtual add() to set the type. virtual const Type *Value( PhaseTransform *phase ) const; + const Type* Value_common( PhaseTransform *phase ) const; // Supplied function returns the subtractend of the inputs. // This also type-checks the inputs for sanity. Guaranteed never to @@ -158,6 +159,7 @@ public: CmpUNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} virtual int Opcode() const; virtual const Type *sub( const Type *, const Type * ) const; + const Type *Value( PhaseTransform *phase ) const; bool is_index_range_check() const; }; diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index 0f011e04864..39662643ac9 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ #include "opto/opcodes.hpp" #include "opto/type.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Portions of code courtesy of Clifford Click // Optimization - Graph Style @@ -842,7 +844,7 @@ bool Type::has_memory() const { #ifndef PRODUCT //------------------------------dump2------------------------------------------ void Type::dump2( Dict &d, uint depth, outputStream *st ) const { - st->print(_type_info[_base].msg); + st->print("%s", _type_info[_base].msg); } //------------------------------dump------------------------------------------- diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 071c12bf0b6..e4340df4f9a 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OPTO_TYPE_HPP #define SHARE_VM_OPTO_TYPE_HPP -#include "libadt/port.hpp" #include "opto/adlcVMDeps.hpp" #include "runtime/handles.hpp" diff --git a/hotspot/src/share/vm/precompiled/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp index daa60c586aa..e8d014430df 100644 --- a/hotspot/src/share/vm/precompiled/precompiled.hpp +++ b/hotspot/src/share/vm/precompiled/precompiled.hpp @@ -199,6 +199,7 @@ # include "runtime/perfData.hpp" # include "runtime/perfMemory.hpp" # include "runtime/prefetch.hpp" +# include "runtime/prefetch.inline.hpp" # include "runtime/reflection.hpp" # include "runtime/reflectionUtils.hpp" # include "runtime/registerMap.hpp" @@ -247,7 +248,6 @@ # include "utilities/yieldingWorkgroup.hpp" #ifdef COMPILER2 # include "libadt/dict.hpp" -# include "libadt/port.hpp" # include "libadt/set.hpp" # include "libadt/vectset.hpp" # include "opto/addnode.hpp" diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 53215062573..6bbe5feb691 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -275,7 +275,7 @@ const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K; class JNITraceWrapper : public StackObj { public: - JNITraceWrapper(const char* format, ...) { + JNITraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { if (TraceJNICalls) { va_list ap; va_start(ap, format); @@ -544,7 +544,7 @@ JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID meth if (m->is_initializer()) { reflection_method = Reflection::new_constructor(m, CHECK_NULL); } else { - reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL); + reflection_method = Reflection::new_method(m, false, CHECK_NULL); } ret = JNIHandles::make_local(env, reflection_method); return ret; @@ -2272,7 +2272,7 @@ JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldI found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd); } assert(found, "bad fieldID passed into jni_ToReflectedField"); - oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); + oop reflected = Reflection::new_field(&fd, CHECK_NULL); ret = JNIHandles::make_local(env, reflected); return ret; JNI_END diff --git a/hotspot/src/share/vm/prims/jniCheck.cpp b/hotspot/src/share/vm/prims/jniCheck.cpp index 7937090cc27..0d5ffab1cdc 100644 --- a/hotspot/src/share/vm/prims/jniCheck.cpp +++ b/hotspot/src/share/vm/prims/jniCheck.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,7 +100,7 @@ extern "C" { \ result_type JNICALL header { \ JavaThread* thr = (JavaThread*)ThreadLocalStorage::get_thread_slow();\ if (thr == NULL || !thr->is_Java_thread()) { \ - tty->print_cr(fatal_using_jnienv_in_nonjava); \ + tty->print_cr("%s", fatal_using_jnienv_in_nonjava); \ os::abort(true); \ } \ JNIEnv* xenv = thr->jni_environment(); \ @@ -184,7 +184,7 @@ static inline void functionEnter(JavaThread* thr) { if (thr->in_critical()) { - tty->print_cr(warn_other_function_in_critical); + tty->print_cr("%s", warn_other_function_in_critical); } if (thr->has_pending_exception()) { NativeReportJNIWarning(thr, "JNI call made with exception pending"); @@ -195,7 +195,7 @@ static inline void functionEnterExceptionAllowed(JavaThread* thr) { if (thr->in_critical()) { - tty->print_cr(warn_other_function_in_critical); + tty->print_cr("%s", warn_other_function_in_critical); } } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index cc6ec977fdf..5b96377b24a 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -26,7 +26,7 @@ #include "classfile/classLoader.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "gc_interface/collectedHeap.inline.hpp" @@ -215,7 +215,7 @@ void trace_class_resolution(Klass* to_class) { #ifdef ASSERT class JVMTraceWrapper : public StackObj { public: - JVMTraceWrapper(const char* format, ...) { + JVMTraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { if (TraceJVMCalls) { va_list ap; va_start(ap, format); @@ -1854,7 +1854,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, if (!publicOnly || fs.access_flags().is_public()) { fd.reinitialize(k(), fs.index()); - oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); + oop field = Reflection::new_field(&fd, CHECK_NULL); result->obj_at_put(out_idx, field); ++out_idx; } @@ -1932,7 +1932,7 @@ static jobjectArray get_class_declared_methods_helper( if (want_constructor) { m = Reflection::new_constructor(method, CHECK_NULL); } else { - m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); + m = Reflection::new_method(method, false, CHECK_NULL); } result->obj_at_put(i, m); } @@ -2055,7 +2055,7 @@ static jobject get_method_at_helper(constantPoolHandle cp, jint index, bool forc } oop method; if (!m->is_initializer() || m->is_static()) { - method = Reflection::new_method(m, true, true, CHECK_NULL); + method = Reflection::new_method(m, true, CHECK_NULL); } else { method = Reflection::new_constructor(m, CHECK_NULL); } @@ -2105,7 +2105,7 @@ static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force if (target_klass == NULL) { THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class"); } - oop field = Reflection::new_field(&fd, true, CHECK_NULL); + oop field = Reflection::new_field(&fd, CHECK_NULL); return JNIHandles::make_local(field); } @@ -2736,14 +2736,14 @@ JVM_END JVM_LEAF(jlong, JVM_Lseek(jint fd, jlong offset, jint whence)) - JVMWrapper4("JVM_Lseek (0x%x, %Ld, %d)", fd, offset, whence); + JVMWrapper4("JVM_Lseek (0x%x, " INT64_FORMAT ", %d)", fd, (int64_t) offset, whence); //%note jvm_r6 return os::lseek(fd, offset, whence); JVM_END JVM_LEAF(jint, JVM_SetLength(jint fd, jlong length)) - JVMWrapper3("JVM_SetLength (0x%x, %Ld)", fd, length); + JVMWrapper3("JVM_SetLength (0x%x, " INT64_FORMAT ")", fd, (int64_t) length); return os::ftruncate(fd, length); JVM_END @@ -2758,13 +2758,14 @@ JVM_END // Printing support ////////////////////////////////////////////////// extern "C" { +ATTRIBUTE_PRINTF(3, 0) int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { // see bug 4399518, 4417214 if ((intptr_t)count <= 0) return -1; return vsnprintf(str, count, fmt, args); } - +ATTRIBUTE_PRINTF(3, 0) int jio_snprintf(char *str, size_t count, const char *fmt, ...) { va_list args; int len; @@ -2774,7 +2775,7 @@ int jio_snprintf(char *str, size_t count, const char *fmt, ...) { return len; } - +ATTRIBUTE_PRINTF(2,3) int jio_fprintf(FILE* f, const char *fmt, ...) { int len; va_list args; @@ -2784,7 +2785,7 @@ int jio_fprintf(FILE* f, const char *fmt, ...) { return len; } - +ATTRIBUTE_PRINTF(2, 0) int jio_vfprintf(FILE* f, const char *fmt, va_list args) { if (Arguments::vfprintf_hook() != NULL) { return Arguments::vfprintf_hook()(f, fmt, args); @@ -2793,7 +2794,7 @@ int jio_vfprintf(FILE* f, const char *fmt, va_list args) { } } - +ATTRIBUTE_PRINTF(1, 2) JNIEXPORT int jio_printf(const char *fmt, ...) { int len; va_list args; @@ -2930,7 +2931,7 @@ JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) JavaThread* receiver = java_lang_Thread::thread(java_thread); Events::log_exception(JavaThread::current(), "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", - receiver, (address)java_thread, throwable); + p2i(receiver), p2i((address)java_thread), p2i(throwable)); // First check if thread is alive if (receiver != NULL) { // Check if exception is getting thrown at self (use oop equality, since the @@ -3520,7 +3521,6 @@ JVM_END JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - // UseNewReflection vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection oop loader = vfst.method()->method_holder()->class_loader(); if (loader != NULL) { diff --git a/hotspot/src/share/vm/prims/jvmtiEnter.xsl b/hotspot/src/share/vm/prims/jvmtiEnter.xsl index ff609eee2f9..e855d21dd81 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl +++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl @@ -1,6 +1,6 @@ " INTPTR_FORMAT, first->top_method()->code()); + if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, p2i(first->top_method()->code())); } else { if (TimeCompilationPolicy) accumulated_time()->start(); GrowableArray* stack = new GrowableArray(50); @@ -640,7 +644,7 @@ RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray* stack if (TraceCompilationPolicy && Verbose) { tty->print("\n\t check caller: "); next_m->print_short_name(tty); - tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)next_m(), next_m->code_size()); + tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", p2i((address)next_m()), next_m->code_size()); } current = next; diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 75e68590b2e..e4b1292c6b6 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,6 +89,8 @@ #endif #endif // COMPILER2 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + bool DeoptimizationMarker::_is_active = false; Deoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame, @@ -742,6 +744,8 @@ int Deoptimization::deoptimize_dependents() { return 0; } +Deoptimization::DeoptAction Deoptimization::_unloaded_action + = Deoptimization::Action_reinterpret; #ifdef COMPILER2 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS) { @@ -1183,6 +1187,23 @@ JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int by } JRT_END +MethodData* +Deoptimization::get_method_data(JavaThread* thread, methodHandle m, + bool create_if_missing) { + Thread* THREAD = thread; + MethodData* mdo = m()->method_data(); + if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { + // Build an MDO. Ignore errors like OutOfMemory; + // that simply means we won't have an MDO to update. + Method::build_interpreter_method_data(m, THREAD); + if (HAS_PENDING_EXCEPTION) { + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); + CLEAR_PENDING_EXCEPTION; + } + mdo = m()->method_data(); + } + return mdo; +} #if defined(COMPILER2) || defined(SHARK) void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { @@ -1283,7 +1304,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra // Ensure that we can record deopt. history: // Need MDO to record RTM code generation state. - bool create_if_missing = ProfileTraps RTM_OPT_ONLY( || UseRTMLocking ); + bool create_if_missing = ProfileTraps || UseCodeAging RTM_OPT_ONLY( || UseRTMLocking ); MethodData* trap_mdo = get_method_data(thread, trap_method, create_if_missing); @@ -1319,7 +1340,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra if (xtty != NULL) xtty->name(class_name); } - if (xtty != NULL && trap_mdo != NULL) { + if (xtty != NULL && trap_mdo != NULL && (int)reason < (int)MethodData::_trap_hist_limit) { // Dump the relevant MDO state. // This is the deopt count for the current reason, any previous // reasons or recompiles seen at this point. @@ -1419,7 +1440,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra // // The other actions cause immediate removal of the present code. - bool update_trap_state = true; + bool update_trap_state = (reason != Reason_tenured); bool make_not_entrant = false; bool make_not_compilable = false; bool reprofile = false; @@ -1546,7 +1567,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) { reprofile = true; } - } // Take requested actions on the method: @@ -1575,6 +1595,11 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra trap_mdo->atomic_set_rtm_state(ProfileRTM); } #endif + // For code aging we count traps separately here, using make_not_entrant() + // as a guard against simultaneous deopts in multiple threads. + if (reason == Reason_tenured && trap_mdo != NULL) { + trap_mdo->inc_tenure_traps(); + } } if (inc_recompile_count) { @@ -1607,24 +1632,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra } JRT_END -MethodData* -Deoptimization::get_method_data(JavaThread* thread, methodHandle m, - bool create_if_missing) { - Thread* THREAD = thread; - MethodData* mdo = m()->method_data(); - if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { - // Build an MDO. Ignore errors like OutOfMemory; - // that simply means we won't have an MDO to update. - Method::build_interpreter_method_data(m, THREAD); - if (HAS_PENDING_EXCEPTION) { - assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); - CLEAR_PENDING_EXCEPTION; - } - mdo = m()->method_data(); - } - return mdo; -} - ProfileData* Deoptimization::query_update_method_data(MethodData* trap_mdo, int trap_bci, @@ -1811,9 +1818,7 @@ const char* Deoptimization::format_trap_state(char* buf, size_t buflen, //--------------------------------statics-------------------------------------- -Deoptimization::DeoptAction Deoptimization::_unloaded_action - = Deoptimization::Action_reinterpret; -const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { +const char* Deoptimization::_trap_reason_name[] = { // Note: Keep this in sync. with enum DeoptReason. "none", "null_check", @@ -1834,9 +1839,10 @@ const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { "loop_limit_check", "speculate_class_check", "speculate_null_check", - "rtm_state_change" + "rtm_state_change", + "tenured" }; -const char* Deoptimization::_trap_action_name[Action_LIMIT] = { +const char* Deoptimization::_trap_action_name[] = { // Note: Keep this in sync. with enum DeoptAction. "none", "maybe_recompile", @@ -1846,6 +1852,9 @@ const char* Deoptimization::_trap_action_name[Action_LIMIT] = { }; const char* Deoptimization::trap_reason_name(int reason) { + // Check that every reason has a name + STATIC_ASSERT(sizeof(_trap_reason_name)/sizeof(const char*) == Reason_LIMIT); + if (reason == Reason_many) return "many"; if ((uint)reason < Reason_LIMIT) return _trap_reason_name[reason]; @@ -1854,6 +1863,9 @@ const char* Deoptimization::trap_reason_name(int reason) { return buf; } const char* Deoptimization::trap_action_name(int action) { + // Check that every action has a name + STATIC_ASSERT(sizeof(_trap_action_name)/sizeof(const char*) == Action_LIMIT); + if ((uint)action < Action_LIMIT) return _trap_action_name[action]; static char buf[20]; diff --git a/hotspot/src/share/vm/runtime/deoptimization.hpp b/hotspot/src/share/vm/runtime/deoptimization.hpp index eb8e2cbdede..02daabccb98 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.hpp +++ b/hotspot/src/share/vm/runtime/deoptimization.hpp @@ -62,6 +62,7 @@ class Deoptimization : AllStatic { Reason_speculate_class_check, // saw unexpected object class from type speculation Reason_speculate_null_check, // saw unexpected null from type speculation Reason_rtm_state_change, // rtm state change detected + Reason_tenured, // age of the code has reached the limit Reason_LIMIT, // Note: Keep this enum in sync. with _trap_reason_name. Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc @@ -357,8 +358,8 @@ class Deoptimization : AllStatic { // returning to a deoptimized caller static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address); - private: static MethodData* get_method_data(JavaThread* thread, methodHandle m, bool create_if_missing); + private: // Update the mdo's count and per-BCI reason bits, returning previous state: static ProfileData* query_update_method_data(MethodData* trap_mdo, int trap_bci, @@ -375,8 +376,8 @@ class Deoptimization : AllStatic { static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread); static DeoptAction _unloaded_action; // == Action_reinterpret; - static const char* _trap_reason_name[Reason_LIMIT]; - static const char* _trap_action_name[Action_LIMIT]; + static const char* _trap_reason_name[]; + static const char* _trap_action_name[]; static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT]; // Note: Histogram array size is 1-2 Kb. diff --git a/hotspot/src/share/vm/runtime/fprofiler.cpp b/hotspot/src/share/vm/runtime/fprofiler.cpp index 7e497b73541..58cb6e89daa 100644 --- a/hotspot/src/share/vm/runtime/fprofiler.cpp +++ b/hotspot/src/share/vm/runtime/fprofiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ #include "runtime/vframe.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Static fields of FlatProfiler int FlatProfiler::received_gc_ticks = 0; int FlatProfiler::vm_operation_ticks = 0; @@ -309,7 +311,7 @@ class ProfilerNode { st->fill_to(col2); t->print_native(st); st->fill_to(col3); - st->print(msg); + st->print("%s", msg); st->cr(); } diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index 1409bd79651..2f7cb8f186a 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,8 @@ # include "nativeInst_ppc.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + RegisterMap::RegisterMap(JavaThread *thread, bool update_map) { _thread = thread; _update_map = update_map; diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index 526d47c9ad6..05daec54cf8 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ #include "shark/shark_globals.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \ @@ -283,6 +285,7 @@ bool Flag::is_external() const { // Length of format string (e.g. "%.1234s") for printing ccstr below #define FORMAT_BUFFER_LEN 16 +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL void Flag::print_on(outputStream* st, bool withComments) { // Don't print notproduct and develop flags in a product build. if (is_constant_in_binary()) { @@ -315,7 +318,10 @@ void Flag::print_on(outputStream* st, bool withComments) { size_t llen = pointer_delta(eol, cp, sizeof(char)); jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, "%%." SIZE_FORMAT "s", llen); +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(format_buffer, cp); +PRAGMA_DIAG_POP st->cr(); cp = eol+1; st->print("%5s %-35s += ", "", _name); @@ -372,7 +378,7 @@ void Flag::print_kind(outputStream* st) { } else { st->print(" "); } - st->print(d.name); + st->print("%s", d.name); } } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index b2f622e3c91..9952ad96bb7 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -177,7 +177,6 @@ define_pd_global(bool, ProfileTraps, false); define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 0); -define_pd_global(intx, BackEdgeThreshold, 0); define_pd_global(intx, OnStackReplacePercentage, 0); define_pd_global(bool, ResizeTLAB, false); @@ -525,13 +524,6 @@ class CommandLineFlags { product_pd(bool, UseMembar, \ "(Unstable) Issues membars on thread state transitions") \ \ - /* Temp PPC Flag to allow disabling the use of lwsync on ppc platforms \ - * that don't support it. This will be replaced by processor detection \ - * logic. \ - */ \ - product(bool, UsePPCLWSYNC, true, \ - "Use lwsync instruction if true, else use slower sync") \ - \ develop(bool, CleanChunkPoolAsync, falseInEmbedded, \ "Clean the chunk pool asynchronously") \ \ @@ -2562,6 +2554,20 @@ class CommandLineFlags { diagnostic(bool, PrintMethodFlushingStatistics, false, \ "print statistics about method flushing") \ \ + diagnostic(intx, HotMethodDetectionLimit, 100000, \ + "Number of compiled code invocations after which " \ + "the method is considered as hot by the flusher") \ + \ + diagnostic(intx, MinPassesBeforeFlush, 10, \ + "Minimum number of sweeper passes before an nmethod " \ + "can be flushed") \ + \ + product(bool, UseCodeAging, true, \ + "Insert counter to detect warm methods") \ + \ + diagnostic(bool, StressCodeAging, false, \ + "Start with counters compiled in") \ + \ develop(bool, UseRelocIndex, false, \ "Use an index to speed random access to relocations") \ \ @@ -3525,10 +3531,6 @@ class CommandLineFlags { product_pd(intx, CompileThreshold, \ "number of interpreted method invocations before (re-)compiling") \ \ - product_pd(intx, BackEdgeThreshold, \ - "Interpreter Back edge threshold at which an OSR compilation is " \ - "invoked") \ - \ product(intx, Tier0InvokeNotifyFreqLog, 7, \ "Interpreter (tier 0) invocation notification frequency") \ \ @@ -3654,22 +3656,6 @@ class CommandLineFlags { \ /* New JDK 1.4 reflection implementation */ \ \ - develop(bool, UseNewReflection, true, \ - "Temporary flag for transition to reflection based on dynamic " \ - "bytecode generation in 1.4; can no longer be turned off in 1.4 " \ - "JDK, and is unneeded in 1.3 JDK, but marks most places VM " \ - "changes were needed") \ - \ - develop(bool, VerifyReflectionBytecodes, false, \ - "Force verification of 1.4 reflection bytecodes. Does not work " \ - "in situations like that described in 4486457 or for " \ - "constructors generated for serialization, so can not be enabled "\ - "in product.") \ - \ - product(bool, ReflectionWrapResolutionErrors, true, \ - "Temporary flag for transition to AbstractMethodError wrapped " \ - "in InvocationTargetException. See 6531596") \ - \ develop(intx, FastSuperclassLimit, 8, \ "Depth of hardwired instanceof accelerator array") \ \ diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp index ca73f86ba7f..e80b6d79828 100644 --- a/hotspot/src/share/vm/runtime/handles.cpp +++ b/hotspot/src/share/vm/runtime/handles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ # include "os_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef ASSERT oop* HandleArea::allocate_handle(oop obj) { assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark"); diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp index 4533c7e8127..6c654d280e2 100644 --- a/hotspot/src/share/vm/runtime/init.cpp +++ b/hotspot/src/share/vm/runtime/init.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "code/icBuffer.hpp" #include "gc_interface/collectedHeap.hpp" #include "interpreter/bytecodes.hpp" diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.cpp b/hotspot/src/share/vm/runtime/interfaceSupport.cpp index 61bdfcebf85..09757155d9d 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "runtime/vframe.hpp" #include "utilities/preserveException.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of InterfaceSupport diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index cddfd3d1ffc..e852b56ef54 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" @@ -97,6 +97,7 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC GrowableArray* collected_profiled_methods; @@ -119,7 +120,8 @@ void collect_profiled_methods(Method* m) { } void print_method_profiling_data() { - if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData)) { + if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData) && + (PrintMethodData || CompilerOracle::should_print_methods())) { ResourceMark rm; HandleMark hm; collected_profiled_methods = new GrowableArray(1024); @@ -366,7 +368,7 @@ void print_statistics() { BaselineTTYOutputer outputer(tty); MemTracker::print_memory_usage(outputer, K, false); } else { - tty->print_cr(MemTracker::reason()); + tty->print_cr("%s", MemTracker::reason()); } } } @@ -407,7 +409,7 @@ void print_statistics() { BaselineTTYOutputer outputer(tty); MemTracker::print_memory_usage(outputer, K, false); } else { - tty->print_cr(MemTracker::reason()); + tty->print_cr("%s", MemTracker::reason()); } } } diff --git a/hotspot/src/share/vm/runtime/jniHandles.cpp b/hotspot/src/share/vm/runtime/jniHandles.cpp index 373c3359d02..7ff38335029 100644 --- a/hotspot/src/share/vm/runtime/jniHandles.cpp +++ b/hotspot/src/share/vm/runtime/jniHandles.cpp @@ -30,6 +30,7 @@ #include "runtime/mutexLocker.hpp" #include "runtime/thread.inline.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC JNIHandleBlock* JNIHandles::_global_handles = NULL; JNIHandleBlock* JNIHandles::_weak_global_handles = NULL; diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp index 8789e5d0df4..34c9366f0d1 100644 --- a/hotspot/src/share/vm/runtime/mutex.cpp +++ b/hotspot/src/share/vm/runtime/mutex.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ # include "mutex_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o // // Native Monitor-Mutex locking - theory of operations diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 82361d3fd43..04c008431c7 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,8 @@ # include +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + OSThread* os::_starting_thread = NULL; address os::_polling_page = NULL; volatile int32_t* os::_mem_serialize_page = NULL; @@ -909,9 +911,9 @@ void os::print_environment_variables(outputStream* st, const char** env_list, for (int i = 0; env_list[i] != NULL; i++) { if (getenv(env_list[i], buffer, len)) { - st->print(env_list[i]); + st->print("%s", env_list[i]); st->print("="); - st->print_cr(buffer); + st->print_cr("%s", buffer); } } } @@ -1095,11 +1097,15 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) { } - // Check if in metaspace. - if (ClassLoaderDataGraph::contains((address)addr)) { - // Use addr->print() from the debugger instead (not here) - st->print_cr(INTPTR_FORMAT - " is pointing into metadata", addr); + // Check if in metaspace and print types that have vptrs (only method now) + if (Metaspace::contains(addr)) { + if (Method::has_method_vptr((const void*)addr)) { + ((Method*)addr)->print_value_on(st); + st->cr(); + } else { + // Use addr->print() from the debugger instead (not here) + st->print_cr(INTPTR_FORMAT " is pointing into metadata", addr); + } return; } diff --git a/hotspot/src/share/vm/runtime/osThread.cpp b/hotspot/src/share/vm/runtime/osThread.cpp index 8c7b5e61c96..57bf1f524fd 100644 --- a/hotspot/src/share/vm/runtime/osThread.cpp +++ b/hotspot/src/share/vm/runtime/osThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #include "oops/oop.inline.hpp" #include "runtime/osThread.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) { pd_initialize(); diff --git a/hotspot/src/share/vm/runtime/perfData.cpp b/hotspot/src/share/vm/runtime/perfData.cpp index f2152ab1c64..caf4c99295e 100644 --- a/hotspot/src/share/vm/runtime/perfData.cpp +++ b/hotspot/src/share/vm/runtime/perfData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ #include "utilities/exceptions.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PerfDataList* PerfDataManager::_all = NULL; PerfDataList* PerfDataManager::_sampled = NULL; PerfDataList* PerfDataManager::_constants = NULL; diff --git a/hotspot/src/share/vm/runtime/perfMemory.cpp b/hotspot/src/share/vm/runtime/perfMemory.cpp index 209288cb680..4eddf2a9722 100644 --- a/hotspot/src/share/vm/runtime/perfMemory.cpp +++ b/hotspot/src/share/vm/runtime/perfMemory.cpp @@ -35,6 +35,8 @@ #include "runtime/statSampler.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Prefix of performance data file. const char PERFDATA_NAME[] = "hsperfdata"; diff --git a/hotspot/src/share/vm/runtime/prefetch.inline.hpp b/hotspot/src/share/vm/runtime/prefetch.inline.hpp new file mode 100644 index 00000000000..e147a211aea --- /dev/null +++ b/hotspot/src/share/vm/runtime/prefetch.inline.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP +#define SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP + +#include "runtime/prefetch.hpp" + +// Linux +#ifdef TARGET_OS_ARCH_linux_x86 +# include "prefetch_linux_x86.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_sparc +# include "prefetch_linux_sparc.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_zero +# include "prefetch_linux_zero.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "prefetch_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "prefetch_linux_ppc.inline.hpp" +#endif + +// Solaris +#ifdef TARGET_OS_ARCH_solaris_x86 +# include "prefetch_solaris_x86.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_solaris_sparc +# include "prefetch_solaris_sparc.inline.hpp" +#endif + +// Windows +#ifdef TARGET_OS_ARCH_windows_x86 +# include "prefetch_windows_x86.inline.hpp" +#endif + +// AIX +#ifdef TARGET_OS_ARCH_aix_ppc +# include "prefetch_aix_ppc.inline.hpp" +#endif + +// BSD +#ifdef TARGET_OS_ARCH_bsd_x86 +# include "prefetch_bsd_x86.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_bsd_zero +# include "prefetch_bsd_zero.inline.hpp" +#endif + +#endif // SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index de707164d03..872d73c72e8 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/verifier.hpp" #include "classfile/vmSymbols.hpp" @@ -466,7 +466,6 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo // New (1.4) reflection implementation. Allow all accesses from // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. if ( JDK_Version::is_gte_jdk14x_version() - && UseNewReflection && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } @@ -571,7 +570,6 @@ bool Reflection::verify_field_access(Klass* current_class, // New (1.4) reflection implementation. Allow all accesses from // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. if ( JDK_Version::is_gte_jdk14x_version() - && UseNewReflection && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } @@ -708,7 +706,7 @@ Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) { } -oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) { +oop Reflection::new_method(methodHandle method, bool for_constant_pool_access, TRAPS) { // In jdk1.2.x, getMethods on an interface erroneously includes , thus the complicated assert. // Also allow sun.reflect.ConstantPool to refer to methods as java.lang.reflect.Methods. assert(!method()->is_initializer() || @@ -731,14 +729,8 @@ oop Reflection::new_method(methodHandle method, bool intern_name, bool for_const if (exception_types.is_null()) return NULL; Symbol* method_name = method->name(); - Handle name; - if (intern_name) { - // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(method_name, CHECK_NULL); - name = Handle(THREAD, name_oop); - } else { - name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); - } + oop name_oop = StringTable::intern(method_name, CHECK_NULL); + Handle name = Handle(THREAD, name_oop); if (name == NULL) return NULL; int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; @@ -825,16 +817,10 @@ oop Reflection::new_constructor(methodHandle method, TRAPS) { } -oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { +oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { Symbol* field_name = fd->name(); - Handle name; - if (intern_name) { - // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(field_name, CHECK_NULL); - name = Handle(THREAD, name_oop); - } else { - name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); - } + oop name_oop = StringTable::intern(field_name, CHECK_NULL); + Handle name = Handle(THREAD, name_oop); Symbol* signature = fd->signature(); instanceKlassHandle holder (THREAD, fd->field_holder()); Handle type = new_type(signature, holder, CHECK_NULL); @@ -933,27 +919,23 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, // resolve based on the receiver if (reflected_method->method_holder()->is_interface()) { // resolve interface call - if (ReflectionWrapResolutionErrors) { - // new default: 6531596 - // Match resolution errors with those thrown due to reflection inlining - // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() - method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); - if (HAS_PENDING_EXCEPTION) { - // Method resolution threw an exception; wrap it in an InvocationTargetException - oop resolution_exception = PENDING_EXCEPTION; - CLEAR_PENDING_EXCEPTION; - // JVMTI has already reported the pending exception - // JVMTI internal flag reset is needed in order to report InvocationTargetException - if (THREAD->is_Java_thread()) { - JvmtiExport::clear_detected_exception((JavaThread*) THREAD); - } - JavaCallArguments args(Handle(THREAD, resolution_exception)); - THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), - vmSymbols::throwable_void_signature(), - &args); + // + // Match resolution errors with those thrown due to reflection inlining + // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() + method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); + if (HAS_PENDING_EXCEPTION) { + // Method resolution threw an exception; wrap it in an InvocationTargetException + oop resolution_exception = PENDING_EXCEPTION; + CLEAR_PENDING_EXCEPTION; + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report InvocationTargetException + if (THREAD->is_Java_thread()) { + JvmtiExport::clear_detected_exception((JavaThread*) THREAD); } - } else { - method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); + JavaCallArguments args(Handle(THREAD, resolution_exception)); + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), + &args); } } else { // if the method can be overridden, we resolve using the vtable index. @@ -970,24 +952,16 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, // Check for abstract methods as well if (method->is_abstract()) { // new default: 6531596 - if (ReflectionWrapResolutionErrors) { - ResourceMark rm(THREAD); - Handle h_origexception = Exceptions::new_exception(THREAD, - vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(target_klass(), - method->name(), - method->signature())); - JavaCallArguments args(h_origexception); - THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), - vmSymbols::throwable_void_signature(), - &args); - } else { - ResourceMark rm(THREAD); - THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(target_klass(), - method->name(), - method->signature())); - } + ResourceMark rm(THREAD); + Handle h_origexception = Exceptions::new_exception(THREAD, + vmSymbols::java_lang_AbstractMethodError(), + Method::name_and_sig_as_C_string(target_klass(), + method->name(), + method->signature())); + JavaCallArguments args(h_origexception); + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), + &args); } } } @@ -1006,7 +980,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, // In the JDK 1.4 reflection implementation, the security check is // done at the Java level - if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { + if (!JDK_Version::is_gte_jdk14x_version()) { // Access checking (unless overridden by Method) if (!override) { @@ -1018,7 +992,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, } } - } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) + } // !Universe::is_gte_jdk14x_version() assert(ptypes->is_objArray(), "just checking"); int args_len = args.is_null() ? 0 : args->length(); diff --git a/hotspot/src/share/vm/runtime/reflection.hpp b/hotspot/src/share/vm/runtime/reflection.hpp index d8694948cd7..5757cfc39f5 100644 --- a/hotspot/src/share/vm/runtime/reflection.hpp +++ b/hotspot/src/share/vm/runtime/reflection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,11 +113,11 @@ class Reflection: public AllStatic { // // Create a java.lang.reflect.Method object based on a method - static oop new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS); + static oop new_method(methodHandle method, bool for_constant_pool_access, TRAPS); // Create a java.lang.reflect.Constructor object based on a method static oop new_constructor(methodHandle method, TRAPS); // Create a java.lang.reflect.Field object based on a field descriptor - static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS); + static oop new_field(fieldDescriptor* fd, TRAPS); // Create a java.lang.reflect.Parameter object based on a // MethodParameterElement static oop new_parameter(Handle method, int index, Symbol* sym, diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index cbf11d17311..e71185d431d 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/symbolTable.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" @@ -82,6 +82,8 @@ #include "c1/c1_globals.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // -------------------------------------------------------------------------------------------------- // Implementation of Safepoint begin/end @@ -539,6 +541,13 @@ void SafepointSynchronize::do_cleanup_tasks() { gclog_or_tty->rotate_log(false); } + { + // CMS delays purging the CLDG until the beginning of the next safepoint and to + // make sure concurrent sweep is done + TraceTime t7("purging class loader data graph", TraceSafepointCleanupTime); + ClassLoaderDataGraph::purge_if_needed(); + } + if (MemTracker::is_on()) { MemTracker::sync(); } @@ -787,7 +796,7 @@ static void print_me(intptr_t *new_sp, intptr_t *old_sp, bool *was_oops) { old_sp += incr*32; new_sp += incr*32; was_oops += incr*32; for( int i2=0; i2<16; i2++ ) { tty->print("call %c%d |"PTR_FORMAT" ","LI"[i2>>3],i2&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); } - tty->print_cr(""); + tty->cr(); } #endif // SPARC #endif // PRODUCT @@ -829,7 +838,7 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason timeout_error_printed = true; // Print out the thread info which didn't reach the safepoint for debugging // purposes (useful when there are lots of threads in the debugger). - tty->print_cr(""); + tty->cr(); tty->print_cr("# SafepointSynchronize::begin: Timeout detected:"); if (reason == _spinning_timeout) { tty->print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint."); @@ -849,7 +858,7 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason (reason == _blocking_timeout && !cur_state->has_called_back()))) { tty->print("# "); cur_thread->print(); - tty->print_cr(""); + tty->cr(); } } tty->print_cr("# SafepointSynchronize::begin: (End of list)"); @@ -1322,7 +1331,7 @@ void SafepointSynchronize::print_stat_on_exit() { spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) { print_statistics(); } - tty->print_cr(""); + tty->cr(); // Print out polling page sampling status. if (!need_to_track_page_armed_status) { diff --git a/hotspot/src/share/vm/runtime/safepoint.hpp b/hotspot/src/share/vm/runtime/safepoint.hpp index e43eef4df96..ab5d2e9445d 100644 --- a/hotspot/src/share/vm/runtime/safepoint.hpp +++ b/hotspot/src/share/vm/runtime/safepoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,7 +174,7 @@ public: // Debugging static void print_state() PRODUCT_RETURN; - static void safepoint_msg(const char* format, ...) PRODUCT_RETURN; + static void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(1, 2) PRODUCT_RETURN; static void deferred_initialize_stat(); static void print_stat_on_exit(); @@ -240,7 +240,7 @@ class ThreadSafepointState: public CHeapObj { static void create(JavaThread *thread); static void destroy(JavaThread *thread); - void safepoint_msg(const char* format, ...) { + void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { if (ShowSafepointMsgs) { va_list ap; va_start(ap, format); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index ad69dcec364..fad31fd02f1 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -82,6 +82,8 @@ #include "c1/c1_Runtime1.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Shared stub locations RuntimeStub* SharedRuntime::_wrong_method_blob; RuntimeStub* SharedRuntime::_wrong_method_abstract_blob; diff --git a/hotspot/src/share/vm/runtime/sharedRuntimeMath.hpp b/hotspot/src/share/vm/runtime/sharedRuntimeMath.hpp new file mode 100644 index 00000000000..4259227c3b3 --- /dev/null +++ b/hotspot/src/share/vm/runtime/sharedRuntimeMath.hpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP +#define SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP + +#include + +// VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles +// [jk] this is not 100% correct because the float word order may different +// from the byte order (e.g. on ARM FPA) +#ifdef VM_LITTLE_ENDIAN +# define __HI(x) *(1+(int*)&x) +# define __LO(x) *(int*)&x +#else +# define __HI(x) *(int*)&x +# define __LO(x) *(1+(int*)&x) +#endif + +static double copysignA(double x, double y) { + __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000); + return x; +} + +/* + * ==================================================== + * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +hugeX = 1.0e+300, +tiny = 1.0e-300; + +static double scalbnA (double x, int n) { + int k,hx,lx; + hx = __HI(x); + lx = __LO(x); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + hx = __HI(x); + k = ((hx&0x7ff00000)>>20) - 54; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */ + if (k > 0) /* normal result */ + {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} + if (k <= -54) { + if (n > 50000) /* in case integer overflow in n+k */ + return hugeX*copysignA(hugeX,x); /*overflow*/ + else return tiny*copysignA(tiny,x); /*underflow*/ + } + k += 54; /* subnormal result */ + __HI(x) = (hx&0x800fffff)|(k<<20); + return x*twom54; +} + +#endif // SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP diff --git a/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp b/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp index c5fb4e2e3e4..69feb28bdfb 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,78 +43,7 @@ # pragma optimize ( "", off ) #endif -#include - -// VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles -// [jk] this is not 100% correct because the float word order may different -// from the byte order (e.g. on ARM) -#ifdef VM_LITTLE_ENDIAN -# define __HI(x) *(1+(int*)&x) -# define __LO(x) *(int*)&x -#else -# define __HI(x) *(int*)&x -# define __LO(x) *(1+(int*)&x) -#endif - -#if !defined(AIX) -double copysign(double x, double y) { - __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000); - return x; -} -#endif - -/* - * ==================================================== - * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * scalbn (double x, int n) - * scalbn(x,n) returns x* 2**n computed by exponent - * manipulation rather than by actually performing an - * exponentiation or a multiplication. - */ - -static const double -two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ - twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ - hugeX = 1.0e+300, - tiny = 1.0e-300; - -#if !defined(AIX) -double scalbn (double x, int n) { - int k,hx,lx; - hx = __HI(x); - lx = __LO(x); - k = (hx&0x7ff00000)>>20; /* extract exponent */ - if (k==0) { /* 0 or subnormal x */ - if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ - x *= two54; - hx = __HI(x); - k = ((hx&0x7ff00000)>>20) - 54; - if (n< -50000) return tiny*x; /*underflow*/ - } - if (k==0x7ff) return x+x; /* NaN or Inf */ - k = k+n; - if (k > 0x7fe) return hugeX*copysign(hugeX,x); /* overflow */ - if (k > 0) /* normal result */ - {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} - if (k <= -54) { - if (n > 50000) /* in case integer overflow in n+k */ - return hugeX*copysign(hugeX,x); /*overflow*/ - else return tiny*copysign(tiny,x); /*underflow*/ - } - k += 54; /* subnormal result */ - __HI(x) = (hx&0x800fffff)|(k<<20); - return x*twom54; -} -#endif +#include "runtime/sharedRuntimeMath.hpp" /* __ieee754_log(x) * Return the logarithm of x @@ -719,7 +648,7 @@ double __ieee754_pow(double x, double y) { z = one-(r-z); j = __HI(z); j += (n<<20); - if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ + if((j>>20)<=0) z = scalbnA(z,n); /* subnormal output */ else __HI(z) += (n<<20); return s*z; } diff --git a/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp b/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp index 7c499d84165..1691bdf7690 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,63 +63,7 @@ #define SAFEBUF #endif -#include - -// VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles -// [jk] this is not 100% correct because the float word order may different -// from the byte order (e.g. on ARM) -#ifdef VM_LITTLE_ENDIAN -# define __HI(x) *(1+(int*)&x) -# define __LO(x) *(int*)&x -#else -# define __HI(x) *(int*)&x -# define __LO(x) *(1+(int*)&x) -#endif - -static double copysignA(double x, double y) { - __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000); - return x; -} - -/* - * scalbn (double x, int n) - * scalbn(x,n) returns x* 2**n computed by exponent - * manipulation rather than by actually performing an - * exponentiation or a multiplication. - */ - -static const double -two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ -twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ -hugeX = 1.0e+300, -tiny = 1.0e-300; - -static double scalbnA (double x, int n) { - int k,hx,lx; - hx = __HI(x); - lx = __LO(x); - k = (hx&0x7ff00000)>>20; /* extract exponent */ - if (k==0) { /* 0 or subnormal x */ - if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ - x *= two54; - hx = __HI(x); - k = ((hx&0x7ff00000)>>20) - 54; - if (n< -50000) return tiny*x; /*underflow*/ - } - if (k==0x7ff) return x+x; /* NaN or Inf */ - k = k+n; - if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */ - if (k > 0) /* normal result */ - {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} - if (k <= -54) { - if (n > 50000) /* in case integer overflow in n+k */ - return hugeX*copysignA(hugeX,x); /*overflow*/ - else return tiny*copysignA(tiny,x); /*underflow*/ - } - k += 54; /* subnormal result */ - __HI(x) = (hx&0x800fffff)|(k<<20); - return x*twom54; -} +#include "runtime/sharedRuntimeMath.hpp" /* * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) diff --git a/hotspot/src/share/vm/runtime/signature.cpp b/hotspot/src/share/vm/runtime/signature.cpp index 3bad97a71d9..a92f5e73b28 100644 --- a/hotspot/src/share/vm/runtime/signature.cpp +++ b/hotspot/src/share/vm/runtime/signature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "oops/typeArrayKlass.hpp" #include "runtime/signature.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of SignatureIterator diff --git a/hotspot/src/share/vm/runtime/stackValue.cpp b/hotspot/src/share/vm/runtime/stackValue.cpp index ce274103d3f..a0e6f5104f8 100644 --- a/hotspot/src/share/vm/runtime/stackValue.cpp +++ b/hotspot/src/share/vm/runtime/stackValue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -196,7 +196,7 @@ void StackValue::print_on(outputStream* st) const { case T_OBJECT: _o()->print_value_on(st); - st->print(" <" INTPTR_FORMAT ">", (address)_o()); + st->print(" <" INTPTR_FORMAT ">", p2i((address)_o())); break; case T_CONFLICT: diff --git a/hotspot/src/share/vm/runtime/stackValueCollection.cpp b/hotspot/src/share/vm/runtime/stackValueCollection.cpp index 110f7120d4f..3794f64d78c 100644 --- a/hotspot/src/share/vm/runtime/stackValueCollection.cpp +++ b/hotspot/src/share/vm/runtime/stackValueCollection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ # include "jniTypes_ppc.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + jint StackValueCollection::int_at(int slot) const { intptr_t val = at(slot)->get_int(); jint ival = *((jint*) (&val)); diff --git a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp index 92f3d0be1dd..5ecbe028724 100644 --- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp +++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,10 +60,10 @@ const char* StubCodeDesc::name_for(address pc) { void StubCodeDesc::print_on(outputStream* st) const { - st->print(group()); + st->print("%s", group()); st->print("::"); - st->print(name()); - st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes()); + st->print("%s", name()); + st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", p2i(begin()), p2i(end()), size_in_bytes()); } // Implementation of StubCodeGenerator diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 6d30bd34032..5ec575aa356 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ #include "utilities/ticks.inline.hpp" #include "utilities/xmlstream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef ASSERT #define SWEEP(nm) record_sweep(nm, __LINE__) @@ -571,37 +573,7 @@ int NMethodSweeper::process_nmethod(nmethod *nm) { SWEEP(nm); } } else { - if (UseCodeCacheFlushing) { - if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { - // Do not make native methods and OSR-methods not-entrant - nm->dec_hotness_counter(); - // Get the initial value of the hotness counter. This value depends on the - // ReservedCodeCacheSize - int reset_val = hotness_counter_reset_val(); - int time_since_reset = reset_val - nm->hotness_counter(); - double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); - // The less free space in the code cache we have - the bigger reverse_free_ratio() is. - // I.e., 'threshold' increases with lower available space in the code cache and a higher - // NmethodSweepActivity. If the current hotness counter - which decreases from its initial - // value until it is reset by stack walking - is smaller than the computed threshold, the - // corresponding nmethod is considered for removal. - if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) { - // A method is marked as not-entrant if the method is - // 1) 'old enough': nm->hotness_counter() < threshold - // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10) - // The second condition is necessary if we are dealing with very small code cache - // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. - // The second condition ensures that methods are not immediately made not-entrant - // after compilation. - nm->make_not_entrant(); - // Code cache state change is tracked in make_not_entrant() - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f", - nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold); - } - } - } - } + possibly_flush(nm); // Clean-up all inline caches that point to zombie/non-reentrant methods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); @@ -610,6 +582,93 @@ int NMethodSweeper::process_nmethod(nmethod *nm) { return freed_memory; } + +void NMethodSweeper::possibly_flush(nmethod* nm) { + if (UseCodeCacheFlushing) { + if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { + bool make_not_entrant = false; + + // Do not make native methods and OSR-methods not-entrant + nm->dec_hotness_counter(); + // Get the initial value of the hotness counter. This value depends on the + // ReservedCodeCacheSize + int reset_val = hotness_counter_reset_val(); + int time_since_reset = reset_val - nm->hotness_counter(); + double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); + // The less free space in the code cache we have - the bigger reverse_free_ratio() is. + // I.e., 'threshold' increases with lower available space in the code cache and a higher + // NmethodSweepActivity. If the current hotness counter - which decreases from its initial + // value until it is reset by stack walking - is smaller than the computed threshold, the + // corresponding nmethod is considered for removal. + if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > MinPassesBeforeFlush)) { + // A method is marked as not-entrant if the method is + // 1) 'old enough': nm->hotness_counter() < threshold + // 2) The method was in_use for a minimum amount of time: (time_since_reset > MinPassesBeforeFlush) + // The second condition is necessary if we are dealing with very small code cache + // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. + // The second condition ensures that methods are not immediately made not-entrant + // after compilation. + make_not_entrant = true; + } + + // The stack-scanning low-cost detection may not see the method was used (which can happen for + // flat profiles). Check the age counter for possible data. + if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) { + MethodCounters* mc = nm->method()->method_counters(); + if (mc == NULL) { + // Sometimes we can get here without MethodCounters. For example if we run with -Xcomp. + // Try to allocate them. + mc = Method::build_method_counters(nm->method(), Thread::current()); + } + if (mc != NULL) { + // Snapshot the value as it's changed concurrently + int age = mc->nmethod_age(); + if (MethodCounters::is_nmethod_hot(age)) { + // The method has gone through flushing, and it became relatively hot that it deopted + // before we could take a look at it. Give it more time to appear in the stack traces, + // proportional to the number of deopts. + MethodData* md = nm->method()->method_data(); + if (md != NULL && time_since_reset > (int)(MinPassesBeforeFlush * (md->tenure_traps() + 1))) { + // It's been long enough, we still haven't seen it on stack. + // Try to flush it, but enable counters the next time. + mc->reset_nmethod_age(); + } else { + make_not_entrant = false; + } + } else if (MethodCounters::is_nmethod_warm(age)) { + // Method has counters enabled, and the method was used within + // previous MinPassesBeforeFlush sweeps. Reset the counter. Stay in the existing + // compiled state. + mc->reset_nmethod_age(); + // delay the next check + nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val()); + make_not_entrant = false; + } else if (MethodCounters::is_nmethod_age_unset(age)) { + // No counters were used before. Set the counters to the detection + // limit value. If the method is going to be used again it will be compiled + // with counters that we're going to use for analysis the the next time. + mc->reset_nmethod_age(); + } else { + // Method was totally idle for 10 sweeps + // The counter already has the initial value, flush it and may be recompile + // later with counters + } + } + } + + if (make_not_entrant) { + nm->make_not_entrant(); + + // Code cache state change is tracked in make_not_entrant() + if (PrintMethodFlushing && Verbose) { + tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f", + nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold); + } + } + } + } +} + // Print out some state information about the current sweep and the // state of the code cache if it's requested. void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { @@ -627,7 +686,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { tty->vprint(format, ap); va_end(ap); } - tty->print_cr(s.as_string()); + tty->print_cr("%s", s.as_string()); } if (LogCompilation && (xtty != NULL)) { @@ -644,7 +703,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { xtty->vprint(format, ap); va_end(ap); } - xtty->print(s.as_string()); + xtty->print("%s", s.as_string()); xtty->stamp(); xtty->end_elem(); } diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp index abee1ec77d2..d9630b2e5c4 100644 --- a/hotspot/src/share/vm/runtime/sweeper.hpp +++ b/hotspot/src/share/vm/runtime/sweeper.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,7 @@ class NMethodSweeper : public AllStatic { static const Tickspan total_time_sweeping() { return _total_time_sweeping; } static const Tickspan peak_sweep_time() { return _peak_sweep_time; } static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } - static void log_sweep(const char* msg, const char* format = NULL, ...); + static void log_sweep(const char* msg, const char* format = NULL, ...) ATTRIBUTE_PRINTF(2, 3); #ifdef ASSERT @@ -111,6 +111,7 @@ class NMethodSweeper : public AllStatic { static int hotness_counter_reset_val(); static void report_state_change(nmethod* nm); static void possibly_enable_sweeper(); + static void possibly_flush(nmethod* nm); static void print(); // Printing/debugging }; diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp index e6d4913d71a..62bd1ab9139 100644 --- a/hotspot/src/share/vm/runtime/synchronizer.cpp +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp @@ -60,6 +60,8 @@ #define ATTR #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // The "core" versions of monitor enter and exit reside in this file. // The interpreter and compilers contain specialized transliterated // variants of the enter-exit fast-path operations. See i486.ad fast_lock(), diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 0d8b90e11a4..e6d9eee7927 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -112,6 +112,8 @@ #include "runtime/rtmLocking.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef DTRACE_ENABLED // Only bother with this argument setup if dtrace is available @@ -4273,7 +4275,7 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock // Threads::print_on() is called at safepoint by VM_PrintThreads operation. void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) { char buf[32]; - st->print_cr(os::local_time_string(buf, sizeof(buf))); + st->print_cr("%s", os::local_time_string(buf, sizeof(buf))); st->print_cr("Full thread dump %s (%s %s):", Abstract_VM_Version::vm_name(), diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 422ba755e48..a5f0a92246d 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -684,7 +684,7 @@ class NamedThread: public Thread { NamedThread(); ~NamedThread(); // May only be called once per thread. - void set_name(const char* format, ...); + void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); virtual bool is_Named_thread() const { return true; } virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; } JavaThread *processed_thread() { return _processed_thread; } diff --git a/hotspot/src/share/vm/runtime/timer.cpp b/hotspot/src/share/vm/runtime/timer.cpp index e33a51cfb97..9067f20b3d3 100644 --- a/hotspot/src/share/vm/runtime/timer.cpp +++ b/hotspot/src/share/vm/runtime/timer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -204,7 +204,7 @@ TraceCPUTime::~TraceCPUTime() { _logfile->print("[Error in TraceCPUTime]"); } if (_print_cr) { - _logfile->print_cr(""); + _logfile->cr(); } _logfile->flush(); } diff --git a/hotspot/src/share/vm/runtime/unhandledOops.cpp b/hotspot/src/share/vm/runtime/unhandledOops.cpp index cc0002d42c9..d27b1fb2f71 100644 --- a/hotspot/src/share/vm/runtime/unhandledOops.cpp +++ b/hotspot/src/share/vm/runtime/unhandledOops.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "runtime/unhandledOops.hpp" #include "utilities/globalDefinitions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef CHECK_UNHANDLED_OOPS const int free_list_size = 256; diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp index 2487ad3c6cd..8b4d72f728e 100644 --- a/hotspot/src/share/vm/runtime/vframe.cpp +++ b/hotspot/src/share/vm/runtime/vframe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,8 @@ #include "runtime/vframeArray.hpp" #include "runtime/vframe_hp.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + vframe::vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : _reg_map(reg_map), _thread(thread) { assert(fr != NULL, "must have frame"); @@ -471,7 +473,7 @@ void vframeStreamCommon::skip_prefixed_method_and_wrappers() { void vframeStreamCommon::skip_reflection_related_frames() { while (!at_end() && - (JDK_Version::is_gte_jdk14x_version() && UseNewReflection && + (JDK_Version::is_gte_jdk14x_version() && (method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { next(); diff --git a/hotspot/src/share/vm/runtime/vframe.hpp b/hotspot/src/share/vm/runtime/vframe.hpp index 27966b1a73e..a284b13de0c 100644 --- a/hotspot/src/share/vm/runtime/vframe.hpp +++ b/hotspot/src/share/vm/runtime/vframe.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -399,7 +399,7 @@ inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) { if (WizardMode) { tty->print_cr("Error in fill_from_frame: pc_desc for " INTPTR_FORMAT " not found or invalid at %d", - _frame.pc(), decode_offset); + p2i(_frame.pc()), decode_offset); nm()->print(); nm()->method()->print_codes(); nm()->print_code(); diff --git a/hotspot/src/share/vm/runtime/vframeArray.cpp b/hotspot/src/share/vm/runtime/vframeArray.cpp index 5dff2d7b62a..72e2e8717cb 100644 --- a/hotspot/src/share/vm/runtime/vframeArray.cpp +++ b/hotspot/src/share/vm/runtime/vframeArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ #include "opto/runtime.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC int vframeArrayElement:: bci(void) const { return (_bci == SynchronizationEntryBCI ? 0 : _bci); } diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index 5ef3a976c49..19f699464b2 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ # include "os_bsd.inline.hpp" #endif +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // ReservedSpace diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 67bf7b1033d..49f0b321011 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -27,6 +27,7 @@ #include "classfile/javaClasses.hpp" #include "classfile/loaderConstraints.hpp" #include "classfile/placeholders.hpp" +#include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "ci/ciField.hpp" #include "ci/ciInstance.hpp" @@ -353,6 +354,7 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; nonstatic_field(MethodData, _method, Method*) \ nonstatic_field(MethodData, _data_size, int) \ nonstatic_field(MethodData, _data[0], intptr_t) \ + nonstatic_field(MethodData, _parameters_type_data_di, int) \ nonstatic_field(MethodData, _nof_decompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_traps, uint) \ @@ -361,10 +363,12 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; nonstatic_field(MethodData, _arg_local, intx) \ nonstatic_field(MethodData, _arg_stack, intx) \ nonstatic_field(MethodData, _arg_returned, intx) \ + nonstatic_field(MethodData, _tenure_traps, uint) \ nonstatic_field(DataLayout, _header._struct._tag, u1) \ nonstatic_field(DataLayout, _header._struct._flags, u1) \ nonstatic_field(DataLayout, _header._struct._bci, u2) \ nonstatic_field(DataLayout, _cells[0], intptr_t) \ + nonstatic_field(MethodCounters, _nmethod_age, int) \ nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \ nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \ nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \ @@ -2497,6 +2501,10 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; declare_constant(Deoptimization::Reason_age) \ declare_constant(Deoptimization::Reason_predicate) \ declare_constant(Deoptimization::Reason_loop_limit_check) \ + declare_constant(Deoptimization::Reason_speculate_class_check) \ + declare_constant(Deoptimization::Reason_speculate_null_check) \ + declare_constant(Deoptimization::Reason_rtm_state_change) \ + declare_constant(Deoptimization::Reason_tenured) \ declare_constant(Deoptimization::Reason_LIMIT) \ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \ \ diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp index a3ff582fab9..ab755589403 100644 --- a/hotspot/src/share/vm/runtime/vmThread.cpp +++ b/hotspot/src/share/vm/runtime/vmThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ #include "utilities/events.hpp" #include "utilities/xmlstream.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Dummy VM operation to act as first element in our circular double-linked list class VM_Dummy: public VM_Operation { VMOp_Type type() const { return VMOp_Dummy; } diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp index e26c3938b20..d46e1f775ac 100644 --- a/hotspot/src/share/vm/runtime/vm_operations.cpp +++ b/hotspot/src/share/vm/runtime/vm_operations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include "services/threadService.hpp" #include "trace/tracing.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #define VM_OP_NAME_INITIALIZE(name) #name, const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp index d2d7efcafa2..5df7d221a2b 100644 --- a/hotspot/src/share/vm/runtime/vm_version.cpp +++ b/hotspot/src/share/vm/runtime/vm_version.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,7 +117,7 @@ void Abstract_VM_Version::initialize() { set_version_field(&_vm_minor_version, JDK_MINOR_VERSION, "bad minor version"); set_version_field(&_vm_micro_version, JDK_MICRO_VERSION, "bad micro version"); int offset = (JDK_BUILD_NUMBER != NULL && JDK_BUILD_NUMBER[0] == 'b') ? 1 : 0; - set_version_field(&_vm_build_number, JDK_BUILD_NUMBER + offset, + set_version_field(&_vm_build_number, &JDK_BUILD_NUMBER[offset], "bad build number"); _initialized = true; diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp index 8551563f59f..9d68175518a 100644 --- a/hotspot/src/share/vm/services/attachListener.cpp +++ b/hotspot/src/share/vm/services/attachListener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -284,15 +284,15 @@ static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream* } if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) { - out->print_cr(err_msg.buffer()); + out->print_cr("%s", err_msg.buffer()); return JNI_ERR; } } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) { - out->print_cr(err_msg.buffer()); + out->print_cr("%s", err_msg.buffer()); return JNI_ERR; } } @@ -381,7 +381,7 @@ static jint print_flag(AttachOperation* op, outputStream* out) { Flag* f = Flag::find_flag((char*)name, strlen(name)); if (f) { f->print_as_flag(out); - out->print_cr(""); + out->cr(); } else { out->print_cr("no such flag '%s'", name); } diff --git a/hotspot/src/share/vm/services/classLoadingService.cpp b/hotspot/src/share/vm/services/classLoadingService.cpp index bdc33fdd2bb..8ce6eb8e532 100644 --- a/hotspot/src/share/vm/services/classLoadingService.cpp +++ b/hotspot/src/share/vm/services/classLoadingService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,7 +136,7 @@ void ClassLoadingService::notify_class_unloaded(InstanceKlass* k) { if (TraceClassUnloading) { ResourceMark rm; - tty->print_cr("[Unloading class %s " INTPTR_FORMAT "]", k->external_name(), k); + tty->print_cr("[Unloading class %s " INTPTR_FORMAT "]", k->external_name(), p2i(k)); } } diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 74444d6168d..ca031f87963 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,8 @@ #include "services/management.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + void DCmdRegistrant::register_dcmds(){ // Registration of the diagnostic commands // First argument specifies which interfaces will export the command @@ -101,7 +103,7 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) { if (factory != NULL) { output()->print_cr("%s%s", factory->name(), factory->is_enabled() ? "" : " [disabled]"); - output()->print_cr(factory->description()); + output()->print_cr("%s", factory->description()); output()->print_cr("\nImpact: %s", factory->impact()); JavaPermission p = factory->permission(); if(p._class != NULL) { diff --git a/hotspot/src/share/vm/services/diagnosticFramework.cpp b/hotspot/src/share/vm/services/diagnosticFramework.cpp index dcc2a21e48a..dcb67d36c3b 100644 --- a/hotspot/src/share/vm/services/diagnosticFramework.cpp +++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -259,7 +259,7 @@ void DCmdParser::print_help(outputStream* out, const char* cmd_name) { } arg = arg->next(); } - out->print_cr(""); + out->cr(); if (_arguments_list != NULL) { out->print_cr("\nArguments:"); arg = _arguments_list; @@ -268,7 +268,7 @@ void DCmdParser::print_help(outputStream* out, const char* cmd_name) { arg->is_mandatory() ? "" : "[optional]", arg->description(), arg->type()); if (arg->has_default()) { - out->print(arg->default_string()); + out->print("%s", arg->default_string()); } else { out->print("no default value"); } @@ -284,7 +284,7 @@ void DCmdParser::print_help(outputStream* out, const char* cmd_name) { arg->is_mandatory() ? "" : "[optional]", arg->description(), arg->type()); if (arg->has_default()) { - out->print(arg->default_string()); + out->print("%s", arg->default_string()); } else { out->print("no default value"); } diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp index 39c9a395d73..79c6c8ca7e0 100644 --- a/hotspot/src/share/vm/services/heapDumper.cpp +++ b/hotspot/src/share/vm/services/heapDumper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1842,6 +1842,7 @@ void VM_HeapDumper::dump_stack_traces() { } // dump the heap to given path. +PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL int HeapDumper::dump(const char* path) { assert(path != NULL && strlen(path) > 0, "path missing"); @@ -1882,7 +1883,10 @@ int HeapDumper::dump(const char* path) { char msg[256]; sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]", JLONG_FORMAT, timer()->seconds()); +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL tty->print_cr(msg, writer.bytes_written()); +PRAGMA_DIAG_POP } else { tty->print_cr("Dump file is incomplete: %s", writer.error()); } diff --git a/hotspot/src/share/vm/services/lowMemoryDetector.cpp b/hotspot/src/share/vm/services/lowMemoryDetector.cpp index 199a342dd77..b68be23dfa4 100644 --- a/hotspot/src/share/vm/services/lowMemoryDetector.cpp +++ b/hotspot/src/share/vm/services/lowMemoryDetector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -353,7 +353,7 @@ void SensorInfo::clear(int count, TRAPS) { #ifndef PRODUCT void SensorInfo::print() { - tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %ld pending_clears = %ld", + tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %d pending_clears = %d", (_sensor_on ? "on" : "off"), _sensor_count, _pending_trigger_count, _pending_clear_count); } diff --git a/hotspot/src/share/vm/services/management.cpp b/hotspot/src/share/vm/services/management.cpp index 7c99aa47730..dc901876104 100644 --- a/hotspot/src/share/vm/services/management.cpp +++ b/hotspot/src/share/vm/services/management.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,6 +56,8 @@ #include "services/threadService.hpp" #include "utilities/macros.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + PerfVariable* Management::_begin_vm_creation_time = NULL; PerfVariable* Management::_end_vm_creation_time = NULL; PerfVariable* Management::_vm_init_done_time = NULL; @@ -1839,12 +1841,12 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value uintx uvalue = (uintx)new_value.j; if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MaxHeapFreeRatio(err_msg, uvalue)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer()); } } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg(""); + FormatBuffer<80> err_msg("%s", ""); if (!Arguments::verify_MinHeapFreeRatio(err_msg, uvalue)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer()); } diff --git a/hotspot/src/share/vm/services/memReporter.cpp b/hotspot/src/share/vm/services/memReporter.cpp index c9cbc08046c..305693dad08 100644 --- a/hotspot/src/share/vm/services/memReporter.cpp +++ b/hotspot/src/share/vm/services/memReporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "services/memPtrArray.hpp" #include "services/memTracker.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + const char* BaselineOutputer::memory_unit(size_t scale) { switch(scale) { case K: return "KB"; diff --git a/hotspot/src/share/vm/services/memSnapshot.cpp b/hotspot/src/share/vm/services/memSnapshot.cpp index 3bfd19324bb..8f5ca4f4195 100644 --- a/hotspot/src/share/vm/services/memSnapshot.cpp +++ b/hotspot/src/share/vm/services/memSnapshot.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ #include "services/memSnapshot.hpp" #include "services/memTracker.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef ASSERT void decode_pointer_record(MemPointerRecord* rec) { @@ -733,7 +735,7 @@ void MemSnapshot::dump_all_vm_pointers() { if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) { tty->print_cr("\t%s", buf); } else { - tty->print_cr(""); + tty->cr(); } } } diff --git a/hotspot/src/share/vm/services/memTrackWorker.cpp b/hotspot/src/share/vm/services/memTrackWorker.cpp index e1382dd1a3a..7bf18eb273c 100644 --- a/hotspot/src/share/vm/services/memTrackWorker.cpp +++ b/hotspot/src/share/vm/services/memTrackWorker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) { // create thread uses cgc thread type for now. We should revisit // the option, or create new thread type. _has_error = !os::create_thread(this, os::cgc_thread); - set_name("MemTrackWorker", 0); + set_name("MemTrackWorker"); // initial generation circuit buffer if (!has_error()) { diff --git a/hotspot/src/share/vm/services/nmtDCmd.cpp b/hotspot/src/share/vm/services/nmtDCmd.cpp index 823e3c443f2..8ced28772f3 100644 --- a/hotspot/src/share/vm/services/nmtDCmd.cpp +++ b/hotspot/src/share/vm/services/nmtDCmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,7 +128,7 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) { // native memory tracking has to be on if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) { // if it is not on, what's the reason? - output()->print_cr(MemTracker::reason()); + output()->print_cr("%s", MemTracker::reason()); return; } diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp index a46067981a0..02156a2f3e2 100644 --- a/hotspot/src/share/vm/services/threadService.cpp +++ b/hotspot/src/share/vm/services/threadService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ #include "runtime/vm_operations.hpp" #include "services/threadService.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // TODO: we need to define a naming convention for perf counters // to distinguish counters for: // - standard JSR174 use diff --git a/hotspot/src/share/vm/trace/traceStream.hpp b/hotspot/src/share/vm/trace/traceStream.hpp index 4acbbb88498..14bc421115c 100644 --- a/hotspot/src/share/vm/trace/traceStream.hpp +++ b/hotspot/src/share/vm/trace/traceStream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ class TraceStream : public StackObj { } void print_val(const char* label, s8 val) { - _st.print("%s = "INT64_FORMAT, label, val); + _st.print("%s = "INT64_FORMAT, label, (int64_t) val); } void print_val(const char* label, bool val) { @@ -113,7 +113,7 @@ class TraceStream : public StackObj { } void print(const char* val) { - _st.print(val); + _st.print("%s", val); } }; diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp index a3d3de99c91..5b1ff17322b 100644 --- a/hotspot/src/share/vm/utilities/accessFlags.hpp +++ b/hotspot/src/share/vm/utilities/accessFlags.hpp @@ -54,7 +54,8 @@ enum { JVM_ACC_IS_OLD = 0x00010000, // RedefineClasses() has replaced this method JVM_ACC_IS_OBSOLETE = 0x00020000, // RedefineClasses() has made method obsolete JVM_ACC_IS_PREFIXED_NATIVE = 0x00040000, // JVMTI has prefixed this native method - JVM_ACC_ON_STACK = 0x00080000, // RedefinedClasses() is used on the stack + JVM_ACC_ON_STACK = 0x00080000, // RedefineClasses() was used on the stack + JVM_ACC_IS_DELETED = 0x00008000, // RedefineClasses() has deleted this method // Klass* flags JVM_ACC_HAS_MIRANDA_METHODS = 0x10000000, // True if this class has miranda methods in it's vtable @@ -131,6 +132,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC { bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; } bool is_old () const { return (_flags & JVM_ACC_IS_OLD ) != 0; } bool is_obsolete () const { return (_flags & JVM_ACC_IS_OBSOLETE ) != 0; } + bool is_deleted () const { return (_flags & JVM_ACC_IS_DELETED ) != 0; } bool is_prefixed_native () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE ) != 0; } // Klass* flags @@ -195,6 +197,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC { void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); } void set_is_old() { atomic_set_bits(JVM_ACC_IS_OLD); } void set_is_obsolete() { atomic_set_bits(JVM_ACC_IS_OBSOLETE); } + void set_is_deleted() { atomic_set_bits(JVM_ACC_IS_DELETED); } void set_is_prefixed_native() { atomic_set_bits(JVM_ACC_IS_PREFIXED_NATIVE); } void clear_not_c1_compilable() { atomic_clear_bits(JVM_ACC_NOT_C1_COMPILABLE); } diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp index 99c84a6ddfe..632b7c656b2 100644 --- a/hotspot/src/share/vm/utilities/array.hpp +++ b/hotspot/src/share/vm/utilities/array.hpp @@ -376,7 +376,7 @@ protected: // FIXME: How to handle this? void print_value_on(outputStream* st) const { - st->print("Array(" INTPTR_FORMAT ")", this); + st->print("Array(" INTPTR_FORMAT ")", p2i(this)); } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/utilities/bitMap.cpp b/hotspot/src/share/vm/utilities/bitMap.cpp index 024e35e374d..bfcda11fdea 100644 --- a/hotspot/src/share/vm/utilities/bitMap.cpp +++ b/hotspot/src/share/vm/utilities/bitMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -522,13 +522,13 @@ BitMap::idx_t BitMap::count_one_bits() const { void BitMap::print_on_error(outputStream* st, const char* prefix) const { st->print_cr("%s[" PTR_FORMAT ", " PTR_FORMAT ")", - prefix, map(), (char*)map() + (size() >> LogBitsPerByte)); + prefix, p2i(map()), p2i((char*)map() + (size() >> LogBitsPerByte))); } #ifndef PRODUCT void BitMap::print_on(outputStream* st) const { - tty->print("Bitmap(%d):", size()); + tty->print("Bitmap(" SIZE_FORMAT "):", size()); for (idx_t index = 0; index < size(); index++) { tty->print("%c", at(index) ? '1' : '0'); } diff --git a/hotspot/src/share/vm/utilities/constantTag.cpp b/hotspot/src/share/vm/utilities/constantTag.cpp index 8f3b68a9b5d..1495a42e624 100644 --- a/hotspot/src/share/vm/utilities/constantTag.cpp +++ b/hotspot/src/share/vm/utilities/constantTag.cpp @@ -28,7 +28,7 @@ #ifndef PRODUCT void constantTag::print_on(outputStream* st) const { - st->print(internal_name()); + st->print("%s", internal_name()); } #endif // PRODUCT diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index 31d13f794b8..604018f8dd9 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,8 @@ # endif #endif // PRODUCT +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + FormatBufferResource::FormatBufferResource(const char * format, ...) : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) { va_list argp; @@ -96,6 +98,7 @@ FormatBufferResource::FormatBufferResource(const char * format, ...) va_end(argp); } +ATTRIBUTE_PRINTF(1, 2) void warning(const char* format, ...) { if (PrintWarnings) { FILE* const err = defaultStream::error_stream(); diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp index 310080dbb0e..9070fd80ee4 100644 --- a/hotspot/src/share/vm/utilities/debug.hpp +++ b/hotspot/src/share/vm/utilities/debug.hpp @@ -43,17 +43,17 @@ class FormatBufferBase { #define RES_BUFSZ 256 class FormatBufferResource : public FormatBufferBase { public: - FormatBufferResource(const char * format, ...); + FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); }; // Use stack for buffer template class FormatBuffer : public FormatBufferBase { public: - inline FormatBuffer(const char * format, ...); - inline void append(const char* format, ...); - inline void print(const char* format, ...); - inline void printv(const char* format, va_list ap); + inline FormatBuffer(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); char* buffer() { return _buf; } int size() { return bufsz; } @@ -223,7 +223,7 @@ void report_should_not_reach_here(const char* file, int line); void report_unimplemented(const char* file, int line); void report_untested(const char* file, int line, const char* message); -void warning(const char* format, ...); +void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2); #ifdef ASSERT // Compile-time asserts. diff --git a/hotspot/src/share/vm/utilities/events.cpp b/hotspot/src/share/vm/utilities/events.cpp index 8ccd65095e4..4d17c9bba42 100644 --- a/hotspot/src/share/vm/utilities/events.cpp +++ b/hotspot/src/share/vm/utilities/events.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ EventMark::EventMark(const char* format, ...) { va_start(ap, format); // Save a copy of begin message and log it. _buffer.printv(format, ap); - Events::log(NULL, _buffer); + Events::log(NULL, "%s", _buffer.buffer()); va_end(ap); } } @@ -91,6 +91,6 @@ EventMark::~EventMark() { if (LogEvents) { // Append " done" to the begin message and log it _buffer.append(" done"); - Events::log(NULL, _buffer); + Events::log(NULL, "%s", _buffer.buffer()); } } diff --git a/hotspot/src/share/vm/utilities/events.hpp b/hotspot/src/share/vm/utilities/events.hpp index 804fe77df2d..71a4a436694 100644 --- a/hotspot/src/share/vm/utilities/events.hpp +++ b/hotspot/src/share/vm/utilities/events.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,7 +128,7 @@ template class EventLogBase : public EventLog { void print(outputStream* out, EventRecord& e) { out->print("Event: %.3f ", e.timestamp); if (e.thread != NULL) { - out->print("Thread " INTPTR_FORMAT " ", e.thread); + out->print("Thread " INTPTR_FORMAT " ", p2i(e.thread)); } print(out, e.data); } @@ -148,7 +148,7 @@ class StringEventLog : public EventLogBase { public: StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase(name, count) {} - void logv(Thread* thread, const char* format, va_list ap) { + void logv(Thread* thread, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0) { if (!should_log()) return; double timestamp = fetch_timestamp(); @@ -159,7 +159,7 @@ class StringEventLog : public EventLogBase { _records[index].data.printv(format, ap); } - void log(Thread* thread, const char* format, ...) { + void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(3, 4) { va_list ap; va_start(ap, format); logv(thread, format, ap); @@ -193,18 +193,17 @@ class Events : AllStatic { static void print(); // Logs a generic message with timestamp and format as printf. - static void log(Thread* thread, const char* format, ...); + static void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // Log exception related message - static void log_exception(Thread* thread, const char* format, ...); + static void log_exception(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); - static void log_deopt_message(Thread* thread, const char* format, ...); + static void log_deopt_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // Register default loggers static void init(); }; - inline void Events::log(Thread* thread, const char* format, ...) { if (LogEvents) { va_list ap; @@ -283,7 +282,7 @@ class EventMark : public StackObj { public: // log a begin event, format as printf - EventMark(const char* format, ...); + EventMark(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // log an end event ~EventMark(); }; diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp index e3d08d5946f..0759eda3789 100644 --- a/hotspot/src/share/vm/utilities/exceptions.cpp +++ b/hotspot/src/share/vm/utilities/exceptions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "utilities/events.hpp" #include "utilities/exceptions.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC // Implementation of ThreadShadow void check_ThreadShadow() { @@ -237,6 +238,7 @@ void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_na _throw_msg(thread, file, line, h_name, msg); } + // Creates an exception oop, calls the method with the given signature. // and returns a Handle Handle Exceptions::new_exception(Thread *thread, Symbol* name, diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp index 504d4caf5e3..52805805d59 100644 --- a/hotspot/src/share/vm/utilities/exceptions.hpp +++ b/hotspot/src/share/vm/utilities/exceptions.hpp @@ -132,7 +132,7 @@ class Exceptions { // There is no THROW... macro for this method. Caller should remember // to do a return after calling it. static void fthrow(Thread* thread, const char* file, int line, Symbol* name, - const char* format, ...); + const char* format, ...) ATTRIBUTE_PRINTF(5, 6); // Create and initialize a new exception static Handle new_exception(Thread* thread, Symbol* name, diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index ca9bc2f16a6..2bbd31afb76 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,32 @@ # include "utilities/globalDefinitions_xlc.hpp" #endif +#ifndef PRAGMA_DIAG_PUSH +#define PRAGMA_DIAG_PUSH +#endif +#ifndef PRAGMA_DIAG_POP +#define PRAGMA_DIAG_POP +#endif +#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED +#define PRAGMA_FORMAT_NONLITERAL_IGNORED +#endif +#ifndef PRAGMA_FORMAT_IGNORED +#define PRAGMA_FORMAT_IGNORED +#endif +#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL +#endif +#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL +#endif +#ifndef PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC +#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC +#endif +#ifndef ATTRIBUTE_PRINTF +#define ATTRIBUTE_PRINTF(fmt, vargs) +#endif + + #include "utilities/macros.hpp" // This file holds all globally used constants & types, class (forward) @@ -1284,6 +1310,11 @@ inline int build_int_from_shorts( jushort low, jushort high ) { return ((int)((unsigned int)high << 16) | (unsigned int)low); } +// Convert pointer to intptr_t, for use in printing pointers. +inline intptr_t p2i(const void * p) { + return (intptr_t) p; +} + // Printf-style formatters for fixed- and variable-width types as pointers and // integers. These are derived from the definitions in inttypes.h. If the platform // doesn't provide appropriate definitions, they should be provided in @@ -1302,6 +1333,7 @@ inline int build_int_from_shorts( jushort low, jushort high ) { // Format 64-bit quantities. #define INT64_FORMAT "%" PRId64 #define UINT64_FORMAT "%" PRIu64 +#define UINT64_FORMAT_X "%" PRIx64 #define INT64_FORMAT_W(width) "%" #width PRId64 #define UINT64_FORMAT_W(width) "%" #width PRIu64 @@ -1314,6 +1346,9 @@ inline int build_int_from_shorts( jushort low, jushort high ) { #ifndef JULONG_FORMAT #define JULONG_FORMAT UINT64_FORMAT #endif +#ifndef JULONG_FORMAT_X +#define JULONG_FORMAT_X UINT64_FORMAT_X +#endif // Format pointers which change size between 32- and 64-bit. #ifdef _LP64 @@ -1324,6 +1359,8 @@ inline int build_int_from_shorts( jushort low, jushort high ) { #define PTR_FORMAT "0x%08" PRIxPTR #endif // _LP64 +#define INTPTR_FORMAT_W(width) "%" #width PRIxPTR + #define SSIZE_FORMAT "%" PRIdPTR #define SIZE_FORMAT "%" PRIuPTR #define SIZE_FORMAT_HEX "0x%" PRIxPTR @@ -1351,11 +1388,10 @@ inline int build_int_from_shorts( jushort low, jushort high ) { // All C++ compilers that we know of have the vtbl pointer in the first // word. If there are exceptions, this function needs to be made compiler // specific. -static inline void* dereference_vptr(void* addr) { +static inline void* dereference_vptr(const void* addr) { return *(void**)addr; } - #ifndef PRODUCT // For unit testing only diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp index f66fb721e3a..22e5d277c81 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -282,6 +282,47 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } #define PRAGMA_IMPLEMENTATION #pragma implementation #define VALUE_OBJ_CLASS_SPEC +#ifndef ATTRIBUTE_PRINTF +// Diagnostic pragmas like the ones defined below in PRAGMA_FORMAT_NONLITERAL_IGNORED +// were only introduced in GCC 4.2. Because we have no other possibility to ignore +// these warnings for older versions of GCC, we simply don't decorate our printf-style +// functions with __attribute__(format) in that case. +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ > 4) +#define ATTRIBUTE_PRINTF(fmt,vargs) __attribute__((format(printf, fmt, vargs))) +#else +#define ATTRIBUTE_PRINTF(fmt,vargs) +#endif +#endif + +#define PRAGMA_FORMAT_NONLITERAL_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") \ + _Pragma("GCC diagnostic ignored \"-Wformat-security\"") +#define PRAGMA_FORMAT_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat\"") + +#if defined(__clang_major__) && \ + (__clang_major__ >= 4 || \ + (__clang_major__ >= 3 && __clang_minor__ >= 1)) || \ + ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) +// Tested to work with clang version 3.1 and better. +#define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push") +#define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop") +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED + +// Hack to deal with gcc yammering about non-security format stuff +#else +// Old versions of gcc don't do push/pop, also do not cope with this pragma within a function +// One method does so much varied printing that it is decorated with both internal and external +// versions of the macro-pragma to obtain better checking with newer compilers. +#define PRAGMA_DIAG_PUSH +#define PRAGMA_DIAG_POP +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED +#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL +#endif + +#ifndef __clang_major__ +#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC _Pragma("GCC diagnostic ignored \"-Wformat\"") _Pragma("GCC diagnostic error \"-Wformat-nonliteral\"") _Pragma("GCC diagnostic error \"-Wformat-security\"") +#endif + #if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) #define TEMPLATE_TABLE_BUG #endif diff --git a/hotspot/src/share/vm/utilities/hashtable.cpp b/hotspot/src/share/vm/utilities/hashtable.cpp index 8698cca914a..c0c73c425fc 100644 --- a/hotspot/src/share/vm/utilities/hashtable.cpp +++ b/hotspot/src/share/vm/utilities/hashtable.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "classfile/javaClasses.hpp" +#include "classfile/stringTable.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" #include "memory/resourceArea.hpp" diff --git a/hotspot/src/share/vm/utilities/numberSeq.cpp b/hotspot/src/share/vm/utilities/numberSeq.cpp index 06fcf40b7a8..230447b2167 100644 --- a/hotspot/src/share/vm/utilities/numberSeq.cpp +++ b/hotspot/src/share/vm/utilities/numberSeq.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -258,5 +258,5 @@ void TruncatedSeq::dump_on(outputStream* s) { } s->print("\t[%d]=%7.3f", i, _sequence[i]); } - s->print_cr(""); + s->cr(); } diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index e09dfccf123..54536c50742 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -268,7 +268,7 @@ void outputStream::print_data(void* data, size_t len, bool with_ascii) { size_t limit = (len + 16) / 16 * 16; for (size_t i = 0; i < limit; ++i) { if (i % 16 == 0) { - indent().print("%07x:", i); + indent().print(INTPTR_FORMAT_W(07)":", i); } if (i % 2 == 0) { print(" "); @@ -289,7 +289,7 @@ void outputStream::print_data(void* data, size_t len, bool with_ascii) { } } } - print_cr(""); + cr(); } } } @@ -606,7 +606,7 @@ void fdStream::write(const char* s, size_t len) { // memory usage and command line flags into header void gcLogFileStream::dump_loggc_header() { if (is_open()) { - print_cr(Abstract_VM_Version::internal_vm_info_string()); + print_cr("%s", Abstract_VM_Version::internal_vm_info_string()); os::print_memory_info(this); print("CommandLine flags: "); CommandLineFlags::printSetFlags(this); @@ -687,7 +687,7 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) { write(time_msg, strlen(time_msg)); if (out != NULL) { - out->print(time_msg); + out->print("%s", time_msg); } dump_loggc_header(); @@ -720,7 +720,7 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) { write(time_msg, strlen(time_msg)); if (out != NULL) { - out->print(time_msg); + out->print("%s", time_msg); } fclose(_file); @@ -765,7 +765,7 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) { write(time_msg, strlen(time_msg)); if (out != NULL) { - out->print(time_msg); + out->print("%s", time_msg); } dump_loggc_header(); @@ -845,7 +845,7 @@ void defaultStream::init_log() { xs->head("hotspot_log version='%d %d'" " process='%d' time_ms='"INT64_FORMAT"'", LOG_MAJOR_VERSION, LOG_MINOR_VERSION, - os::current_process_id(), time_ms); + os::current_process_id(), (int64_t)time_ms); // Write VM version header immediately. xs->head("vm_version"); xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr(); diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp index 92440ee0a64..563bbe432b5 100644 --- a/hotspot/src/share/vm/utilities/ostream.hpp +++ b/hotspot/src/share/vm/utilities/ostream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ class outputStream : public ResourceObj { static const char* do_vsnprintf(char* buffer, size_t buflen, const char* format, va_list ap, bool add_cr, - size_t& result_len); + size_t& result_len) ATTRIBUTE_PRINTF(3, 0); public: // creation @@ -80,10 +80,10 @@ class outputStream : public ResourceObj { void set_position(int pos) { _position = pos; } // printing - void print(const char* format, ...); - void print_cr(const char* format, ...); - void vprint(const char *format, va_list argptr); - void vprint_cr(const char* format, va_list argptr); + void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); + void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); void print_raw(const char* str) { write(str, strlen(str)); } void print_raw(const char* str, int len) { write(str, len); } void print_raw_cr(const char* str) { write(str, strlen(str)); cr(); } @@ -274,10 +274,10 @@ class staticBufferStream : public outputStream { ~staticBufferStream() {}; virtual void write(const char* c, size_t len); void flush(); - void print(const char* format, ...); - void print_cr(const char* format, ...); - void vprint(const char *format, va_list argptr); - void vprint_cr(const char* format, va_list argptr); + void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); + void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); }; // In the non-fixed buffer case an underlying buffer will be created and diff --git a/hotspot/src/share/vm/utilities/quickSort.cpp b/hotspot/src/share/vm/utilities/quickSort.cpp index 0cb7f6ef833..de008877989 100644 --- a/hotspot/src/share/vm/utilities/quickSort.cpp +++ b/hotspot/src/share/vm/utilities/quickSort.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ void QuickSort::print_array(const char* prefix, int* array, int length) { for (int i = 0; i < length; i++) { tty->print(" %d", array[i]); } - tty->print_cr(""); + tty->cr(); } bool QuickSort::compare_arrays(int* actual, int* expected, int length) { diff --git a/hotspot/src/share/vm/utilities/taskqueue.cpp b/hotspot/src/share/vm/utilities/taskqueue.cpp index 2811c84d75d..a3daa8847b6 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.cpp +++ b/hotspot/src/share/vm/utilities/taskqueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ #include "utilities/stack.inline.hpp" #include "utilities/taskqueue.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + #ifdef TRACESPINNING uint ParallelTaskTerminator::_total_yields = 0; uint ParallelTaskTerminator::_total_spins = 0; diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index 097e28de9c5..62d8ba6b176 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,8 @@ #include "utilities/top.hpp" #include "utilities/vmError.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // List of environment variables that should be reported in error log file. const char *env_list[] = { // All platforms @@ -358,17 +360,17 @@ void VMError::report(outputStream* st) { st->print((_id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " : "(mmap) failed to map "); jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size); - st->print(buf); + st->print("%s", buf); st->print(" bytes"); if (_message != NULL) { st->print(" for "); - st->print(_message); + st->print("%s", _message); } st->cr(); } else { if (_message != NULL) st->print("# "); - st->print_cr(_message); + st->print_cr("%s", _message); } // In error file give some solutions if (_verbose) { @@ -485,7 +487,7 @@ void VMError::report(outputStream* st) { } else { st->print("Failed to write core dump. %s", coredump_message); } - st->print_cr(""); + st->cr(); st->print_cr("#"); STEP(65, "(printing bug submit message)") diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp index 479cd04029a..3d1f1eef7a6 100644 --- a/hotspot/src/share/vm/utilities/workgroup.cpp +++ b/hotspot/src/share/vm/utilities/workgroup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ #include "runtime/os.hpp" #include "utilities/workgroup.hpp" +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + // Definitions of WorkGang methods. AbstractWorkGang::AbstractWorkGang(const char* name, @@ -376,21 +378,22 @@ const char* AbstractGangTask::name() const { WorkGangBarrierSync::WorkGangBarrierSync() : _monitor(Mutex::safepoint, "work gang barrier sync", true), - _n_workers(0), _n_completed(0), _should_reset(false) { + _n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) { } WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name) : _monitor(Mutex::safepoint, name, true), - _n_workers(n_workers), _n_completed(0), _should_reset(false) { + _n_workers(n_workers), _n_completed(0), _should_reset(false), _aborted(false) { } void WorkGangBarrierSync::set_n_workers(uint n_workers) { - _n_workers = n_workers; - _n_completed = 0; + _n_workers = n_workers; + _n_completed = 0; _should_reset = false; + _aborted = false; } -void WorkGangBarrierSync::enter() { +bool WorkGangBarrierSync::enter() { MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag); if (should_reset()) { // The should_reset() was set and we are the first worker to enter @@ -413,10 +416,17 @@ void WorkGangBarrierSync::enter() { set_should_reset(true); monitor()->notify_all(); } else { - while (n_completed() != n_workers()) { + while (n_completed() != n_workers() && !aborted()) { monitor()->wait(/* no_safepoint_check */ true); } } + return !aborted(); +} + +void WorkGangBarrierSync::abort() { + MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag); + set_aborted(); + monitor()->notify_all(); } // SubTasksDone functions. diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp index e1184a67972..30337f1ef50 100644 --- a/hotspot/src/share/vm/utilities/workgroup.hpp +++ b/hotspot/src/share/vm/utilities/workgroup.hpp @@ -359,18 +359,20 @@ class FlexibleWorkGang: public WorkGang { class WorkGangBarrierSync : public StackObj { protected: Monitor _monitor; - uint _n_workers; - uint _n_completed; + uint _n_workers; + uint _n_completed; bool _should_reset; + bool _aborted; Monitor* monitor() { return &_monitor; } uint n_workers() { return _n_workers; } uint n_completed() { return _n_completed; } bool should_reset() { return _should_reset; } + bool aborted() { return _aborted; } void zero_completed() { _n_completed = 0; } void inc_completed() { _n_completed++; } - + void set_aborted() { _aborted = true; } void set_should_reset(bool v) { _should_reset = v; } public: @@ -383,8 +385,14 @@ public: // Enter the barrier. A worker that enters the barrier will // not be allowed to leave until all other threads have - // also entered the barrier. - void enter(); + // also entered the barrier or the barrier is aborted. + // Returns false if the barrier was aborted. + bool enter(); + + // Aborts the barrier and wakes up any threads waiting for + // the barrier to complete. The barrier will remain in the + // aborted state until the next call to set_n_workers(). + void abort(); }; // A class to manage claiming of subtasks within a group of tasks. The diff --git a/hotspot/src/share/vm/utilities/xmlstream.cpp b/hotspot/src/share/vm/utilities/xmlstream.cpp index e6714e15a86..785f927b10e 100644 --- a/hotspot/src/share/vm/utilities/xmlstream.cpp +++ b/hotspot/src/share/vm/utilities/xmlstream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -336,6 +336,8 @@ void xmlStream::done_raw(const char* kind) { print_raw_cr(">"); } +PRAGMA_DIAG_PUSH +PRAGMA_FORMAT_NONLITERAL_IGNORED // ------------------------------------------------------------------ void xmlStream::va_done(const char* format, va_list ap) { char buffer[200]; @@ -354,6 +356,7 @@ void xmlStream::va_done(const char* format, va_list ap) { buffer[kind_len] = 0; tail(buffer); } +PRAGMA_DIAG_POP // Output a timestamp attribute. void xmlStream::stamp() { @@ -399,7 +402,7 @@ void xmlStream::method_text(methodHandle method) { ResourceMark rm; assert_if_no_error(inside_attrs(), "printing attributes"); if (method.is_null()) return; - text()->print(method->method_holder()->external_name()); + text()->print("%s", method->method_holder()->external_name()); print_raw(" "); // " " is easier for tools to parse than "::" method->name()->print_symbol_on(text()); print_raw(" "); // separator diff --git a/hotspot/src/share/vm/utilities/xmlstream.hpp b/hotspot/src/share/vm/utilities/xmlstream.hpp index 7ab93744b27..22a12cacda3 100644 --- a/hotspot/src/share/vm/utilities/xmlstream.hpp +++ b/hotspot/src/share/vm/utilities/xmlstream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ class xmlStream : public outputStream { outputStream* out() { return _out; } // helpers for writing XML elements - void va_tag(bool push, const char* format, va_list ap); + void va_tag(bool push, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0); virtual void see_tag(const char* tag, bool push) NOT_DEBUG({}); virtual void pop_tag(const char* tag) NOT_DEBUG({}); @@ -109,29 +109,29 @@ class xmlStream : public outputStream { int unflushed_count() { return (int)(out()->count() - _last_flush); } // writing complete XML elements - void elem(const char* format, ...); - void begin_elem(const char* format, ...); - void end_elem(const char* format, ...); + void elem(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void begin_elem(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void end_elem(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void end_elem(); - void head(const char* format, ...); - void begin_head(const char* format, ...); - void end_head(const char* format, ...); + void head(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void begin_head(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void end_head(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); void end_head(); - void done(const char* format, ...); // xxx_done event, plus tail + void done(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); // xxx_done event, plus tail void done_raw(const char * kind); void tail(const char* kind); // va_list versions - void va_elem(const char* format, va_list ap); - void va_begin_elem(const char* format, va_list ap); - void va_head(const char* format, va_list ap); - void va_begin_head(const char* format, va_list ap); - void va_done(const char* format, va_list ap); + void va_elem(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_begin_elem(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_head(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_begin_head(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + void va_done(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); // write text (with quoting of special XML characters <>&'" etc.) outputStream* text() { return _text; } - void text(const char* format, ...); - void va_text(const char* format, va_list ap) { + void text(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + void va_text(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0) { text()->vprint(format, ap); } diff --git a/hotspot/test/Makefile b/hotspot/test/Makefile index f29ef326c1d..f81cc8d64df 100644 --- a/hotspot/test/Makefile +++ b/hotspot/test/Makefile @@ -147,6 +147,11 @@ BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} ) all: jtreg_tests @$(ECHO) "Testing completed successfully" +# Support "hotspot_" prefixed test make targets too +# The hotspot_% targets are for example invoked by the top level Makefile +hotspot_%: + $(MAKE) $* + # Prep for output prep: clean @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 1053faa7f16..8c2db990110 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -66,7 +66,6 @@ needs_jdk = \ gc/metaspace/TestMetaspacePerfCounters.java \ gc/metaspace/TestPerfCountersAndMemoryPools.java \ runtime/6819213/TestBootNativeLibraryPath.java \ - runtime/6925573/SortMethodsTest.java \ runtime/7158988/FieldMonitor.java \ runtime/7194254/Test7194254.java \ runtime/Metaspace/FragmentMetaspace.java \ @@ -84,6 +83,7 @@ needs_jdk = \ runtime/RedefineObject/TestRedefineObject.java \ runtime/XCheckJniJsig/XCheckJSig.java \ serviceability/attach/AttachWithStalePidFile.java \ + serviceability/jvmti/8036666/GetObjectLockCount.java \ serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \ serviceability/dcmd/DynLibDcmdTest.java @@ -135,9 +135,12 @@ needs_compact3 = \ gc/parallelScavenge/TestDynShrinkHeap.java \ runtime/InternalApi/ThreadCpuTimesDeadlock.java \ serviceability/threads/TestFalseDeadLock.java \ + serviceability/jvmti/GetObjectSizeOverflow.java \ + serviceability/jvmti/TestRedefineWithUnresolvedClass.java \ compiler/tiered/NonTieredLevelsTest.java \ compiler/tiered/TieredLevelsTest.java \ - compiler/intrinsics/bmi/verifycode + compiler/intrinsics/bmi/verifycode \ + runtime/whitebox/WBStackSize.java # Compact 2 adds full VM tests compact2 = \ diff --git a/hotspot/test/compiler/5091921/Test7005594.java b/hotspot/test/compiler/5091921/Test7005594.java index 4a23be13702..32e8bae93a4 100644 --- a/hotspot/test/compiler/5091921/Test7005594.java +++ b/hotspot/test/compiler/5091921/Test7005594.java @@ -25,7 +25,6 @@ /** * @test * @bug 7005594 - * @ignore 7117034 * @summary Array overflow not handled correctly with loop optimzations * * @run shell Test7005594.sh diff --git a/hotspot/test/compiler/5091921/Test7005594.sh b/hotspot/test/compiler/5091921/Test7005594.sh index 8d9fc36ead7..2ca434ae876 100644 --- a/hotspot/test/compiler/5091921/Test7005594.sh +++ b/hotspot/test/compiler/5091921/Test7005594.sh @@ -78,7 +78,7 @@ cp ${TESTSRC}/Test7005594.sh . ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java -${TESTJAVA}/bin/java ${TESTVMOPTS} -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1 +${TESTJAVA}/bin/java ${TESTVMOPTS} -Xmx1600m -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1 result=$? @@ -97,7 +97,7 @@ then fi # The test should pass when no enough space for object heap -grep "Could not reserve enough space for object heap" test.out +grep "Could not reserve enough space for .*object heap" test.out if [ $? = 0 ] then echo "Passed" diff --git a/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java b/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java new file mode 100644 index 00000000000..04dea1e3934 --- /dev/null +++ b/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014 Google, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8043354 + * @summary bcEscapeAnalyzer allocated_escapes not conservative enough + * @run main/othervm -XX:CompileOnly=.visitAndPop TestAllocatedEscapesPtrComparison + * @author Chuck Rasbold rasbold@google.com + */ + +/* + * Test always passes with -XX:-OptmimizePtrCompare + */ + +import java.util.ArrayList; +import java.util.List; + +public class TestAllocatedEscapesPtrComparison { + + static TestAllocatedEscapesPtrComparison dummy; + + class Marker { + } + + List markerList = new ArrayList<>(); + + // Suppress compilation of this method, it must be processed + // by the bytecode escape analyzer. + + // Make a new marker and put it on the List + Marker getMarker() { + // result escapes through markerList + final Marker result = new Marker(); + markerList.add(result); + return result; + } + + void visit(int depth) { + // Make a new marker + getMarker(); + + // Call visitAndPop every once in a while + // Cap the depth of our recursive visits + if (depth % 10 == 2) { + visitAndPop(depth + 1); + } else if (depth < 15) { + visit(depth + 1); + } + } + + void visitAndPop(int depth) { + // Random dummy allocation to force EscapeAnalysis to process this method + dummy = new TestAllocatedEscapesPtrComparison(); + + // Make a new marker + Marker marker = getMarker(); + + visit(depth + 1); + + // Walk and pop the marker list up to the current marker + boolean found = false; + for (int i = markerList.size() - 1; i >= 0; i--) { + Marker removed = markerList.remove(i); + + // In the failure, EA mistakenly converts this comparison to false + if (removed == marker) { + found = true; + break; + } + } + + if (!found) { + throw new RuntimeException("test fails"); + } + } + + + public static void main(String args[]) { + TestAllocatedEscapesPtrComparison tc = new TestAllocatedEscapesPtrComparison(); + + // Warmup and run enough times + for (int i = 0; i < 20000; i++) { + tc.visit(0); + } + } +} diff --git a/hotspot/test/compiler/arguments/BMICommandLineOptionTestBase.java b/hotspot/test/compiler/arguments/BMICommandLineOptionTestBase.java index 6d4fa400dda..ec27615fba3 100644 --- a/hotspot/test/compiler/arguments/BMICommandLineOptionTestBase.java +++ b/hotspot/test/compiler/arguments/BMICommandLineOptionTestBase.java @@ -25,6 +25,12 @@ import com.oracle.java.testlibrary.cli.*; /** * Base class for all X86 bit manipulation related command line options. + * + * Note that this test intended to verify that VM could be launched with + * specific options and that values of these options processed correctly. + * In order to do that test launch a new VM with tested options, the same + * flavor-specific flag as one that was used for parent VM (-client, -server, + * -minimal, -graal) and '-version'. */ public abstract class BMICommandLineOptionTestBase extends CPUSpecificCommandLineOptionTest { @@ -58,10 +64,11 @@ public abstract class BMICommandLineOptionTestBase String supportedCPUFeatures[], String unsupportedCPUFeatures[]) { super(".*", supportedCPUFeatures, unsupportedCPUFeatures); - this.optionName = optionName; - this.warningMessage = warningMessage; - this.errorMessage = CommandLineOptionTest. - UNRECOGNIZED_OPTION_ERROR_FORMAT.format(optionName); + this.optionName = optionName; + this.warningMessage = warningMessage; + this.errorMessage = String.format( + CommandLineOptionTest.UNRECOGNIZED_OPTION_ERROR_FORMAT, + optionName); } } diff --git a/hotspot/test/compiler/arguments/BMISupportedCPUTest.java b/hotspot/test/compiler/arguments/BMISupportedCPUTest.java index c0af31fd766..df6e1540918 100644 --- a/hotspot/test/compiler/arguments/BMISupportedCPUTest.java +++ b/hotspot/test/compiler/arguments/BMISupportedCPUTest.java @@ -28,6 +28,12 @@ import com.oracle.java.testlibrary.cli.*; * Test on bit manipulation related command line options, * that should be executed on CPU that supports all required * features. + * + * Note that this test intended to verify that VM could be launched with + * specific options and that values of these options processed correctly. + * In order to do that test launch a new VM with tested options, the same + * flavor-specific flag as one that was used for parent VM (-client, -server, + * -minimal, -graal) and '-version'. */ public class BMISupportedCPUTest extends BMICommandLineOptionTestBase { @@ -49,24 +55,38 @@ public class BMISupportedCPUTest extends BMICommandLineOptionTestBase { @Override public void runTestCases() throws Throwable { - // verify that VM will succesfully start up whithout warnings - CommandLineOptionTest. - verifyJVMStartup("-XX:+" + optionName, - null, new String[] { warningMessage }, - ExitCode.OK); + /* + Verify that VM will successfully start up without warnings. + VM will be launched with following flags: + -XX:+ -version + */ + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { warningMessage }, ExitCode.OK, + CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - // verify that VM will succesfully start up whithout warnings - CommandLineOptionTest. - verifyJVMStartup("-XX:-" + optionName, - null, new String[] { warningMessage }, - ExitCode.OK); + /* + Verify that VM will successfully start up without warnings. + VM will be launched with following flags: + -XX:- -version + */ + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { warningMessage }, ExitCode.OK, + CommandLineOptionTest.prepareBooleanFlag(optionName, false)); - // verify that on appropriate CPU option in on by default - CommandLineOptionTest.verifyOptionValue(optionName, "true"); + /* + Verify that on appropriate CPU option in on by default. + VM will be launched with following flags: + -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true"); - // verify that option could be explicitly turned off - CommandLineOptionTest.verifyOptionValue(optionName, "false", - "-XX:-" + optionName); + /* + Verify that option could be explicitly turned off. + VM will be launched with following flags: + -XX:- -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } } diff --git a/hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java b/hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java index 7a78c74e579..93fbcb29687 100644 --- a/hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java +++ b/hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java @@ -28,6 +28,12 @@ import com.oracle.java.testlibrary.cli.*; * Test on bit manipulation related command line options, * that should be executed on CPU that does not support * required features. + * + * Note that this test intended to verify that VM could be launched with + * specific options and that values of these options processed correctly. + * In order to do that test launch a new VM with tested options, the same + * flavor-specific flag as one that was used for parent VM (-client, -server, + * -minimal, -graal) and '-version'. */ public class BMIUnsupportedCPUTest extends BMICommandLineOptionTestBase { @@ -64,28 +70,38 @@ public class BMIUnsupportedCPUTest extends BMICommandLineOptionTestBase { */ public void unsupportedX86CPUTestCases() throws Throwable { - // verify that VM will succesfully start up, but output will - // contain a warning - CommandLineOptionTest. - verifyJVMStartup("-XX:+" + optionName, - new String[] { warningMessage }, - new String[] { errorMessage }, - ExitCode.OK); + /* + Verify that VM will successfully start up, but output will contain a + warning. VM will be launched with following options: + -XX:+ -version + */ + CommandLineOptionTest.verifySameJVMStartup( + new String[] { warningMessage }, new String[] { errorMessage }, + ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag( + optionName, true)); - // verify that VM will succesfully startup without any warnings - CommandLineOptionTest. - verifyJVMStartup("-XX:-" + optionName, - null, - new String[] { warningMessage, errorMessage }, - ExitCode.OK); + /* + Verify that VM will successfully startup without any warnings. + VM will be launched with following options: + -XX:- -version + */ + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { warningMessage, errorMessage }, ExitCode.OK, + CommandLineOptionTest.prepareBooleanFlag(optionName, false)); - // verify that on unsupported CPUs option is off by default - CommandLineOptionTest.verifyOptionValue(optionName, "false"); + /* + Verify that on unsupported CPUs option is off by default. + VM will be launched with following options: -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false"); - // verify that on unsupported CPUs option will be off even if - // it was explicitly turned on by uset - CommandLineOptionTest.verifyOptionValue(optionName, "false", - "-XX:+" + optionName); + /* + Verify that on unsupported CPUs option will be off even if + it was explicitly turned on by user. VM will be launched with + following options: -XX:+ -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + CommandLineOptionTest.prepareBooleanFlag(optionName, true)); } @@ -97,18 +113,17 @@ public class BMIUnsupportedCPUTest extends BMICommandLineOptionTestBase { */ public void unsupportedNonX86CPUTestCases() throws Throwable { - // verify that VM known nothing about tested option - CommandLineOptionTest. - verifyJVMStartup("-XX:+" + optionName, - new String[] { errorMessage }, - null, - ExitCode.FAIL); + /* + Verify that VM known nothing about tested option. VM will be launched + with following options: -XX:[+-] -version + */ + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, null, ExitCode.FAIL, + CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - CommandLineOptionTest. - verifyJVMStartup("-XX:-" + optionName, - new String[] { errorMessage }, - null, - ExitCode.FAIL); + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, null, ExitCode.FAIL, + CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } } diff --git a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java index 995d450e365..d6628b1ed0c 100644 --- a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java @@ -40,7 +40,8 @@ import com.oracle.java.testlibrary.*; import com.oracle.java.testlibrary.cli.*; public class TestUseCountTrailingZerosInstructionOnSupportedCPU - extends BMISupportedCPUTest { + extends BMISupportedCPUTest { + private static final String DISABLE_BMI = "-XX:-UseBMI1Instructions"; public TestUseCountTrailingZerosInstructionOnSupportedCPU() { super("UseCountTrailingZerosInstruction", TZCNT_WARNING, "bmi1"); @@ -51,18 +52,23 @@ public class TestUseCountTrailingZerosInstructionOnSupportedCPU super.runTestCases(); - // verify that option will be disabled if all BMI1 instuctions - // are explicitly disabled - CommandLineOptionTest. - verifyOptionValue("UseCountTrailingZerosInstruction", "false", - "-XX:-UseBMI1Instructions"); + /* + Verify that option will be disabled if all BMI1 instructions + are explicitly disabled. VM will be launched with following options: + -XX:-UseBMI1Instructions -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + TestUseCountTrailingZerosInstructionOnSupportedCPU.DISABLE_BMI); - // verify that option could be turned on even if other BMI1 - // instructions were turned off - CommandLineOptionTest. - verifyOptionValue("UseCountTrailingZerosInstruction", "true", - "-XX:-UseBMI1Instructions", - "-XX:+UseCountTrailingZerosInstruction"); + /* + Verify that option could be turned on even if other BMI1 + instructions were turned off. VM will be launched with following + options: -XX:-UseBMI1Instructions + -XX:+UseCountTrailingZerosInstruction -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + TestUseCountTrailingZerosInstructionOnSupportedCPU.DISABLE_BMI, + CommandLineOptionTest.prepareBooleanFlag(optionName, true)); } public static void main(String args[]) throws Throwable { diff --git a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java index 86853aab0c5..67b6ea318ca 100644 --- a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java +++ b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java @@ -25,7 +25,7 @@ * @test * @bug 8031321 * @summary Verify processing of UseCountTrailingZerosInstruction option - * on CPU without TZCNT instuction (BMI1 feature) support. + * on CPU without TZCNT instruction (BMI1 feature) support. * @library /testlibrary /testlibrary/whitebox * @build TestUseCountTrailingZerosInstructionOnUnsupportedCPU * BMIUnsupportedCPUTest @@ -40,7 +40,8 @@ import com.oracle.java.testlibrary.*; import com.oracle.java.testlibrary.cli.*; public class TestUseCountTrailingZerosInstructionOnUnsupportedCPU - extends BMIUnsupportedCPUTest { + extends BMIUnsupportedCPUTest { + private static final String ENABLE_BMI = "-XX:+UseBMI1Instructions"; public TestUseCountTrailingZerosInstructionOnUnsupportedCPU() { super("UseCountTrailingZerosInstruction", TZCNT_WARNING, "bmi1"); @@ -51,16 +52,24 @@ public class TestUseCountTrailingZerosInstructionOnUnsupportedCPU super.unsupportedX86CPUTestCases(); - // verify that option will not be turned on during - // UseBMI1Instuctions processing - CommandLineOptionTest. - verifyOptionValue("UseCountTrailingZerosInstruction", "false", - "-XX:+UseBMI1Instructions"); + /* + Verify that option will not be turned on during UseBMI1Instructions + processing. VM will be launched with following options: + -XX:+UseBMI1Instructions -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + TestUseCountTrailingZerosInstructionOnUnsupportedCPU. + ENABLE_BMI); - CommandLineOptionTest. - verifyOptionValue("UseCountTrailingZerosInstruction", "false", - "-XX:+UseCountTrailingZerosInstruction", - "-XX:+UseBMI1Instructions"); + /* + VM will be launched with following options: + -XX:+UseCountTrailingZerosInstruction -XX:+UseBMI1Instructions + -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + CommandLineOptionTest.prepareBooleanFlag(optionName, true), + TestUseCountTrailingZerosInstructionOnUnsupportedCPU. + ENABLE_BMI); } public static void main(String args[]) throws Throwable { diff --git a/hotspot/test/compiler/ciReplay/TestVM.sh b/hotspot/test/compiler/ciReplay/TestVM.sh index bdb38748504..e58d63e16fa 100644 --- a/hotspot/test/compiler/ciReplay/TestVM.sh +++ b/hotspot/test/compiler/ciReplay/TestVM.sh @@ -26,7 +26,6 @@ ## ## @test ## @bug 8011675 -## @ignore 8032498 ## @summary testing of ciReplay with using generated by VM replay.txt ## @author igor.ignatyev@oracle.com ## @run shell TestVM.sh diff --git a/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh b/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh index 19f23583e6d..d961d42541d 100644 --- a/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh +++ b/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh @@ -26,7 +26,6 @@ ## ## @test ## @bug 8011675 -## @ignore 8032498 ## @summary testing of ciReplay with using generated by VM replay.txt w/o comp_level ## @author igor.ignatyev@oracle.com ## @run shell TestVM_no_comp_level.sh diff --git a/hotspot/test/compiler/ciReplay/common.sh b/hotspot/test/compiler/ciReplay/common.sh index f992ff39fc2..cf17febc4f7 100644 --- a/hotspot/test/compiler/ciReplay/common.sh +++ b/hotspot/test/compiler/ciReplay/common.sh @@ -234,6 +234,12 @@ generate_replay() { sed -e 's/.*location: //'` echo CRASH OUTPUT: cat crash.out + + if [ "${core_locations}" = "" ] + then + test_fail 2 "CHECK :: CORE_LOCATION" "output doesn't contain the location of core file, see crash.out" + fi + rm crash.out # processing core locations for *nix diff --git a/hotspot/test/compiler/uncommontrap/TestSpecTrapClassUnloading.java b/hotspot/test/compiler/uncommontrap/TestSpecTrapClassUnloading.java index fcdd592263d..ae700981216 100644 --- a/hotspot/test/compiler/uncommontrap/TestSpecTrapClassUnloading.java +++ b/hotspot/test/compiler/uncommontrap/TestSpecTrapClassUnloading.java @@ -25,7 +25,7 @@ * @test * @bug 8031752 * @summary speculative traps need to be cleaned up at GC - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:+UseTypeSpeculation -XX:TypeProfileLevel=222 -XX:CompileCommand=exclude,java.lang.reflect.Method::invoke -XX:CompileCommand=exclude,sun.reflect.DelegatingMethodAccessorImpl::invoke -Xmx1M TestSpecTrapClassUnloading + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:+UseTypeSpeculation -XX:TypeProfileLevel=222 -XX:CompileCommand=exclude,java.lang.reflect.Method::invoke -XX:CompileCommand=exclude,sun.reflect.DelegatingMethodAccessorImpl::invoke -Xmx512M TestSpecTrapClassUnloading * */ @@ -45,7 +45,7 @@ public class TestSpecTrapClassUnloading { MemoryChunk other; long[] array; MemoryChunk(MemoryChunk other) { - other = other; + this.other = other; array = new long[1024 * 1024 * 1024]; } } diff --git a/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java b/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java index 6d36106c43b..53728b8187b 100644 --- a/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java +++ b/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java @@ -21,6 +21,11 @@ * questions. */ +import static com.oracle.java.testlibrary.Asserts.assertEQ; +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import com.oracle.java.testlibrary.DynamicVMOption; + /** * @test TestDynMaxHeapFreeRatio * @bug 8028391 @@ -33,32 +38,45 @@ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMaxHeapFreeRatio * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMaxHeapFreeRatio */ -import com.oracle.java.testlibrary.TestDynamicVMOption; -import com.oracle.java.testlibrary.DynamicVMOptionChecker; - -public class TestDynMaxHeapFreeRatio extends TestDynamicVMOption { - - public static final String MinFreeRatioFlagName = "MinHeapFreeRatio"; - public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio"; - - public TestDynMaxHeapFreeRatio() { - super(MaxFreeRatioFlagName); - } - - public void test() { - - int minHeapFreeValue = DynamicVMOptionChecker.getIntValue(MinFreeRatioFlagName); - System.out.println(MinFreeRatioFlagName + " = " + minHeapFreeValue); - - testPercentageValues(); - - checkInvalidValue(Integer.toString(minHeapFreeValue - 1)); - checkValidValue(Integer.toString(minHeapFreeValue)); - checkValidValue("100"); - } +public class TestDynMaxHeapFreeRatio { public static void main(String args[]) throws Exception { - new TestDynMaxHeapFreeRatio().test(); - } + // low boundary value + int minValue = DynamicVMOption.getInt("MinHeapFreeRatio"); + System.out.println("MinHeapFreeRatio= " + minValue); + + String badValues[] = { + null, + "", + "not a number", + "8.5", "-0.01", + Integer.toString(Integer.MIN_VALUE), + Integer.toString(Integer.MAX_VALUE), + Integer.toString(minValue - 1), + "-1024", "-1", "101", "1997" + }; + + String goodValues[] = { + Integer.toString(minValue), + Integer.toString(minValue + 1), + Integer.toString((minValue + 100) / 2), + "99", "100" + }; + + DynamicVMOption option = new DynamicVMOption("MaxHeapFreeRatio"); + + assertTrue(option.isWriteable(), "Option " + option.name + + " is expected to be writable"); + + for (String v : badValues) { + assertFalse(option.isValidValue(v), + "'" + v + "' is expected to be illegal for flag " + option.name); + } + for (String v : goodValues) { + option.setValue(v); + String newValue = option.getValue(); + assertEQ(v, newValue); + } + } } diff --git a/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java b/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java index 13132f04d38..bbf0ecf3f5f 100644 --- a/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java +++ b/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java @@ -33,30 +33,52 @@ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMinHeapFreeRatio * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMinHeapFreeRatio */ -import com.oracle.java.testlibrary.TestDynamicVMOption; -import com.oracle.java.testlibrary.DynamicVMOptionChecker; +import static com.oracle.java.testlibrary.Asserts.assertEQ; +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import com.oracle.java.testlibrary.DynamicVMOption; -public class TestDynMinHeapFreeRatio extends TestDynamicVMOption { - - public static final String MinFreeRatioFlagName = "MinHeapFreeRatio"; - public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio"; - - public TestDynMinHeapFreeRatio() { - super(MinFreeRatioFlagName); - } - - public void test() { - int maxHeapFreeValue = DynamicVMOptionChecker.getIntValue(MaxFreeRatioFlagName); - System.out.println(MaxFreeRatioFlagName + " = " + maxHeapFreeValue); - - testPercentageValues(); - - checkInvalidValue(Integer.toString(maxHeapFreeValue + 1)); - checkValidValue(Integer.toString(maxHeapFreeValue)); - checkValidValue("0"); - } +public class TestDynMinHeapFreeRatio { public static void main(String args[]) throws Exception { - new TestDynMinHeapFreeRatio().test(); + + // high boundary value + int maxValue = DynamicVMOption.getInt("MaxHeapFreeRatio"); + System.out.println("MaxHeapFreeRatio= " + maxValue); + + String badValues[] = { + null, + "", + "not a number", + "8.5", "-0.01", + Integer.toString(Integer.MIN_VALUE), + Integer.toString(Integer.MAX_VALUE), + Integer.toString(maxValue + 1), + "-1024", "-1", "101", "1997" + }; + + String goodValues[] = { + Integer.toString(maxValue), + Integer.toString(maxValue - 1), + Integer.toString(maxValue / 2), + "0", "1" + }; + + // option under test + DynamicVMOption option = new DynamicVMOption("MinHeapFreeRatio"); + + assertTrue(option.isWriteable(), "Option " + option.name + + " is expected to be writable"); + + for (String v : badValues) { + assertFalse(option.isValidValue(v), + "'" + v + "' is expected to be illegal for flag " + option.name); + } + + for (String v : goodValues) { + option.setValue(v); + String newValue = option.getValue(); + assertEQ(v, newValue); + } } } diff --git a/hotspot/test/gc/g1/TestGCLogMessages.java b/hotspot/test/gc/g1/TestGCLogMessages.java index 0d5ba41fac9..dbb617001ba 100644 --- a/hotspot/test/gc/g1/TestGCLogMessages.java +++ b/hotspot/test/gc/g1/TestGCLogMessages.java @@ -22,7 +22,7 @@ */ /* - * @test TestPrintGCDetails + * @test TestGCLogMessages * @bug 8035406 8027295 8035398 8019342 * @summary Ensure that the PrintGCDetails output for a minor GC with G1 * includes the expected necessary messages. @@ -90,12 +90,6 @@ public class TestGCLogMessages { output.shouldContain("[String Dedup Fixup"); output.shouldContain("[Young Free CSet"); output.shouldContain("[Non-Young Free CSet"); - - // also check evacuation failure messages once - output.shouldNotContain("[Evacuation Failure"); - output.shouldNotContain("[Recalculate Used"); - output.shouldNotContain("[Remove Self Forwards"); - output.shouldNotContain("[Restore RemSet"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java index 14755075d3b..6f9b02de270 100644 --- a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java +++ b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java @@ -26,10 +26,9 @@ * @bug 8016479 * @summary Verify that the heap shrinks after full GC according to the current values of the Min/MaxHeapFreeRatio flags * @library /testlibrary - * @run main/othervm -XX:+UseAdaptiveSizePolicyWithSystemGC -XX:+UseParallelGC -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -verbose:gc TestDynShrinkHeap + * @run main/othervm -XX:+UseAdaptiveSizePolicyWithSystemGC -XX:+UseParallelGC -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -Xmx1g -verbose:gc TestDynShrinkHeap */ - -import com.oracle.java.testlibrary.TestDynamicVMOption; +import com.oracle.java.testlibrary.DynamicVMOption; import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.util.ArrayList; @@ -42,14 +41,9 @@ public class TestDynShrinkHeap { public static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio"; private static ArrayList list = new ArrayList<>(0); - private static final int M = 1024 * 1024; // to make heap more manageable by test code - - private final TestDynamicVMOption maxRatioOption; - private final TestDynamicVMOption minRatioOption; + private static final int LEN = 512 * 1024 + 1; public TestDynShrinkHeap() { - minRatioOption = new TestDynamicVMOption(MIN_FREE_RATIO_FLAG_NAME); - maxRatioOption = new TestDynamicVMOption(MAX_FREE_RATIO_FLAG_NAME); } private final void test() { @@ -75,18 +69,19 @@ public class TestDynShrinkHeap { } private void eat() { - for (int i = 0; i < M; i++) { + for (int i = 0; i < LEN; i++) { list.add(new byte[1024]); } - MemoryUsagePrinter.printMemoryUsage("allocated " + M + " arrays"); + MemoryUsagePrinter.printMemoryUsage("allocated " + LEN + " arrays"); - list.subList(0, M / 2).clear(); + list.subList(0, LEN / 2).clear(); System.gc(); MemoryUsagePrinter.printMemoryUsage("array halved"); } private void free() { - maxRatioOption.setIntValue(minRatioOption.getIntValue() + 1); + int min = DynamicVMOption.getInt(MIN_FREE_RATIO_FLAG_NAME); + DynamicVMOption.setInt(MAX_FREE_RATIO_FLAG_NAME, min); System.gc(); MemoryUsagePrinter.printMemoryUsage("under pressure"); } diff --git a/hotspot/test/runtime/6929067/T.java b/hotspot/test/runtime/6929067/T.java deleted file mode 100644 index 48c48857b95..00000000000 --- a/hotspot/test/runtime/6929067/T.java +++ /dev/null @@ -1,12 +0,0 @@ -public class T -{ - public static boolean foo(boolean bar) - { - return bar; - } - - public static void printIt() - { - System.out.println("Hello"); - } -} diff --git a/hotspot/test/runtime/6929067/invoke.c b/hotspot/test/runtime/6929067/invoke.c deleted file mode 100644 index 8dde2cd671b..00000000000 --- a/hotspot/test/runtime/6929067/invoke.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include - -#include - -union env_union -{ - void *void_env; - JNIEnv *jni_env; -}; - -union env_union tmp; -JNIEnv* env; -JavaVM* jvm; -JavaVMInitArgs vm_args; -JavaVMOption options[1]; -jclass class_id; -jmethodID method_id; -jint result; - -long product(unsigned long n, unsigned long m) { - if (m == 1) { - return n; - } else { - int *p = alloca(sizeof (int)); - *p = n; - return product (n, m-1) + *p; - } -} - -void * -floobydust (void *p) -{ - (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL); - env = tmp.jni_env; - - class_id = (*env)->FindClass (env, "T"); - assert (class_id); - - method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V"); - assert (method_id); - - (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL); - - (*jvm)->DetachCurrentThread(jvm); - - printf("%ld\n", product(5000,5000)); - - (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL); - env = tmp.jni_env; - - class_id = (*env)->FindClass (env, "T"); - assert (class_id); - - method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V"); - assert (method_id); - - (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL); - - (*jvm)->DetachCurrentThread(jvm); - - printf("%ld\n", product(5000,5000)); - - return NULL; -} - -int -main (int argc, const char** argv) -{ - options[0].optionString = "-Xss320k"; - - vm_args.version = JNI_VERSION_1_2; - vm_args.ignoreUnrecognized = JNI_TRUE; - vm_args.options = options; - vm_args.nOptions = 1; - - result = JNI_CreateJavaVM (&jvm, &tmp.void_env, &vm_args); - assert (result >= 0); - - env = tmp.jni_env; - - floobydust (NULL); - - pthread_t thr; - pthread_create (&thr, NULL, floobydust, NULL); - pthread_join (thr, NULL); - - return 0; -} diff --git a/hotspot/test/runtime/7110720/Test7110720.sh b/hotspot/test/runtime/7110720/Test7110720.sh deleted file mode 100644 index ae6c4098a1c..00000000000 --- a/hotspot/test/runtime/7110720/Test7110720.sh +++ /dev/null @@ -1,119 +0,0 @@ -# -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# - - -# -# @test Test7110720.sh -# @bug 7110720 -# @summary improve VM configuration file loading -# @run shell Test7110720.sh -# - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -# Jtreg sets TESTVMOPTS which may include -d64 which is -# required to test a 64-bit JVM on some platforms. -# If another test harness still creates HOME/JDK64BIT, -# we can recognise that. - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - FS="/" - RM=/bin/rm - CP=/bin/cp - MV=/bin/mv - ## for solaris, linux it's HOME - FILE_LOCATION=$HOME - if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ] - then - TESTVMOPTS=`cat ${FILE_LOCATION}${FS}JDK64BIT` - fi - ;; - Windows_* ) - FS="\\" - RM=rm - CP=cp - MV=mv - ;; - CYGWIN_* ) - FS="/" - RM=rm - CP=cp - MV=mv - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - - -JAVA=${TESTJAVA}${FS}bin${FS}java - -# Don't test debug builds, they do read the config files: -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "debug" >/dev/null -if [ "$?" = "0" ]; then - echo Skipping test for debug build. - exit 0 -fi - -ok=yes - -$RM -f .hotspot_compiler .hotspotrc - -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: base case failure" - exit 1 -fi - - -echo "garbage in, garbage out" > .hotspot_compiler -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: .hotspot_compiler was read" - ok=no -fi - -$MV .hotspot_compiler hs_comp.txt -${JAVA} ${TESTVMOPTS} -XX:CompileCommandFile=hs_comp.txt -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "1" ]; then - echo "FAILED: explicit compiler command file not read" - ok=no -fi - -$RM -f .hotspot_compiler hs_comp.txt - -echo "garbage" > .hotspotrc -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: .hotspotrc was read" - ok=no -fi - -$MV .hotspotrc hs_flags.txt -${JAVA} ${TESTVMOPTS} -XX:Flags=hs_flags.txt -version 2>&1 | grep "garbage" >/dev/null -if [ "$?" = "1" ]; then - echo "FAILED: explicit flags file not read" - ok=no -fi - -if [ "${ok}" = "no" ]; then - echo "Some tests failed." - exit 1 -else - echo "Passed" - exit 0 -fi - diff --git a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java index e5df0c9450b..aa5b4746139 100644 --- a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java +++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java @@ -33,17 +33,28 @@ import com.oracle.java.testlibrary.*; public class CompilerConfigFileWarning { public static void main(String[] args) throws Exception { - if (Platform.isDebugBuild()) { - System.out.println("Skip on debug builds since we'll always read the file there"); - return; - } + ProcessBuilder pb; + OutputAnalyzer output; + PrintWriter pw; - PrintWriter pw = new PrintWriter(".hotspot_compiler"); - pw.println("aa"); + pw = new PrintWriter("hs_comp.txt"); + pw.println("aaa, aaa"); pw.close(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file."); + pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("CompilerOracle: unrecognized line"); + output.shouldContain("aaa aaa"); + + // Skip on debug builds since we'll always read the file there + if (!Platform.isDebugBuild()) { + pw = new PrintWriter(".hotspot_compiler"); + pw.println("aa"); + pw.close(); + + pb = ProcessTools.createJavaProcessBuilder("-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file."); + } } } diff --git a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java index b81da5923fd..8f04a076b76 100644 --- a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java +++ b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java @@ -33,17 +33,28 @@ import com.oracle.java.testlibrary.*; public class ConfigFileWarning { public static void main(String[] args) throws Exception { - if (Platform.isDebugBuild()) { - System.out.println("Skip on debug builds since we'll always read the file there"); - return; - } + PrintWriter pw; + ProcessBuilder pb; + OutputAnalyzer output; - PrintWriter pw = new PrintWriter(".hotspotrc"); - pw.println("aa"); + pw = new PrintWriter("hs_flags.txt"); + pw.println("aaa"); pw.close(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file."); + pb = ProcessTools.createJavaProcessBuilder("-XX:Flags=hs_flags.txt","-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Unrecognized VM option 'aaa'"); + output.shouldHaveExitValue(1); + + // Skip on debug builds since we'll always read the file there + if (!Platform.isDebugBuild()) { + pw = new PrintWriter(".hotspotrc"); + pw.println("aa"); + pw.close(); + + pb = ProcessTools.createJavaProcessBuilder("-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file."); + } } } diff --git a/jdk/test/demo/jvmti/mtrace/TraceJFrame.java b/hotspot/test/runtime/CommandLine/TestHexArguments.java similarity index 50% rename from jdk/test/demo/jvmti/mtrace/TraceJFrame.java rename to hotspot/test/runtime/CommandLine/TestHexArguments.java index c0dbe0ba960..1fd33466662 100644 --- a/jdk/test/demo/jvmti/mtrace/TraceJFrame.java +++ b/hotspot/test/runtime/CommandLine/TestHexArguments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,37 +21,29 @@ * questions. */ - -/* @test - * @bug 5000000 6299047 - * @summary Test jvmti demo mtrace - * - * @compile ../DemoRun.java - * @compile JFrameCreateTime.java - * @build TraceJFrame - * @run main TraceJFrame JFrameCreateTime +/* + * @test + * @bug 8042885 + * @summary Make sure there is no error using hexadecimal format in vm options + * @author Yumin Qi + * @library /testlibrary */ -import java.awt.GraphicsEnvironment; +import java.io.File; +import com.oracle.java.testlibrary.*; -public class TraceJFrame { +public class TestHexArguments { public static void main(String args[]) throws Exception { - if (GraphicsEnvironment.isHeadless()) { - System.out.println("TraceJFrame test was skipped due to headless mode"); - } else { - DemoRun demo; + String[] javaArgs = {"-XX:SharedBaseAddress=0x1D000000", "-version"}; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, javaArgs); - /* Run demo that uses JVMTI mtrace agent (no options) */ - demo = new DemoRun("mtrace", "" /* options to mtrace */ ); - demo.runit(args[0]); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("Could not create the Java Virtual Machine"); + output.shouldHaveExitValue(0); - /* Make sure patterns in output look ok */ - if (demo.output_contains("ERROR")) { - throw new RuntimeException("Test failed - ERROR seen in output"); - } - - /* Must be a pass. */ - System.out.println("Test passed - cleanly terminated"); - } - } + String[] javaArgs1 = {"-XX:SharedBaseAddress=1D000000", "-version"}; + pb = ProcessTools.createJavaProcessBuilder(true, javaArgs1); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Could not create the Java Virtual Machine"); + } } diff --git a/hotspot/test/runtime/InitialThreadOverflow/invoke.c b/hotspot/test/runtime/InitialThreadOverflow/invoke.c deleted file mode 100644 index 84f0e405003..00000000000 --- a/hotspot/test/runtime/InitialThreadOverflow/invoke.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include - -#include - -JavaVM* jvm; - -void * -floobydust (void *p) { - JNIEnv *env; - jclass class_id; - jmethodID method_id; - - (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL); - - class_id = (*env)->FindClass (env, "DoOverflow"); - assert (class_id); - - method_id = (*env)->GetStaticMethodID(env, class_id, "printIt", "()V"); - assert (method_id); - - (*env)->CallStaticVoidMethod(env, class_id, method_id, NULL); - - (*jvm)->DetachCurrentThread(jvm); -} - -int -main (int argc, const char** argv) { - JavaVMOption options[1]; - options[0].optionString = (char*) "-Xss320k"; - - JavaVMInitArgs vm_args; - vm_args.version = JNI_VERSION_1_2; - vm_args.ignoreUnrecognized = JNI_TRUE; - vm_args.options = options; - vm_args.nOptions = 1; - - JNIEnv* env; - jint result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); - assert(result >= 0); - - pthread_t thr; - pthread_create(&thr, NULL, floobydust, NULL); - pthread_join(thr, NULL); - - floobydust(NULL); - - return 0; -} diff --git a/hotspot/test/runtime/InitialThreadOverflow/testme.sh b/hotspot/test/runtime/InitialThreadOverflow/testme.sh deleted file mode 100644 index d5d0eb223ff..00000000000 --- a/hotspot/test/runtime/InitialThreadOverflow/testme.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. - -# @test testme.sh -# @bug 8009062 -# @summary Poor performance of JNI AttachCurrentThread after fix for 7017193 -# @compile DoOverflow.java -# @run shell testme.sh - -set -x -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -if [ "${VM_OS}" != "linux" ] -then - echo "Test only valid for Linux" - exit 0 -fi - -gcc_cmd=`which gcc` -if [ "x$gcc_cmd" = "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 - exit 0; -fi - -CFLAGS="-m${VM_BITS}" - -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH -export LD_LIBRARY_PATH - -cp ${TESTSRC}/invoke.c . - -# Copy the result of our @compile action: -cp ${TESTCLASSES}/DoOverflow.class . - -echo "Architecture: ${VM_CPU}" -echo "Compilation flag: ${CFLAGS}" -echo "VM type: ${VM_TYPE}" -echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" - -# Note pthread may not be found thus invoke creation will fail to be created. -# Check to ensure you have a /usr/lib/libpthread.so if you don't please look -# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. - -$gcc_cmd -DLINUX ${CFLAGS} -o invoke \ - -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ - -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ - -ljvm -lpthread invoke.c - -./invoke -exit $? diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java b/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java deleted file mode 100644 index 162f3ad4722..00000000000 --- a/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test CdsWriteError - * @summary Test how VM handles situation when it is impossible to write the - * CDS archive. VM is expected to exit gracefully and display the - * correct reason for the error. - * @library /testlibrary - * @run main CdsWriteError - * @bug 8032222 - */ - -import com.oracle.java.testlibrary.*; -import java.io.File; - -public class CdsWriteError { - public static void main(String[] args) throws Exception { - - if (Platform.isWindows()) { - System.out.println("This test is ignored on Windows. This test " + - "manipulates folder writable attribute, which is known to be " + - "often ignored by Windows"); - - return; - } - - // This test has been unstable for Mac OSx (see JDK-8032222) - if (Platform.isOSX()) { - System.out.println("This test is skipped on Mac"); - return; - } - - String folderName = "tmp"; - String fileName = folderName + File.separator + "empty.jsa"; - - // create an empty archive file and make it read only - File folder = new File(folderName); - if (!folder.mkdir()) - throw new RuntimeException("Error when creating a tmp folder"); - - File cdsFile = new File(fileName); - if (!cdsFile.createNewFile()) - throw new RuntimeException("Error when creating an empty CDS file"); - if (!cdsFile.setWritable(false)) - throw new RuntimeException("Error: could not set writable attribute on cds file"); - if (!folder.setWritable(false)) - throw new RuntimeException("Error: could not set writable attribute on the cds folder"); - - try { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./" + fileName, "-Xshare:dump"); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Unable to create shared archive file"); - output.shouldHaveExitValue(1); - } finally { - // doing this, just in case, to make sure that files can be deleted by the harness - // on any subsequent run - folder.setWritable(true); - cdsFile.setWritable(true); - } - } -} - diff --git a/hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java b/hotspot/test/runtime/StackGuardPages/DoOverflow.java similarity index 87% rename from hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java rename to hotspot/test/runtime/StackGuardPages/DoOverflow.java index 958285ca915..4b9c45b62e8 100644 --- a/hotspot/test/runtime/InitialThreadOverflow/DoOverflow.java +++ b/hotspot/test/runtime/StackGuardPages/DoOverflow.java @@ -30,12 +30,16 @@ public class DoOverflow { overflow(); } + public static void printAlive() { + System.out.println("Java thread is alive."); + } + public static void printIt() { System.out.println("Going to overflow stack"); try { new DoOverflow().overflow(); } catch(java.lang.StackOverflowError e) { - System.out.println("Overflow OK " + count); + System.out.println("Test PASSED. Got StackOverflowError at " + count + " iteration"); } } } diff --git a/hotspot/test/runtime/StackGuardPages/invoke.c b/hotspot/test/runtime/StackGuardPages/invoke.c new file mode 100644 index 00000000000..483ac0b98e7 --- /dev/null +++ b/hotspot/test/runtime/StackGuardPages/invoke.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* This code tests the fact that we actually remove stack guard page when calling + * JavaThread::exit() i.e. when detaching from current thread. + * We overflow the stack and check that we get access error because of a guard page. + * Than we detach from vm thread and overflow stack once again. This time we shouldn't + * get access error because stack guard page is removed + * + * Notice: due a complicated interaction of signal handlers, the test may crash. + * It's OK - don't file a bug. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +JavaVM* _jvm; + +static jmp_buf context; + +static int _last_si_code = -1; +static int _failures = 0; +static int _rec_count = 0; +static int _kp_rec_count = 0; + +pid_t gettid() { + return (pid_t) syscall(SYS_gettid); +} + +static void handler(int sig, siginfo_t *si, void *unused) { + _last_si_code = si->si_code; + printf("Got SIGSEGV(%d) at address: 0x%lx\n",si->si_code, (long) si->si_addr); + longjmp(context, 1); +} + +void set_signal_handler() { + static char altstack[SIGSTKSZ]; + + stack_t ss = { + .ss_size = SIGSTKSZ, + .ss_flags = 0, + .ss_sp = altstack + }; + + struct sigaction sa = { + .sa_sigaction = handler, + .sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESETHAND + }; + + _last_si_code = -1; + + sigaltstack(&ss, 0); + sigemptyset(&sa.sa_mask); + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + fprintf(stderr, "Test ERROR. Can't set sigaction (%d)\n", errno); + exit(7); + } +} + +void *run_java_overflow (void *p) { + JNIEnv *env; + jclass class_id; + jmethodID method_id; + int res; + + res = (*_jvm)->AttachCurrentThread(_jvm, (void**)&env, NULL); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't attach to current thread\n"); + exit(7); + } + + class_id = (*env)->FindClass (env, "DoOverflow"); + if (class_id == NULL) { + fprintf(stderr, "Test ERROR. Can't load class DoOverflow\n"); + exit(7); + } + + method_id = (*env)->GetStaticMethodID(env, class_id, "printIt", "()V"); + if (method_id == NULL) { + fprintf(stderr, "Test ERROR. Can't find method DoOverflow.printIt\n"); + exit(7); + } + + (*env)->CallStaticVoidMethod(env, class_id, method_id, NULL); + + res = (*_jvm)->DetachCurrentThread(_jvm); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't call detach from current thread\n"); + exit(7); + } +} + +void do_overflow(){ + int *p = alloca(sizeof(int)); + if (_kp_rec_count == 0 || _rec_count < _kp_rec_count) { + _rec_count ++; + do_overflow(); + } +} + +void *run_native_overflow(void *p) { + // Test that stack guard page is correctly set for initial and non initial thread + // and correctly removed for the initial thread + JNIEnv *env; + jclass class_id; + jmethodID method_id; + int res; + + printf("run_native_overflow %ld\n", (long) gettid()); + + res = (*_jvm)->AttachCurrentThread(_jvm, (void **)&env, NULL); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't attach to current thread\n"); + exit(7); + } + + class_id = (*env)->FindClass (env, "DoOverflow"); + if (class_id == NULL) { + fprintf(stderr, "Test ERROR. Can't load class DoOverflow\n"); + exit(7); + } + + method_id = (*env)->GetStaticMethodID (env, class_id, "printAlive", "()V"); + if (method_id == NULL) { + fprintf(stderr, "Test ERROR. Can't find method DoOverflow.printAlive\n"); + exit(7); + } + + (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL); + + set_signal_handler(); + if (! setjmp(context)) { + do_overflow(); + } + + if (_last_si_code == SEGV_ACCERR) { + printf("Test PASSED. Got access violation accessing guard page at %d\n", _rec_count); + } + + res = (*_jvm)->DetachCurrentThread(_jvm); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't call detach from current thread\n"); + exit(7); + } + + if (getpid() != gettid()) { + // For non-initial thread we don't unmap the region but call os::uncommit_memory and keep PROT_NONE + // so if host has enough swap space we will get the same SEGV with code SEGV_ACCERR(2) trying + // to access it as if the guard page is present. + // We have no way to check this, so bail out, marking test as succeeded + printf("Test PASSED. Not initial thread\n"); + return NULL; + } + + // Limit depth of recursion for second run. It can't exceed one for first run. + _kp_rec_count = _rec_count; + _rec_count = 0; + + set_signal_handler(); + if (! setjmp(context)) { + do_overflow(); + } + + if (_last_si_code == SEGV_ACCERR) { + ++ _failures; + fprintf(stderr,"Test FAILED. Stack guard page is still there at %d\n", _rec_count); + } else if (_last_si_code == -1) { + printf("Test PASSED. No stack guard page is present. Maximum recursion level reached at %d\n", _rec_count); + } + else{ + printf("Test PASSED. No stack guard page is present. SIGSEGV(%d) at %d\n", _last_si_code, _rec_count); + } + + return NULL; +} + +void usage() { + fprintf(stderr, "Usage: invoke test_java_overflow\n"); + fprintf(stderr, " invoke test_native_overflow\n"); + exit(7); +} + + +int main (int argc, const char** argv) { + JavaVMInitArgs vm_args; + JavaVMOption options[2]; + JNIEnv* env; + + printf("Test started with pid: %ld\n", (long) getpid()); + + options[0].optionString = "-Xint"; + options[1].optionString = "-Xss320k"; + + vm_args.version = JNI_VERSION_1_2; + vm_args.ignoreUnrecognized = JNI_TRUE; + vm_args.options = options; + vm_args.nOptions = 2; + + if (JNI_CreateJavaVM (&_jvm, (void **)&env, &vm_args) < 0 ) { + fprintf(stderr, "Test ERROR. Can't create JavaVM\n"); + exit(7); + } + + pthread_t thr; + + if (argc > 1 && strcmp(argv[1], "test_java_overflow") == 0) { + printf("\nTesting JAVA_OVERFLOW\n"); + + printf("Testing stack guard page behaviour for other thread\n"); + pthread_create (&thr, NULL, run_java_overflow, NULL); + pthread_join (thr, NULL); + + printf("Testing stack guard page behaviour for initial thread\n"); + run_java_overflow(NULL); + // This test crash on error + exit(0); + } + + if (argc > 1 && strcmp(argv[1], "test_native_overflow") == 0) { + printf("\nTesting NATIVE_OVERFLOW\n"); + + printf("Testing stack guard page behaviour for other thread\n"); + pthread_create (&thr, NULL, run_native_overflow, NULL); + pthread_join (thr, NULL); + + printf("Testing stack guard page behaviour for initial thread\n"); + run_native_overflow(NULL); + + exit((_failures > 0) ? 1 : 0); + } + + fprintf(stderr, "Test ERROR. Unknown parameter %s\n", ((argc > 1) ? argv[1] : "none")); + usage(); +} diff --git a/hotspot/test/runtime/6929067/Test6929067.sh b/hotspot/test/runtime/StackGuardPages/testme.sh similarity index 62% rename from hotspot/test/runtime/6929067/Test6929067.sh rename to hotspot/test/runtime/StackGuardPages/testme.sh index e1fd6b78237..7f6a24a3d31 100644 --- a/hotspot/test/runtime/6929067/Test6929067.sh +++ b/hotspot/test/runtime/StackGuardPages/testme.sh @@ -1,13 +1,10 @@ #!/bin/sh -## -## @test Test6929067.sh -## @bug 6929067 -## @bug 8021296 -## @bug 8025519 -## @summary Stack guard pages should be removed when thread is detached -## @run shell Test6929067.sh -## +# +# @test testme.sh +# @summary Stack guard pages should be installed correctly and removed when thread is detached +# @run shell testme.sh +# if [ "${TESTSRC}" = "" ] then @@ -32,12 +29,9 @@ fi CFLAGS=-m${VM_BITS} -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH +LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:${TESTJAVA}/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH -cp ${TESTSRC}/*.java ${THIS_DIR} -${COMPILEJAVA}/bin/javac *.java - echo "Architecture: ${VM_CPU}" echo "Compilation flag: ${CFLAGS}" echo "VM type: ${VM_TYPE}" @@ -47,10 +41,20 @@ echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" # Check to ensure you have a /usr/lib/libpthread.so if you don't please look # for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. -$gcc_cmd -DLINUX ${CFLAGS} -o invoke \ +cp ${TESTSRC}/DoOverflow.java . +${COMPILEJAVA}/bin/javac DoOverflow.java + +$gcc_cmd -DLINUX -g3 ${CFLAGS} -o invoke \ -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ + -L${TESTJAVA}/lib/${VM_CPU}/${VM_TYPE} \ ${TESTSRC}/invoke.c -ljvm -lpthread -./invoke +if [ $? -ne 0 ] ; then + echo "Compile failed, Ignoring failed compilation and forcing the test to pass" + exit 0 +fi + +./invoke test_java_overflow +./invoke test_native_overflow exit $? diff --git a/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java new file mode 100644 index 00000000000..fa33c1e3c62 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestEmptyBootstrapMethodsAttr + * @bug 8041918 + * @library /testlibrary + * @summary Test empty bootstrap_methods table within BootstrapMethods attribute + * @compile TestEmptyBootstrapMethodsAttr.java + * @run main TestEmptyBootstrapMethodsAttr + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class TestEmptyBootstrapMethodsAttr { + + public static void main(String args[]) throws Throwable { + System.out.println("Regression test for bug 8041918"); + String jarFile = System.getProperty("test.src") + File.separator + "emptynumbootstrapmethods.jar"; + + // ====== extract the test case + ProcessBuilder pb = new ProcessBuilder(new String[] { JDKToolFinder.getJDKTool("jar"), "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // Test case #1: + // Try loading class with empty bootstrap_methods table where no + // other attributes are following BootstrapMethods in attribute table. + String className = "emptynumbootstrapmethods1"; + + // ======= execute test case #1 + // Expect a lack of main method, this implies that the class loaded correctly + // with an empty bootstrap_methods and did not generate a ClassFormatError. + pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("java.lang.ClassFormatError"); + output.shouldContain("Main method not found in class " + className); + output.shouldHaveExitValue(1); + + // Test case #2: + // Try loading class with empty bootstrap_methods table where an + // AnnotationDefault attribute follows the BootstrapMethods in the attribute table. + className = "emptynumbootstrapmethods2"; + + // ======= execute test case #2 + // Expect a lack of main method, this implies that the class loaded correctly + // with an empty bootstrap_methods and did not generate ClassFormatError. + pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("java.lang.ClassFormatError"); + output.shouldContain("Main method not found in class " + className); + output.shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar new file mode 100644 index 00000000000..6ea40b970fb Binary files /dev/null and b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar differ diff --git a/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod new file mode 100644 index 00000000000..df1c210bee5 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This test contains a BootstrapMethods attribute with an empty + * bootstrap_methods table. This yields a BootstrapMethods + * attribute length of 2 and should not cause a + * java.lang.ClassFormatError to be thrown. + */ +class emptynumbootstrapmethods1 { + 0xCAFEBABE; + 0; // minor version + 51; // version + [12] { // Constant Pool + ; // first element is empty + class #2; // #1 at 0x0A + Utf8 "emptynumbootstrapmethods1"; // #2 at 0x0D + class #4; // #3 at 0x1F + Utf8 "java/lang/Object"; // #4 at 0x22 + MethodHandle 5b #9; // #5 at 0x35 + NameAndType #7 #8; // #6 at 0x39 + Utf8 "equals"; // #7 at 0x3E + Utf8 "(Ljava/lang/Object;)Z"; // #8 at 0x47 + Method #3 #6; // #9 at 0x5F + Utf8 "equalsx"; // #10 at 0x3E + Utf8 "BootstrapMethods"; // #11 at 0x69 + } // Constant Pool + + 0x0001; // access + #1;// this_cpx + #3;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [0] { // methods + } // methods + + [1] { // Attributes + Attr(#11, 2) { // BootstrapMethods at 0x8A + [0] { // bootstrap_methods + } + } // end BootstrapMethods + } // Attributes +} // end class atrbsm00101m10p diff --git a/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod new file mode 100644 index 00000000000..428fad98a88 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This test contains a BootstrapMethods attribute with an empty + * bootstrap_methods table. This yields a BootstrapMethods + * attribute length of 2 and should not cause a + * java.lang.ClassFormatError to be thrown. To ensure that an empty + * bootstrap_methods table is parsed correctly, another attribute, + * AnnotationDefault, follows the BootstrapMethods attribute in + * the attribute table. + */ + +class emptynumbootstrapmethods2 { + 0xCAFEBABE; + 0; // minor version + 51; // version + [14] { // Constant Pool + ; // first element is empty + class #2; // #1 at 0x0A + Utf8 "emptynumbootstrapmethods2"; // #2 at 0x0D + class #4; // #3 at 0x1F + Utf8 "java/lang/Object"; // #4 at 0x22 + MethodHandle 5b #9; // #5 at 0x35 + NameAndType #7 #8; // #6 at 0x39 + Utf8 "equals"; // #7 at 0x3E + Utf8 "(Ljava/lang/Object;)Z"; // #8 at 0x47 + Method #3 #6; // #9 at 0x5F + Utf8 "equalsx"; // #10 at 0x3E + Utf8 "BootstrapMethods"; // #11 at 0x69 + Utf8 "AnnotationDefault"; // #12 + Utf8 "LAnnotationDefaultI;"; // #13 + } // Constant Pool + + 0x0001; // access + #1;// this_cpx + #3;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [0] { // methods + } // methods + + [2] { // Attributes + Attr(#11, 2) { // BootstrapMethods at 0x8A + [0] { // bootstrap_methods + } + } // end BootstrapMethods + ; + Attr(#12) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #13; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes +} // end class atrbsm00101m10p diff --git a/hotspot/test/runtime/duplAttributes/DuplAttributes.jcod b/hotspot/test/runtime/duplAttributes/DuplAttributes.jcod new file mode 100644 index 00000000000..1a9a1ae8f4b --- /dev/null +++ b/hotspot/test/runtime/duplAttributes/DuplAttributes.jcod @@ -0,0 +1,1310 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + * This file contains ten different sub-tests. Each sub-test consists of a + * class with a different case of an invalid duplicate attribute. The main + * test runs each of these tests individually. If any of them fail then the + * whole test fails. + */ + + + +/* + * This test contains a class with invalid duplicate AnnotationDefault attributes. + */ +class AnnotationDefaultDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 ""; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/lang/Object;"; // #8 + Utf8 "AnnotationDefault"; // #9 + Utf8 "LAnnotationDefaultI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "AnnotationDefaultDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "AnnotationDefaultDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + + Attr(#9) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + // wrong: + ; + Attr(#9) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes + +} // end class + + + +/* + * This test contains a class with invalid duplicate RuntimeInvisibleAnnotations + * attributes. + */ +class ClassInvisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 ""; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/lang/Object;"; // #8 + Utf8 "RuntimeInvisibleAnnotations"; // #9 + Utf8 "LClassInvisAnnotsI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "ClassInvisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "ClassInvisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations +// wrong: + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations +// end wrong + } // Attributes + +} // end class + + + +/* + * This test contains a class with invalid duplicate RuntimeVisibleAnnotations + * attributes. + */ +class ClassVisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 ""; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/lang/Object;"; // #8 + Utf8 "RuntimeVisibleAnnotations"; // #9 + Utf8 "LClassVisAnnotsI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "ClassVisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "ClassVisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations +// wrong: + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations +// end wrong + } // Attributes + +} // end class + + + +/* + * This test contains a field with invalid duplicate RuntimeInvisibleAnnotations + * attributes. + */ +class FieldInvisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 "fld"; // #5 + Utf8 "Ljava/util/ArrayList;"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/util/ArrayList;"; // #8 + Utf8 "RuntimeInvisibleAnnotations"; // #9 + Utf8 "LFieldInvisAnnotsI;"; // #10 + Utf8 ""; // #11 + Utf8 "()V"; // #12 + Utf8 "Code"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #11 #12; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "FieldInvisAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "FieldInvisAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + // end wrong + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0001; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a field with invalid duplicate RuntimeVisibleAnnotations + * attributes. + */ +class FieldVisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 "fld"; // #5 + Utf8 "Ljava/util/ArrayList;"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/util/ArrayList;"; // #8 + Utf8 "RuntimeVisibleAnnotations"; // #9 + Utf8 "LFieldVisAnnotsI;"; // #10 + Utf8 ""; // #11 + Utf8 "()V"; // #12 + Utf8 "Code"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #11 #12; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "FieldVisAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "FieldVisAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + // end wrong + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0001; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a method with invalid duplicate RuntimeInvisibleAnnotations + * attributes. + */ +class MethInvisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 ""; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/lang/Object;"; // #8 + Utf8 "RuntimeInvisibleAnnotations"; // #9 + Utf8 "LMethInvisAnnotsI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "MethInvisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "MethInvisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeInvisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeInvisibleAnnotations + } // Attributes + +} // end class + + + +/* + * This test contains a method with invalid duplicate + * RuntimeInvisibleParameterAnnotations attributes. + */ +class MethInvisParamAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "m"; // #8 + Utf8 "()I"; // #9 + Utf8 "Signature"; // #10 + Utf8 "()I"; // #11 + Utf8 "RuntimeInvisibleParameterAnnotations"; // #12 + Utf8 "LMethInvisParamAnnotsI;"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #5 #6; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "MethInvisParamAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "MethInvisParamAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x03AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + Attr(#10) { // Signature + #11; + } // end Signature + ; + Attr(#12) { // RuntimeInvisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeInvisibleParameterAnnotations +// wrong: + ; + Attr(#12) { // RuntimeInvisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeInvisibleParameterAnnotations +// end wrong + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a method with invalid duplicate RuntimeVisibleAnnotations + * attributes. + */ +class MethVisAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 ""; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/lang/Object;"; // #8 + Utf8 "RuntimeVisibleAnnotations"; // #9 + Utf8 "LMethodVisAnnotsDupI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "MethVisAnnotsDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "MethVisAnnotsDupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + // wrong: + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // RuntimeVisibleAnnotations + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #10; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end RuntimeVisibleAnnotations + } // Attributes + +} // end class + + + +/* + * This test contains a method with invalid duplicate + * RuntimeVisibleParameterAnnotations attributes. + */ +class MethVisParamAnnotsDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "m"; // #8 + Utf8 "()I"; // #9 + Utf8 "Signature"; // #10 + Utf8 "()I"; // #11 + Utf8 "RuntimeVisibleParameterAnnotations"; // #12 + Utf8 "LMethVisParamAnnotsI;"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #5 #6; // #16 + class #21; // #17 + NameAndType #14 #15; // #18 + Utf8 "MethVisParamAnnotsDup"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "MethVisParamAnnotsDupChecker"; // #21 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x03AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + ; + Attr(#10) { // Signature + #11; + } // end Signature + ; + Attr(#12) { // RuntimeVisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeVisibleParameterAnnotations +// wrong: + ; + Attr(#12) { // RuntimeVisibleParameterAnnotations + 0x0001010000000D00; + 0x00; + } // end RuntimeVisibleParameterAnnotations +// end wrong + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80002AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + } // Attributes +} // end class + + + +/* + * This test contains a method with invalid duplicate SourceDebugExtension + * attributes. + */ +class SrcDbgExtDup { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #11; // #1 + class #12; // #2 + class #13; // #3 + Utf8 ""; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "Signature"; // #7 + Utf8 "Ljava/lang/Object;"; // #8 + Utf8 "SourceDebugExtension"; // #9 + Utf8 "LSrcDbgExtDupI;"; // #10 + NameAndType #4 #5; // #11 + Utf8 "SrcDbgExtDup"; // #12 + Utf8 "java/lang/Object"; // #13 + Utf8 "run"; // #14 + Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #15 + NameAndType #14 #15; // #16 + class #19; // #17 + Method #17 #16; // #18 + Utf8 "SrcDbgExt_dupChecker"; // #19 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #14; // name_cpx + #15; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A2BB80012AC; + }; + [] { // Traps + } // end Traps + [] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#7) { // Signature + #8; + } // end Signature + ; + Attr(#9) { // SourceDebugExtension + [] { // debug_extensions + { // type debug_extension + []b { // type_path + } + } // type debug_extension + } // type debug_extensions + } // end SourceDebugExtension +// wrong: + ; + Attr(#9) { // SourceDebugExtension + [] { // debug_extensions + { // type debug_extension + []b { // type_path + } + } // type debug_extension + } // type debug_extensions + } // end SourceDebugExtension +// end wrong + } // Attributes + +} // end class diff --git a/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java b/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java new file mode 100644 index 00000000000..8b5235ebc01 --- /dev/null +++ b/hotspot/test/runtime/duplAttributes/DuplAttributesTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8040292 + * @library /testlibrary + * @summary Throw exceptions when duplicate attributes are detected. + * @run main DuplAttributesTest + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class DuplAttributesTest { + + static final String testsrc = System.getProperty("test.src"); + + public static void runTest(String test, String result) throws Throwable { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-cp", testsrc + File.separator + "test.jar", test); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("java.lang.ClassFormatError: Multiple " + result); + } + + public static void main(String args[]) throws Throwable { + System.out.println("Regression test for bug 8040292"); + + runTest("ClassInvisAnnotsDup", "RuntimeInvisibleAnnotations"); + runTest("ClassVisAnnotsDup", "RuntimeVisibleAnnotations"); + runTest("SrcDbgExtDup", "SourceDebugExtension"); + + runTest("FieldInvisAnnotsDup", "RuntimeInvisibleAnnotations"); + runTest("FieldVisAnnotsDup", "RuntimeVisibleAnnotations"); + + runTest("AnnotationDefaultDup", "AnnotationDefault"); + runTest("MethInvisAnnotsDup", "RuntimeInvisibleAnnotations"); + runTest("MethVisAnnotsDup", "RuntimeVisibleAnnotations"); + runTest("MethInvisParamAnnotsDup", "RuntimeInvisibleParameterAnnotations"); + runTest("MethVisParamAnnotsDup", "RuntimeVisibleParameterAnnotations"); + } +} + diff --git a/hotspot/test/runtime/duplAttributes/test.jar b/hotspot/test/runtime/duplAttributes/test.jar new file mode 100644 index 00000000000..af160708f17 Binary files /dev/null and b/hotspot/test/runtime/duplAttributes/test.jar differ diff --git a/hotspot/test/runtime/whitebox/WBStackSize.java b/hotspot/test/runtime/whitebox/WBStackSize.java new file mode 100644 index 00000000000..2a0216082d7 --- /dev/null +++ b/hotspot/test/runtime/whitebox/WBStackSize.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test WBStackSize + * @summary verify that whitebox functions getThreadFullStackSize() and getThreadRemainingStackSize are working + * @library /testlibrary /testlibrary/whitebox + * @build WBStackSize + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xss512k WBStackSize + */ + +/* + * The test may product a false failure if too big StackYellowPages/StackRedPages/ShackShadowPages + * VM options are specified. The proper test would retrieve the page size from VM and account for these options + * instead of check below: + * Math.abs(actualStackSize - configStackSize) > configStackSize * 0.1 + * + * Please file a test bug, if this is a problem. + */ + +import com.sun.management.HotSpotDiagnosticMXBean; +import sun.hotspot.WhiteBox; + +public class WBStackSize { + + static final long K = 1024; + + static final long MIN_STACK_SIZE = 8 * K; + static final long MAX_STACK_SIZE_ALLOCATED_IN_MAIN = 200 * K; // current value is about 130k on 64-bit platforms + + static final WhiteBox wb = WhiteBox.getWhiteBox(); + + static long stackSizeOnOverflow = -1; + + static int eatAllStack() { + return eatAllStack() * 2; + } + + static void testStackOverflow() { + + stackSizeOnOverflow = wb.getThreadRemainingStackSize(); + + if (stackSizeOnOverflow > MIN_STACK_SIZE) { + + try { + testStackOverflow(); + } catch (StackOverflowError e) { + // We caught SOE too early. The error will be reported in main() + } + + } else { + + try { + eatAllStack(); + throw new RuntimeException("Haven't caught StackOverflowError at all"); + } catch (StackOverflowError e) { + // OK: we caught the anticipated error + } + } + } + + public static void main(String[] args) { + HotSpotDiagnosticMXBean bean = sun.management.ManagementFactoryHelper.getDiagnosticMXBean(); + long configStackSize = Long.valueOf(bean.getVMOption("ThreadStackSize").getValue()) * K; + + System.out.println("ThreadStackSize VM option: " + configStackSize); + + long actualStackSize = wb.getThreadStackSize(); + System.out.println("Full stack size: " + actualStackSize); + + if (Math.abs(actualStackSize - configStackSize) > configStackSize * 0.1) { + throw new RuntimeException("getThreadFullStackSize value [" + actualStackSize + + "] should be within 90%..110% of the value returned by HotSpotDiagnosticMXBean"); + } + + long remainingStackSize = wb.getThreadRemainingStackSize(); + System.out.println("Remaining stack size in main(): " + remainingStackSize); + + // Up to 200k can be already allocated by VM + if (remainingStackSize > configStackSize + || (configStackSize > MAX_STACK_SIZE_ALLOCATED_IN_MAIN + && remainingStackSize < configStackSize - MAX_STACK_SIZE_ALLOCATED_IN_MAIN)) { + + throw new RuntimeException("getThreadRemainingStackSize value [" + remainingStackSize + + "] should be at least ThreadStackSize value [" + configStackSize + "] minus [" + + MAX_STACK_SIZE_ALLOCATED_IN_MAIN + "]"); + } + + testStackOverflow(); + + if (stackSizeOnOverflow > MIN_STACK_SIZE) { + throw new RuntimeException("Caught StackOverflowError too early: when there were " + + stackSizeOnOverflow + " bytes in stack"); + } else if (stackSizeOnOverflow < 0) { + throw new RuntimeException("Internal test error: stackRemainingSize < 0"); + } else { + System.out.println("Caught StackOverflowError as expected"); + } + } +} diff --git a/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java new file mode 100644 index 00000000000..ec33d813541 --- /dev/null +++ b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.PrintWriter; +import com.oracle.java.testlibrary.*; + +/* + * Test to verify GetObjectSize does not overflow on a 600M element int[] + * + * @test + * @bug 8027230 + * @library /testlibrary + * @build GetObjectSizeOverflowAgent + * @run main ClassFileInstaller GetObjectSizeOverflowAgent + * @run main GetObjectSizeOverflow + */ +public class GetObjectSizeOverflow { + public static void main(String[] args) throws Exception { + + if (!Platform.is64bit()) { + System.out.println("Test needs a 4GB heap and can only be run as a 64bit process, skipping."); + return; + } + + PrintWriter pw = new PrintWriter("MANIFEST.MF"); + pw.println("Premain-Class: GetObjectSizeOverflowAgent"); + pw.close(); + + ProcessBuilder pb = new ProcessBuilder(); + pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", "agent.jar", "GetObjectSizeOverflowAgent.class"}); + pb.start().waitFor(); + + ProcessBuilder pt = ProcessTools.createJavaProcessBuilder(true, "-Xmx4000m", "-javaagent:agent.jar", "GetObjectSizeOverflowAgent"); + OutputAnalyzer output = new OutputAnalyzer(pt.start()); + + if (output.getStdout().contains("Could not reserve enough space") || output.getStderr().contains("java.lang.OutOfMemoryError")) { + System.out.println("stdout: " + output.getStdout()); + System.out.println("stderr: " + output.getStderr()); + System.out.println("Test could not reserve or allocate enough space, skipping"); + return; + } + + output.stdoutShouldContain("GetObjectSizeOverflow passed"); + } +} diff --git a/hotspot/test/serviceability/jvmti/GetObjectSizeOverflowAgent.java b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflowAgent.java new file mode 100644 index 00000000000..8f7c2162364 --- /dev/null +++ b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflowAgent.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.lang.instrument.*; + +public class GetObjectSizeOverflowAgent { + + static Instrumentation instrumentation; + + public static void premain(String agentArgs, Instrumentation instrumentation) { + GetObjectSizeOverflowAgent.instrumentation = instrumentation; + } + + public static void main(String[] args) throws Exception { + int[] a = new int[600_000_000]; + long size = instrumentation.getObjectSize(a); + + if (size < 2_400_000_000L) { + throw new RuntimeException("Invalid size of array, expected >= 2400000000, got " + size); + } + + System.out.println("GetObjectSizeOverflow passed"); + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java new file mode 100644 index 00000000000..49671ef54fa --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.java.testlibrary; + +import com.sun.management.HotSpotDiagnosticMXBean; +import java.lang.management.ManagementFactory; + +/** + * A utility class to work with VM options which could be altered during + * execution. + * + * This class is a wrapper around {@code com.sun.management.VMOption}. + * It provides more convenient interface to read/write the values. + * + */ +public class DynamicVMOption { + + private final HotSpotDiagnosticMXBean mxBean; + + /** + * VM option name, like "MinHeapFreeRatio". + */ + public final String name; + + /** + * Creates an instance of DynamicVMOption. + * + * @param name the VM option name + */ + public DynamicVMOption(String name) { + this.name = name; + mxBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + } + + /** + * Sets a new value for the option. + * Trying to set not applicable value will cause IllegalArgumentException. + * Behavior with null is undefined, most likely NPE will be thrown. + * + * @param newValue the value to be set + * @see #getValue() + * @throws IllegalArgumentException if newValue is not applicable to the option + */ + public final void setValue(String newValue) { + mxBean.setVMOption(name, newValue); + } + + /** + * Returns the value of option. + * + * @return the current option value + * @see #setValue(java.lang.String) + */ + public final String getValue() { + return mxBean.getVMOption(name).getValue(); + } + + /** + * Returns true, if option is writable, false otherwise. + * + * @return true, if option is writable, false otherwise + */ + public final boolean isWriteable() { + return mxBean.getVMOption(name).isWriteable(); + } + + /** + * Checks if the given value is applicable for the option. + * + * This method tries to set the option to the new value. If no exception + * has been thrown the value is treated as valid. + * + * Calling this method will not change the option value. After an attempt + * to set a new value, the option will be restored to its previous value. + * + * @param value the value to verify + * @return true if option could be set to the given value + */ + public boolean isValidValue(String value) { + boolean isValid = true; + String oldValue = getValue(); + try { + setValue(value); + } catch (NullPointerException e) { + if (value == null) { + isValid = false; + } + } catch (IllegalArgumentException e) { + isValid = false; + } finally { + setValue(oldValue); + } + return isValid; + } + + /** + * Returns the value of the given VM option as String. + * + * This is a simple shortcut for {@code new DynamicVMOption(name).getValue()} + * + * @param name the name of VM option + * @return value as a string + * @see #getValue() + */ + public static String getString(String name) { + return new DynamicVMOption(name).getValue(); + } + + /** + * Returns the value of the given option as int. + * + * @param name the name of VM option + * @return value parsed as integer + * @see #getString(java.lang.String) + * + */ + public static int getInt(String name) { + return Integer.parseInt(getString(name)); + } + + /** + * Sets the VM option to a new value. + * + * This is a simple shortcut for {@code new DynamicVMOption(name).setValue(value)} + * + * @param name the name of VM option + * @param value the value to be set + * @see #setValue(java.lang.String) + */ + public static void setString(String name, String value) { + new DynamicVMOption(name).setValue(value); + } + + /** + * Sets the VM option value to a new integer value. + * + * @param name the name of VM option + * @param value the integer value to be set + * @see #setString(java.lang.String, java.lang.String) + */ + public static void setInt(String name, int value) { + new DynamicVMOption(name).setValue(Integer.toString(value)); + } + +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java deleted file mode 100644 index baa717d46aa..00000000000 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.java.testlibrary; - -import com.sun.management.HotSpotDiagnosticMXBean; -import com.sun.management.VMOption; -import java.lang.management.ManagementFactory; - -/** - * Simple class to check writeability, invalid and valid values for VMOption - */ -public class DynamicVMOptionChecker { - - /** - * Reads VM option from PlatformMXBean and parse it to integer value - * - * @param name of option - * @return parsed value - */ - public static int getIntValue(String name) { - - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - return Integer.parseInt(option.getValue()); - } - - /** - * Sets VM option value - * - * @param name of option - * @param value to set - */ - public static void setIntValue(String name, int value) { - ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class).setVMOption(name, Integer.toString(value)); - } - - /** - * Checks that VM option is dynamically writable - * - * @param name - * @throws RuntimeException if option if not writable - * @return always true - */ - public static boolean checkIsWritable(String name) { - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - if (!option.isWriteable()) { - throw new RuntimeException(name + " is not writable"); - } - - return true; - } - - /** - * Checks that value cannot be set - * - * @param name of flag - * @param value string representation of value to set - * @throws RuntimeException on error - when expected exception hasn't been thrown - */ - public static void checkInvalidValue(String name, String value) { - // should throw - try { - ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - setVMOption(name, value); - - } catch (IllegalArgumentException e) { - return; - } - - throw new RuntimeException("Expected IllegalArgumentException was not thrown, " + name + "= " + value); - } - - /** - * Checks that value can be set - * - * @param name of flag to set - * @param value string representation of value to set - * @throws RuntimeException on error - when value in VM is not equal to origin - */ - public static void checkValidValue(String name, String value) { - ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - setVMOption(name, value); - - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - if (!option.getValue().equals(value)) { - throw new RuntimeException("Actual value of " + name + " \"" + option.getValue() - + "\" not equal origin \"" + value + "\""); - } - } - -} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java deleted file mode 100644 index 2c164596924..00000000000 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.java.testlibrary; - -/** - * Simple class to check writeability, invalid and valid values for concrete VMOption - */ -public class TestDynamicVMOption { - - private final String name; - private final int value; - - /** - * Constructor - * - * @param name of VM option to test - */ - public TestDynamicVMOption(String name) { - this.name = name; - this.value = DynamicVMOptionChecker.getIntValue(name); - System.out.println(this.name + " = " + this.value); - } - - /** - * Checks that this value can accept valid percentage values and cannot accept invalid percentage values - * - * @throws RuntimeException - */ - public void testPercentageValues() { - checkInvalidValue(Integer.toString(Integer.MIN_VALUE)); - checkInvalidValue(Integer.toString(Integer.MAX_VALUE)); - checkInvalidValue("-10"); - checkInvalidValue("190"); - } - - /** - * Reads VM option from PlatformMXBean and parse it to integer value - * - * @return value - */ - public int getIntValue() { - return DynamicVMOptionChecker.getIntValue(this.name); - } - - /** - * Sets VM option value - * - * @param value to set - */ - public void setIntValue(int value) { - DynamicVMOptionChecker.setIntValue(this.name, value); - } - - /** - * Checks that this VM option is dynamically writable - * - * @throws RuntimeException if option if not writable - * @return true - */ - public boolean checkIsWritable() throws RuntimeException { - return DynamicVMOptionChecker.checkIsWritable(this.name); - } - - /** - * Checks that value for this VM option cannot be set - * - * @param value to check - * @throws RuntimeException on error - when expected exception hasn't been thrown - */ - public void checkInvalidValue(String value) { - DynamicVMOptionChecker.checkInvalidValue(this.name, value); - } - - /** - * Checks that value for this VM option can be set - * - * @param value to check - * @throws RuntimeException on error - when value in VM is not equal to origin - */ - public void checkValidValue(String value) { - DynamicVMOptionChecker.checkValidValue(this.name, value); - } - -} diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index e35260c6d2f..a959900459a 100644 --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -150,6 +150,8 @@ public class WhiteBox { public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations); public native void runMemoryUnitTests(); public native void readFromNoaccessArea(); + public native long getThreadStackSize(); + public native long getThreadRemainingStackSize(); // CPU features public native String getCPUFeatures(); diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f631e59bbe0..e7c3b4c5d14 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -256,3 +256,6 @@ f93a792fe37279d4d37aea86a99f3abbdc6fe79b jdk9-b09 6b4280dceb00642f54d5bc1c2cb7d34c99a04992 jdk9-b11 e88cecf5a21b760ff7d7761c2db6bb8c82bc9f0c jdk9-b12 5eaf717f6e36037a6d3744ffeee0e4c88e64a0d2 jdk9-b13 +32b3fc4bc7374a34d52b7f4e2391b4b4b0c084e8 jdk9-b14 +6bad71866c7598587860e0981b0b0e51ec8c0476 jdk9-b15 +a1461221b05d4620e4d7d1907e2a0282aaedf31c jdk9-b16 diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc deleted file mode 100644 index 8c1f57a8b18..00000000000 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Makefile.inc +++ /dev/null @@ -1,60 +0,0 @@ -########################################################################### -# reserved comment block -# DO NOT REMOVE OR ALTER! -########################################################################### -########################################################################## -# Copyright 2001-2004 The Apache Software Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# -# $Id: Makefile.inc,v 1.2 2004/02/17 16:32:49 minchau Exp $ -# -#################################################################### -# # -# Makefile.inc for XSLT compiler # -# # -#################################################################### - -#################################################################### -# Useful macros # -#################################################################### - -JAVAC = javac -#JAVAC_FLAGS = -g -d $(XSLT)/src/classes -JAVAC_FLAGS = -sourcepath $(XSLT)/src -JAVACC = javacc -JAVACC_FLAGS = -static=FALSE -JAVACUP = javacup -JAVACUP_FLAGS = -JAVALEX = jlex -JAVALEX_FLAGS = - -#################################################################### -# Explicit rules # -#################################################################### - -.SUFFIXES: .java .class .jj .lex .cup - -.java.class: - $(JAVAC) $(JAVAC_FLAGS) $< - -.jj.java: - $(JAVACC) $(JAVACC_FLAGS) $< - -.cup.java: - $(JAVACUP) $(JAVACUP_FLAGS) $< - -.lex.java: - $(JAVALEX) $(JAVALEX_FLAGS) $< - diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory deleted file mode 100644 index a607891fefd..00000000000 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/javax.xml.transform.TransformerFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl b/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl deleted file mode 100644 index 79c33dd2078..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.apache.xerces.dom.DOMImplementationSourceImpl +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList b/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList deleted file mode 100644 index 814f03139f0..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/org.w3c.dom.DOMImplementationSourceList +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.dom.DOMXSImplementationSourceImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory deleted file mode 100644 index 4a5c28226b5..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/datatype/javax.xml.datatype.DatatypeFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory deleted file mode 100644 index dc39440e898..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.DocumentBuilderFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory deleted file mode 100644 index cd8406950db..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/javax.xml.parsers.SAXParserFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory deleted file mode 100644 index 51d33a674c7..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/javax.xml.validation.SchemaFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration deleted file mode 100644 index 8f6ac8baba9..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.DTDConfiguration +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.DTDConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration deleted file mode 100644 index af1926488fd..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XML11Configuration +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.XML11Configuration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration deleted file mode 100644 index ca8bc3e7232..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.apache.xerces.xni.parser.XMLParserConfiguration +++ /dev/null @@ -1 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver deleted file mode 100644 index e1a387435c4..00000000000 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/org.xml.sax.driver +++ /dev/null @@ -1,2 +0,0 @@ -com.sun.org.apache.xerces.internal.parsers.SAXParser - diff --git a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory b/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory deleted file mode 100644 index adc26b34340..00000000000 --- a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLEventFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.xml.internal.stream.events.XMLEventFactoryImpl diff --git a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory b/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory deleted file mode 100644 index 456882c2cb3..00000000000 --- a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLInputFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.xml.internal.stream.XMLInputFactoryImpl diff --git a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory b/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory deleted file mode 100644 index 3de51905314..00000000000 --- a/jaxp/src/com/sun/xml/internal/stream/javax.xml.stream.XMLOutputFactory +++ /dev/null @@ -1 +0,0 @@ -com.sun.xml.internal.stream.XMLOutputFactoryImpl diff --git a/jaxp/src/org/xml/sax/COPYING b/jaxp/src/org/xml/sax/COPYING deleted file mode 100644 index dd0b9813dbc..00000000000 --- a/jaxp/src/org/xml/sax/COPYING +++ /dev/null @@ -1,12 +0,0 @@ -SAX IS FREE ------------ - -I hereby abandon any property rights to SAX 2.0 (the Simple API for -XML), and release all of the SAX 2.0 source code, compiled code, and -documentation contained in this distribution into the Public Domain. -SAX comes with NO WARRANTY or guarantee of fitness for any purpose. - - -David Megginson -david@megginson.com -2000-01-14 diff --git a/jaxp/src/org/xml/sax/COPYING.txt b/jaxp/src/org/xml/sax/COPYING.txt deleted file mode 100644 index 27518b4b9cc..00000000000 --- a/jaxp/src/org/xml/sax/COPYING.txt +++ /dev/null @@ -1,39 +0,0 @@ - SAX COPYRIGHT STATUS - -Version 1.0 of the Simple API for XML (SAX), created collectively by -the membership of the XML-DEV mailing list, is hereby released into -the public domain. - -No one owns SAX: you may use it freely in both commercial and -non-commercial applications, bundle it with your software -distribution, include it on a CD-ROM, list the source code in a book, -mirror the documentation at your own web site, or use it in any other -way you see fit. - - - NO WARRANTY - -Because SAX is released to the public domain, there is no warranty for -the design or for the software implementation, to the extent permitted -by applicable law. Except when otherwise stated in writing the -copyright holders and/or other parties provide SAX "as is" without -warranty of any kind, either expressed or implied, including, but not -limited to, the implied warranties of merchantability and fitness for -a particular purpose. The entire risk as to the quality and -performance of SAX is with you. Should SAX prove defective, you -assume the cost of all necessary servicing, repair or correction. - -In no event unless required by applicable law or agreed to in writing -will any copyright holder, or any other party who may modify and/or -redistribute SAX, be liable to you for damages, including any general, -special, incidental or consequential damages arising out of the use or -inability to use SAX (including but not limited to loss of data or -data being rendered inaccurate or losses sustained by you or third -parties or a failure of the SAX to operate with any other programs), -even if such holder or other party has been advised of the possibility -of such damages. - - -David Megginson -1998-05-11 - diff --git a/jaxws/.hgtags b/jaxws/.hgtags index b2197334dde..b6167002ea2 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -259,3 +259,6 @@ c9e8bb8c1144a966ca7b481142c6b5e55d14a29c jdk9-b09 1f953ba7db2b535e19f0354abfee6d67605e0684 jdk9-b11 779f8b21c75f83e3918dac8499e4d0ecb3a54ed7 jdk9-b12 3d42204854c9f703e3ccdc8891248e73057713ab jdk9-b13 +02e58850b7062825308413d420f2b02c1f25a724 jdk9-b14 +e9780330017a6b464a385356d77e5136f9de8d09 jdk9-b15 +1e1a3b2215b7551d88e89d1ca8c1e1ebe3d3c0ab jdk9-b16 diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory b/jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory deleted file mode 100644 index 36ea2a98abe..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/etc/META-INF/services/com.sun.xml.internal.ws.spi.db.BindingContextFactory +++ /dev/null @@ -1,2 +0,0 @@ -com.sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory -# com.sun.xml.internal.ws.db.toplink.JAXBContextFactory diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng deleted file mode 100644 index 59bcb4e49bc..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/config.rng +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - import java.util.List; - import java.util.ArrayList; - import java.io.File; - - - - private File baseDir; - private Classes classes; - private List schema = new ArrayList(); - public Classes getClasses() { return this.classes;} - public File getBaseDir() { return baseDir;} - public List getSchema() { return this.schema;} - - - - - bd = - baseDir = $runtime.getBaseDir(bd); - - - - (baseDir); - this.schema.add (_schema); - - - - - - - - import java.util.List; - import java.util.ArrayList; - - - private List includes = new ArrayList(); - public List getIncludes() { return $runtime.getIncludePatterns(this.includes);} - private List excludes = new ArrayList(); - public List getExcludes() { return $runtime.getExcludePatterns(this.excludes);} - - - - - - - - this.includes.add(include_content); - - - - - - - - - - this.excludes.add(exclude_content); - - - - - - - - - - - - import java.io.File; - - - private File location; - private String namespace; - public String getNamespace() { return this.namespace;} - public File getLocation() { return this.location;} - - - - - namespace = - - - - - - loc = - location = new File(baseDir,loc); - - - - - diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng deleted file mode 100644 index 41c18ff0d1d..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/bindingfile.rng +++ /dev/null @@ -1,317 +0,0 @@ - - - - - - - - - - - 1.0ea2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class - - - - - - - - - - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sequence - choice - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - list - set - vector - - - - - - - - - - - - - - - - - - - - - - - - preserve - replace - collapse - - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng deleted file mode 100644 index f689228d585..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/binding.rng +++ /dev/null @@ -1,913 +0,0 @@ - - - - -]> - - - - - import com.sun.codemodel.internal.*; - import com.sun.tools.internal.xjc.generator.bean.field.*; - import com.sun.tools.internal.xjc.model.*; - import com.sun.xml.internal.bind.api.impl.NameConverter; - import com.sun.xml.internal.bind.v2.WellKnownNamespace; - import com.sun.xml.internal.bind.marshaller.SAX2DOMEx; - import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.*; - import com.sun.tools.internal.xjc.reader.Const; - import org.xml.sax.*; - import org.w3c.dom.Document; - import org.xml.sax.helpers.DefaultHandler; - import java.util.*; - import javax.xml.namespace.QName; - import javax.xml.parsers.ParserConfigurationException; - - - - - - - - - - - - - - - - import java.io.StringWriter; - import com.sun.xml.internal.bind.marshaller.DataWriter; - - - // customization declarations - public BindInfo bi; - - private StringWriter w; - - private SAX2DOMEx sax2dom; - - - - bi = new BindInfo($runtime.copyLocator()); - $runtime.currentBindInfo = bi; - - - - - - - - - - result = - bi.addDecl(result); - - - - - - - - - if($runtime.isExtensionURI($uri)) { - // parse this sub-tree as an extension - try { - sax2dom = new SAX2DOMEx(); - } catch( ParserConfigurationException e ) { - throw new Error(e); // impossible - } - $runtime.redirectSubtree(sax2dom,$uri,$localName,$qname); - } else { - // ignore this sub-tree - sax2dom = null; - $runtime.redirectSubtree(new DefaultHandler(),$uri,$localName,$qname); - } - - - if(sax2dom!=null) { - bi.addDecl(new BIXPluginCustomization(((Document)sax2dom.getDOM()).getDocumentElement(),$runtime.copyLocator())); - } - - - - - - - - - - - - msg = - bi.appendDocumentation($runtime.truncateDocComment(msg),true); - - - - - w = new StringWriter(); - DataWriter xw = new DataWriter(w,"UTF-8"); - xw.setXmlDecl(false); - $runtime.redirectSubtree(xw,$uri,$localName,$qname); - - - - "+ - $runtime.escapeMarkup($runtime.truncateDocComment(w.toString()))+ - "", - false ); - w=null; - ]]> - - - - - - - - - - - - - - - - - private BIDeclaration result; - - - - result = - result = - result = - result = - result = - result = - result = - - - - - - - - - - private Locator loc; - private Map globalConvs = new HashMap(); - private NameConverter nameConverter = NameConverter.standard; - private String enableJavaNamingConvention = "true"; - private String fixedAttrToConstantProperty = "false"; - private String needIsSetMethod = "false"; - private String simpleTypeSubstitution = "false"; - private boolean flattenClasses = false; - private Set enumBaseTypes = new HashSet(); - private int defaultEnumSizeCap = 256; - private boolean generateEnumMemberName = false; - private boolean choiceContentPropertyWithModelGroupBinding = false; - private boolean xSmartWildcardDefaultBinding = false; - private boolean xSimpleMode; - private boolean generateValueClass = true; - private boolean generateElementClass = false; - private boolean generateMixedExtensions = false; - - public BIGlobalBinding makeResult() { - if( enumBaseTypes.size()==0 ) - enumBaseTypes.add(new QName(WellKnownNamespace.XML_SCHEMA,"NCName")); // defaults to NCName - - return new BIGlobalBinding( - globalConvs,nameConverter, - choiceContentPropertyWithModelGroupBinding, - generateValueClass, - generateElementClass, - $runtime.parseBoolean(enableJavaNamingConvention), - $runtime.parseBoolean(fixedAttrToConstantProperty), - $runtime.parseBoolean(needIsSetMethod), - $runtime.parseBoolean(simpleTypeSubstitution), - generateEnumMemberName, - flattenClasses, - enumBaseTypes, - defaultEnumSizeCap, - ct, - serializable, - xSuperClass, - xSuperInterface, - xSimpleMode, - xSmartWildcardDefaultBinding, - loc); - } - - - loc = $runtime.copyLocator(); - - - - - asWordSeparator - - asCharInWord - nameConverter = NameConverter.jaxrpcCompatible; - - - - - - - - enableJavaNamingConvention = - - - - - - fixedAttrToConstantProperty = - - - - - - needIsSetMethod = - - - - - - simpleTypeSubstitution = - - - - - - - - nested - flattenClasses = false; - - - toplevel - flattenClasses = true; - - - - - - - - ct = - - - - - - - generateError - - generateName - generateEnumMemberName = true; - - - - - - - - - - value = - QName qn = $runtime.parseQName(value); - enumBaseTypes.add( qn ); - - - - - - - - - - value = - defaultEnumSizeCap = Integer.parseInt(value); - - - - - - - - - value = - choiceContentPropertyWithModelGroupBinding = $runtime.parseBoolean(value); - - - - - - value = - generateValueClass = $runtime.parseBoolean(value); - - - - - - value = - generateElementClass = $runtime.parseBoolean(value); - - - - - - value = - generateMixedExtensions = $runtime.parseBoolean(value); - - - - - - - value = - if( $runtime.parseBoolean(value)==true ) - $runtime.reportUnsupportedFeature("enableValidation"); - - - - - value = - if( $runtime.parseBoolean(value)==true ) - $runtime.reportUnsupportedFeature("enableFailFastCheck"); - - - - - - - - - xmlType = - - conv = - - globalConvs.put( $runtime.parseQName(xmlType), conv ); - - - - - serialuid = - - - if(serialuid!=null) - serializable = new BISerializable(Long.parseLong(serialuid)); - else - serializable = new BISerializable(null); - - - - serializable = - xSuperClass = - xSuperInterface = - - - - xSmartWildcardDefaultBinding = true; - - - - - xSimpleMode = true; - - - - - - - - - - - - - - - - - - - - - - - - - - private Locator loc; - public BISchemaBinding makeResult() { - return new BISchemaBinding(packageName,javadoc,tt,et,at,mt,nt,loc); - } - - - - loc = $runtime.copyLocator(); - - - - - packageName = - - - javadoc = - - - - - - - - - - - tt = - - - et = - - - at = - - - mt = - - - nt = - - - - - - - - - - - - private String prefix=""; - private String suffix=""; - - - - - - prefix = - - - - - suffix = - - - - - - - - - javadoc = - javadoc = $runtime.truncateDocComment(javadoc); - - - - - - private FieldRenderer r = null; - - type = - - if( type.equals("indexed") ) - r = FieldRenderer.ARRAY; - else - try { - r = new UntypedListFieldRenderer( $runtime.codeModel.ref(type) ); - } catch( ClassNotFoundException e ) { - throw new NoClassDefFoundError(e.getMessage()); - } - - - - - - - - private Locator loc; - public BIClass makeResult() { - return new BIClass(loc,name,implClass,javadoc); - } - - - - loc = $runtime.copyLocator(); - - javadoc = - - - - name = - - - - implClass = - - - - - - - - private Locator loc; - private Boolean isConst = null; - private Boolean isSet = null; - private Boolean genElemProp = null; - - public BIProperty makeResult() throws SAXException { - JType baseTypeRef = null; - if(baseType!=null) - baseTypeRef = $runtime.getType(baseType); - - return new BIProperty(loc,name,javadoc,baseTypeRef,conv,ct,isConst,isSet,genElemProp); - } - - - - loc = $runtime.copyLocator(); - - name = - - - baseType = - - - - ct = - - - - - isConstStr = - isConst = $runtime.parseBoolean(isConstStr)?Boolean.TRUE:Boolean.FALSE; - - - - - isSetStr = - isSet = $runtime.parseBoolean(isSetStr)?Boolean.TRUE:Boolean.FALSE; - - - - - genElemPropStr = - genElemProp = $runtime.parseBoolean(genElemPropStr)?Boolean.TRUE:Boolean.FALSE; - - - - - failFast = - - if( $runtime.parseBoolean(failFast) ) { - $runtime.reportUnimplementedFeature("generateFailFastSetterMethod"); - } - - - - - - javadoc = - - - - conv = - - - - - - - - - r = - - - - - - - - import com.sun.tools.internal.xjc.generator.util.WhitespaceNormalizer; - - - - - - parse = - - - print = - - - - - _context = - context = $runtime.parseBoolean(_context); - - - - - - - - - - import java.util.HashMap; - - - private HashMap members = new HashMap(); - private boolean dontBind = false; - private Locator loc,loc2; - - private BIEnum makeResult() { - return new BIEnum(loc,dontBind,name,javadoc,members); - } - - - - loc = $runtime.copyLocator(); - - - false - dontBind = true; - - - - name = - - - javadoc = - - - jname = null; - javadoc = null; - - loc2 = $runtime.copyLocator(); - - jname = - - value = - - javadoc = - - members.put( value, new BIEnumMember(loc2,jname,javadoc) ); - - - - - - - - - - - - - private Locator loc; - private BIEnumMember makeResult() { - return new BIEnumMember(loc,name,javadoc); - } - - - - loc = $runtime.copyLocator(); - name = - - javadoc = - - - - - - - - - private JDefinedClass makeResult() { - try { - JDefinedClass c = $runtime.codeModel._class(name); - c.hide(); - return c; - } catch( JClassAlreadyExistsException e ) { - return e.getExistingClass(); - } - } - - - - name = - - - - - - - private JDefinedClass makeResult() { - try { - JDefinedClass c = $runtime.codeModel._class(name,ClassType.INTERFACE); - c.hide(); - return c; - } catch( JClassAlreadyExistsException e ) { - return e.getExistingClass(); - } - } - - - - name = - - - - - - - private long uid = 1; - private BISerializable makeResult() { - return new BISerializable(uid); - } - - - -// loc = $runtime.copyLocator(); - - - v = - uid = Long.parseLong(v); - - - - - - - - - - complex - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng deleted file mode 100644 index 88eb2f56610..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/xmlschema/xmlschema-for-jaxb.rng +++ /dev/null @@ -1,1579 +0,0 @@ - - - - - - - RELAX NG schema for XML Schema by Jeni Tennison. Based on - XML - Schema Part I: Structures Recommendation and XML Schema Part - II: Datatypes. - - - - Amended to comply with 10 August 2001 Tutorial. - - Removed key attributes. - Replaced not element with except elements. - - Replaced multiple consecutive optional attributes to use the - zeroOrMore/choice pattern. - - - Removed interleave elements inside list elements (which are no longer - permitted). - - - - - - This allows any number of attributes that are not in the XML Schema - namespace or are in no namespace. This is somewhat more complicated than - the XML Schema anyAttribute equivalent. - - - - - - - - - This allows any number of attributes that are not in the XML Schema - namespace or are in no namespace, an optional id attribute of type ID, - and an optional annotation element. This is used as the basis for many - element content models. - - - - - - - - - - - - - - - This gives the content model of the top level of the schema. - - - - - - - - - - - - This gives the components that can be redefined within the redefine - element. They also occur at the top level of the schema. - - - - - - - - - - - This gives the values for the various form attributes: - elementFormDefault and attributeFormDefault on the schema element, and - the form attributes on the element and attribute elements. - - - qualified - unqualified - - - - - - - This gives the values that can be taken in the lists used to control - derivation by extension or restriction (this is 'reduced' derivation - because some derivation can involve substitution). This RELAX NG schema, - like the XML Schema Recommendation here, allows the keywords 'extension' and - 'restriction' to be repeated any number of times. - - - - - extension - restriction - - - - - - - - This specifies the possible values for attributes that control derivation. - - - #all - - - - - - - This is the beginning point for the schema, and defines the schema - element. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This gives the value type for the maxOccurs attribute, which may be a - non-negative number or the keyword 'unbounded'. - - - - unbounded - - - - - - This specifies the occurs attributes, minOccurs and maxOccurs, as they - are normally used. - - - - - - - - - - - - - - - - This gives the possible content of complex types. - - - - - - - - - - - - This gives the particles that can make up a model group. - - - - - - - - - - - - - This specifies the relationship between fixed and default attributes on - element and attribute elements - if one is present, then the other cannot - be. This is a constraint that cannot be specified using XML Schema. - - - - - - - - - - - This specifies the relationship between the type attribute and the - simpleType element child of attribute elements - if one is present, then - the other cannot be, although it is possible for neither to be allowed. - - - - - - - - - - - - - This describes attribute elements when used in a local context. They - have an optional use attribute, possibly a fixed or default attribute, - and then can either have a ref attribute (referring to a top-level - attribute) or a name attribute with an optional form attribute and - specifying an attribute type. - - - - - - - optional - prohibited - required - - - - - - - - - - - - - - - - - - - - - - - - - - This describes attribute elements when used at the top level of the - schema. They must have a name, may have a fixed or default attribute, - and specify their type through a type attribute or child simpleType - element. The name attribute of each attribute element that appears at - the top level of the schema is unique. - - - - - - - - - - - - - - This gives the model group for specifying the attributes in a complex - type, an extension or restriction. - - - - - - - - - - - - - - - This specifies the anyAttribute wildcard. - - - - - - - - - This specifies the content of a complexType element. As children, it can - have a simpleContent, a complexContent or a model group. Only if it has - one of the latter two, may it have a mixed attribute. This latter - constraint is something that cannot be specified in XML Schema. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This specifies the basic content of a complexType element. - - - - - - - - - - - - - - - - - - - - - - - - - - - This describes a restriction element within a complexContent element - (i.e. one that restricts a complex type). It has a base attribute, may - contain a model group and may contain attribute declarations of various - sorts. - - - - - - - - - - - - - - - - This specifies the basic model for an extension element: adding a - required base attribute to the model used for most components. - - - - - - - - - - This describes an extension element within a complexContent element - (i.e. one that restricts a complex type). It may contain a model group - and may contain attribute declarations of various sorts. - - - - - - - - - - - - - This describes a complexContent element. It may have a mixed attribute, - and either a restriction or extension element as content. - - - - - - - - - - - - - - - - - - This describes a restriction element that appears within a simpleContent - or simpleType element (i.e. one that restricts a simple type). Its - content follows the simple restriction model that is detailed below, and - may include attribute declarations. - - - - - - - - - - - This describes an extension element that appears within a simpleContent - element (i.e. one that extends a simple type). Like other extensions, it - has a base type, but it can only be used to add attributes. - - - - - - - - - - This describes a simpleContent element, whose content can either hold a - restriction or extension element. - - - - - - - - - - - - - This gives the possible values for block attributes on element elements, - which includes substitution amongst the list of possible values. This - RELAX NG schema, like the XML Schema Recommendation, allows each of the - keywords 'extension', 'restriction' and 'substitution' to occur more than - once within the list. - - - #all - - - - extension - restriction - substitution - - - - - - - - - This describes the basic content model of an element element. It is - annotated, may have a fixed or default attribute, and may have nillable - and/or block attributes. Its type may be specified through a type - attribute, a local simple type or a local complex type - the choice - between these methods is something that cannot be indicated with XML - Schema. This content is optionally followed by some identify constraints. - - - - - - - - - - - - - - - - - - - - - - - - - - - This describes an element element that appears at the top level of the - schema. On top of the basic content for an element element, it has to - have a name, which is a unique identifier in the element symbol space. It - may have substitutionGroup, abstract and/or final attributes. - - - - - - - - - - - - - - - - - - - - - - - - - This describes an element element that appears locally, within a - complexType or group element. It may have minOccurs and/or maxOccurs - attributes. If it has a ref attribute, then that's all it can - have. Otherwise, it must have a name and specifies its type in the same - way as the basic element content model described above. It may in this - case also have a form element. These constraints on local elements - cannot be described within XML Schema. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This gives the content of a model group (not a group element) in the - normal run of things. It has occurrence attributes and any number of - particles within it. - - - - - - - - - - - This gives the content of a model group (not a group element) within a - named group - it differs from the above in that it doesn't have any - occurrence attributes. - - - - - - - - - - This describes an all element that appears outside a named group (i.e. as - the content of a complexType element). It has the standard model for an - all element, but adds minOccurs and maxOccurs attributes which can only - take certain values. - - - - - - - - - This describes a choice element that appears outside a named group. - - - - - - - - - This describes a sequence element that appears outside a named group. - - - - - - - - - This describes a wildcard element (i.e. any or anyAttribute). The - namespace attribute can take a list URIs interspersed with the keywords - '##targetNamespace' and/or '##local'. This RELAX NG schema, like the XML - Schema Recommendation, allows the keywords to be specified more than once - each within the list, if they're given. This model also specifies the - processContents attribute. - - - - - - - ##any - ##other - - - - - ##targetNamespace - ##local - - - - - - - - lax - skip - strict - - - - - - - - - This describes an any element as a wildcard. - - - - - - - - - - - - - - - - - - This describes an import element that's used when its parent schema - element specifies a targetNamespace. In these cases, the namespace - attribute on the import element is optional. - - - - - - - - - - - - - - - - - - - - - - - This is designed to describe the content of the appinfo elements in the - schema. At the moment this allows any mixed content without validation. - Note that this is fairly complex compared to the XML Schema equivalent, - which would be a single any element. - - - - - - - - - - - - This describes an appinfo element. It has an optional source attribute - and can currently contain anything at all. - - - - - - - - - - - - - - This is designed to describe the content of the documentation elements in - the schema. At the moment this allows any mixed content without - validation. Note that this is fairly complex compared to the XML Schema - equivalent, which would be a single any element. - - - - - - - This describes a documentation element. It has optional source - and xml:lang attributes and can currently contain anything at all. - - - - - - - - - - - - - - - - - - - This describes an annotation element. It can have any attributes, may - have an id attribute, and contains any number of documentation or appinfo - elements. - - - - - - - - - - - - - - - - - - - - This gives the various types of derivation of simple types. - - - - - - - - - - - This specifies the values of the final attribute for simple types. This - RELAX NG schema for XML Schema, like the XML Schema Recommendation, allows - the keywords 'list', 'union' and 'restriction' to appear more than once - within the list. - - - #all - - - - list - union - restriction - - - - - - - - - - - - - - This gives the basic content of a simple type. - - - - - - - - - - - - - - - - - - - - - - This specifies the types of facets that are valid in restrictions on the - built-in data types. This can only perform rudimentary checking, but - should be enough in most circumstances. Note that for xs:anySimpleType - and xs:string, the whiteSpace facet can take any value, for - xs:normalizedString it can be 'replace' or 'collapse', and for all other - built-in types it has to be 'collapse'. - - - - - - - - - - - - - - - - - - - This describes a list element. It can either specify a local simple type - or have a itemType attribute. This constraint cannot be expressed in XML - Schema. - - - - - - - - - - - - - - - This describes a union element. If the memberTypes attribute is missing - or empty, then it must contain one or more simpleType elements; if - it's present, then it can contain simpleType elements or list simple - types in the memberTypes attribute. This constraint cannot be expressed - in XML Schema. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This is the basic content of a facet. It has an optional fixed attribute. - - - - - - - - - - - - This is the content of a facet that cannot be fixed (enumeration or - pattern). It has a value attribute that can take any kind of value. - - - - - - - - - - This describes an enumeration element. - - - - - - - - - diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java index bc35f38f8da..ead4533885d 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java @@ -582,7 +582,8 @@ public class AttachmentPartImpl extends AttachmentPart { mailMap.addMailcap("text/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); mailMap.addMailcap("application/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); mailMap.addMailcap("application/fastinfoset;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler"); - mailMap.addMailcap("multipart/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler"); + // this handler seems to be not used according VCS history ... + // mailMap.addMailcap("multipart/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler"); mailMap.addMailcap("image/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler"); mailMap.addMailcap("text/plain;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler"); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj deleted file mode 100644 index c0b8d256cbd..00000000000 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/compact/CompactSyntax.jj +++ /dev/null @@ -1,1963 +0,0 @@ -options { - STATIC = false; - UNICODE_INPUT = true; - JAVA_UNICODE_ESCAPE = true; -} - -PARSER_BEGIN(CompactSyntax) - -package com.sun.xml.internal.rngom.parse.compact; - -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; - -import com.sun.xml.internal.rngom.ast.builder.Annotations; -import com.sun.xml.internal.rngom.ast.builder.BuildException; -import com.sun.xml.internal.rngom.ast.builder.CommentList; -import com.sun.xml.internal.rngom.ast.builder.DataPatternBuilder; -import com.sun.xml.internal.rngom.ast.builder.Div; -import com.sun.xml.internal.rngom.ast.builder.ElementAnnotationBuilder; -import com.sun.xml.internal.rngom.ast.builder.Grammar; -import com.sun.xml.internal.rngom.ast.builder.GrammarSection; -import com.sun.xml.internal.rngom.ast.builder.Include; -import com.sun.xml.internal.rngom.ast.builder.IncludedGrammar; -import com.sun.xml.internal.rngom.ast.builder.NameClassBuilder; -import com.sun.xml.internal.rngom.ast.builder.SchemaBuilder; -import com.sun.xml.internal.rngom.ast.builder.Scope; -import com.sun.xml.internal.rngom.ast.om.Location; -import com.sun.xml.internal.rngom.ast.om.ParsedElementAnnotation; -import com.sun.xml.internal.rngom.ast.om.ParsedNameClass; -import com.sun.xml.internal.rngom.ast.om.ParsedPattern; -import com.sun.xml.internal.rngom.parse.Context; -import com.sun.xml.internal.rngom.parse.IllegalSchemaException; -import com.sun.xml.internal.rngom.parse.Parseable; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.LocatorImpl; - -import com.sun.xml.internal.rngom.util.Localizer; -import com.sun.xml.internal.rngom.xml.util.WellKnownNamespaces; - - -public class CompactSyntax implements Context { - private static final int IN_ELEMENT = 0; - private static final int IN_ATTRIBUTE = 1; - private static final int IN_ANY_NAME = 2; - private static final int IN_NS_NAME = 4; - - private String defaultNamespace; - private String compatibilityPrefix = null; - private SchemaBuilder sb; - private NameClassBuilder ncb; - private String sourceUri; - /** - * This is what we are parsing right now. - */ - private CompactParseable parseable; - private ErrorHandler eh; - private final Hashtable namespaceTable = new Hashtable(); - private final Hashtable datatypesTable = new Hashtable(); - private boolean hadError = false; - private static final Localizer localizer = new Localizer(new Localizer(Parseable.class),CompactSyntax.class); - private final Hashtable attributeNameTable = new Hashtable(); - private boolean annotationsIncludeElements = false; - - /** - * String that represents the inherited namespace. - * - *

- * HACK: we always allocate a new String instance so that - * we can distinguish inherited value from the explicitly - * given value. - */ - private /*final*/ String inheritedNs; // essentially final but JavaCC don't let us declare it as so. - - final class LocatedString { - private final String str; - private final Token tok; - - LocatedString(String str, Token tok) { - this.str = str; - this.tok = tok; - } - - String getString() { - return str; - } - - Location getLocation() { - return makeLocation(tok); - } - - Token getToken() { - return tok; - } - - } - - public CompactSyntax(CompactParseable parseable, Reader r, String sourceUri, SchemaBuilder sb, ErrorHandler eh, String inheritedNs) { - this(r); - this.sourceUri = sourceUri; - this.parseable = parseable; - this.sb = sb; - this.ncb = sb.getNameClassBuilder(); - this.eh = eh; - // this causes the root pattern to have non-null annotations - // which is useful because it gives a context to trang - this.topLevelComments = sb.makeCommentList(); - this.inheritedNs = defaultNamespace = new String(inheritedNs); - } - - ParsedPattern parse(Scope scope) throws IllegalSchemaException { - try { - ParsedPattern p = Input(scope); - if (!hadError) - return p; - } - catch (ParseException e) { - error("syntax_error", e.getMessage(), e.currentToken.next); - } - catch (EscapeSyntaxException e) { - reportEscapeSyntaxException(e); - } - throw new IllegalSchemaException(); - } - - ParsedPattern parseInclude(IncludedGrammar g) throws IllegalSchemaException { - try { - ParsedPattern p = IncludedGrammar(g); - if (!hadError) - return p; - } - catch (ParseException e) { - error("syntax_error", e.getMessage(), e.currentToken.next); - } - catch (EscapeSyntaxException e) { - reportEscapeSyntaxException(e); - } - throw new IllegalSchemaException(); - } - - private void checkNsName(int context, LocatedString ns) { - if ((context & IN_NS_NAME) != 0) - error("ns_name_except_contains_ns_name", ns.getToken()); - } - - private void checkAnyName(int context, Token t) { - if ((context & IN_NS_NAME) != 0) - error("ns_name_except_contains_any_name", t); - if ((context & IN_ANY_NAME) != 0) - error("any_name_except_contains_any_name", t); - } - - private void error(String key, Token tok) { - doError(localizer.message(key), tok); - } - - private void error(String key, String arg, Token tok) { - doError(localizer.message(key, arg), tok); - } - - private void error(String key, String arg1, String arg2, Token tok) { - doError(localizer.message(key, arg1, arg2), tok); - } - - private void doError(String message, Token tok) { - hadError = true; - if (eh != null) { - LocatorImpl loc = new LocatorImpl(); - loc.setLineNumber(tok.beginLine); - loc.setColumnNumber(tok.beginColumn); - loc.setSystemId(sourceUri); - try { - eh.error(new SAXParseException(message, loc)); - } - catch (SAXException se) { - throw new BuildException(se); - } - } - } - - private void reportEscapeSyntaxException(EscapeSyntaxException e) { - if (eh != null) { - LocatorImpl loc = new LocatorImpl(); - loc.setLineNumber(e.getLineNumber()); - loc.setColumnNumber(e.getColumnNumber()); - loc.setSystemId(sourceUri); - try { - eh.error(new SAXParseException(localizer.message(e.getKey()), loc)); - } - catch (SAXException se) { - throw new BuildException(se); - } - } - } - - private static String unquote(String s) { - if (s.length() >= 6 && s.charAt(0) == s.charAt(1)) { - s = s.replace('\u0000', '\n'); - return s.substring(3, s.length() - 3); - } - else - return s.substring(1, s.length() - 1); - } - - Location makeLocation(Token t) { - return sb.makeLocation(sourceUri, t.beginLine, t.beginColumn); - } - - private static ParsedPattern[] addPattern(ParsedPattern[] patterns, int i, ParsedPattern p) { - if (i >= patterns.length) { - ParsedPattern[] oldPatterns = patterns; - patterns = new ParsedPattern[oldPatterns.length*2]; - System.arraycopy(oldPatterns, 0, patterns, 0, oldPatterns.length); - } - patterns[i] = p; - return patterns; - } - - String getCompatibilityPrefix() { - if (compatibilityPrefix == null) { - compatibilityPrefix = "a"; - while (namespaceTable.get(compatibilityPrefix) != null) - compatibilityPrefix = compatibilityPrefix + "a"; - } - return compatibilityPrefix; - } - - public String resolveNamespacePrefix(String prefix) { - String result = (String)namespaceTable.get(prefix); - if (result.length() == 0) - return null; - return result; - } - - public Enumeration prefixes() { - return namespaceTable.keys(); - } - - public String getBaseUri() { - return sourceUri; - } - - public boolean isUnparsedEntity(String entityName) { - return false; - } - - public boolean isNotation(String notationName) { - return false; - } - - public Context copy() { - return this; - } - - private Context getContext() { - return this; - } - - private CommentList getComments() { - return getComments(getTopLevelComments()); - } - - private CommentList topLevelComments; - - private CommentList getTopLevelComments() { - CommentList tem = topLevelComments; - topLevelComments = null; - return tem; - } - - private void noteTopLevelComments() { - topLevelComments = getComments(topLevelComments); - } - - private void topLevelComments(GrammarSection section) { - section.topLevelComment(getComments(null)); - } - - private Token lastCommentSourceToken = null; - - private CommentList getComments(CommentList comments) { - Token nextToken = getToken(1); - if (lastCommentSourceToken != nextToken) { - if (lastCommentSourceToken == null) - lastCommentSourceToken = token; - do { - lastCommentSourceToken = lastCommentSourceToken.next; - Token t = lastCommentSourceToken.specialToken; - if (t != null) { - while (t.specialToken != null) - t = t.specialToken; - if (comments == null) - comments = sb.makeCommentList(); - for (; t != null; t = t.next) { - String s = mungeComment(t.image); - Location loc = makeLocation(t); - if (t.next != null - && t.next.kind == CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE) { - StringBuffer buf = new StringBuffer(s); - do { - t = t.next; - buf.append('\n'); - buf.append(mungeComment(t.image)); - } while (t.next != null - && t.next.kind == CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE); - s = buf.toString(); - } - comments.addComment(s, loc); - } - } - } while (lastCommentSourceToken != nextToken); - } - return comments; - } - - private ParsedPattern afterComments(ParsedPattern p) { - CommentList comments = getComments(null); - if (comments == null) - return p; - return sb.commentAfter(p, comments); - } - - private ParsedNameClass afterComments(ParsedNameClass nc) { - CommentList comments = getComments(null); - if (comments == null) - return nc; - return ncb.commentAfter(nc, comments); - } - - private static String mungeComment(String image) { - int i = image.indexOf('#') + 1; - while (i < image.length() && image.charAt(i) == '#') - i++; - if (i < image.length() && image.charAt(i) == ' ') - i++; - return image.substring(i); - } - - private Annotations getCommentsAsAnnotations() { - CommentList comments = getComments(); - if (comments == null) - return null; - return sb.makeAnnotations(comments, getContext()); - } - - private Annotations addCommentsToChildAnnotations(Annotations a) { - CommentList comments = getComments(); - if (comments == null) - return a; - if (a == null) - a = sb.makeAnnotations(null, getContext()); - a.addComment(comments); - return a; - } - - private Annotations addCommentsToLeadingAnnotations(Annotations a) { - CommentList comments = getComments(); - if (comments == null) - return a; - if (a == null) - return sb.makeAnnotations(comments, getContext()); - a.addLeadingComment(comments); - return a; - } - - private Annotations getTopLevelCommentsAsAnnotations() { - CommentList comments = getTopLevelComments(); - if (comments == null) - return null; - return sb.makeAnnotations(comments, getContext()); - } - - private void clearAttributeList() { - attributeNameTable.clear(); - } - - private void addAttribute(Annotations a, String ns, String localName, String prefix, String value, Token tok) { - String key = ns + "#" + localName; - if (attributeNameTable.get(key) != null) - error("duplicate_attribute", ns, localName, tok); - else { - attributeNameTable.put(key, key); - a.addAttribute(ns, localName, prefix, value, makeLocation(tok)); - } - } - - private void checkExcept(Token[] except) { - if (except[0] != null) - error("except_missing_parentheses", except[0]); - } - - private String lookupPrefix(String prefix, Token t) { - String ns = (String)namespaceTable.get(prefix); - if (ns == null) { - error("undeclared_prefix", prefix, t); - return "#error"; - } - return ns; - } - private String lookupDatatype(String prefix, Token t) { - String ns = (String)datatypesTable.get(prefix); - if (ns == null) { - error("undeclared_prefix", prefix, t); - return ""; // XXX - } - return ns; - } - private String resolve(String str) { - try { - return new URL(new URL(sourceUri), str).toString(); - } - catch (MalformedURLException e) { } - return str; - } -} - -PARSER_END(CompactSyntax) - -ParsedPattern Input(Scope scope) : -{ - ParsedPattern p; -} -{ - Preamble() - (LOOKAHEAD(TopLevelLookahead()) p = TopLevelGrammar(scope) - | p = Expr(true, scope, null, null) { p = afterComments(p); } ) - { return p; } -} - -void TopLevelLookahead() : -{} -{ - "[" - | Identifier() ("[" | "=" | "&=" | "|=") - | LookaheadGrammarKeyword() - | LookaheadBody() LookaheadAfterAnnotations() - | LookaheadDocumentation() (LookaheadBody())? LookaheadAfterAnnotations() -} - -void LookaheadAfterAnnotations() : -{} -{ - Identifier() ("=" | "&=" | "|=") - | LookaheadGrammarKeyword() -} - -void LookaheadGrammarKeyword() : -{} -{ - "start" | "div" | "include" -} - -void LookaheadDocumentation() : -{} -{ - (( | ) ()*)+ -} - -void LookaheadBody() : -{} -{ - "[" - ( | UnprefixedName() | "=" | | "~" | LookaheadBody() )* - "]" -} - -ParsedPattern IncludedGrammar(IncludedGrammar g) : -{ - Annotations a; - ParsedPattern p; -} -{ - Preamble() - (LOOKAHEAD(TopLevelLookahead()) a = GrammarBody(g, g, getTopLevelCommentsAsAnnotations()) - | a = Annotations() "grammar" "{" a = GrammarBody(g, g, a) { topLevelComments(g); } "}") - { p = afterComments(g.endIncludedGrammar(sb.makeLocation(sourceUri, 1, 1), a)); } - - { return p; } -} - -ParsedPattern TopLevelGrammar(Scope scope) : -{ - Annotations a = getTopLevelCommentsAsAnnotations(); - Grammar g; - ParsedPattern p; -} -{ - { g = sb.makeGrammar(scope); } - a = GrammarBody(g, g, a) - { p = afterComments(g.endGrammar(sb.makeLocation(sourceUri, 1, 1), a)); } - - { return p; } -} - -void Preamble() : -{} -{ - (NamespaceDecl() | DatatypesDecl())* - { - namespaceTable.put("xml", WellKnownNamespaces.XML); - if (datatypesTable.get("xsd") == null) - datatypesTable.put("xsd", WellKnownNamespaces.XML_SCHEMA_DATATYPES); - } -} - -void NamespaceDecl() : -{ - LocatedString prefix = null; - boolean isDefault = false; - String namespaceName; -} -{ - { noteTopLevelComments(); } - (("namespace" prefix = UnprefixedName()) - | ("default" { isDefault = true; } - "namespace" (prefix = UnprefixedName())?)) - "=" - namespaceName = NamespaceName() - { - if (isDefault) - defaultNamespace = namespaceName; - if (prefix != null) { - if (prefix.getString().equals("xmlns")) - error("xmlns_prefix", prefix.getToken()); - else if (prefix.getString().equals("xml")) { - if (!namespaceName.equals(WellKnownNamespaces.XML)) - error("xml_prefix_bad_uri", prefix.getToken()); - } - else if (namespaceName.equals(WellKnownNamespaces.XML)) - error("xml_uri_bad_prefix", prefix.getToken()); - else { - if (namespaceName.equals(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_ANNOTATIONS)) - compatibilityPrefix = prefix.getString(); - namespaceTable.put(prefix.getString(), namespaceName); - } - } - } -} - -String NamespaceName() : -{ - String r; -} -{ - (r = Literal() | "inherit" { r = this.inheritedNs; }) - { return r; } -} - -void DatatypesDecl() : -{ - LocatedString prefix; - String uri; -} -{ - { noteTopLevelComments(); } - "datatypes" prefix = UnprefixedName() "=" uri = Literal() - { - datatypesTable.put(prefix.getString(), uri); - } -} - -ParsedPattern AnnotatedPrimaryExpr(boolean topLevel, Scope scope, Token[] except) : -{ - Annotations a; - ParsedPattern p; - ParsedElementAnnotation e; - Token t; -} -{ - a = Annotations() - p = PrimaryExpr(topLevel, scope, a, except) - ( t = e = AnnotationElement(false) { - if (topLevel) - error("top_level_follow_annotation", t); - else - p = sb.annotateAfter(p, e); - })* - { return p; } -} - - -ParsedPattern PrimaryExpr(boolean topLevel, Scope scope, Annotations a, Token[] except) : -{ - ParsedPattern p; -} -{ - (p = ElementExpr(scope, a) - | p = AttributeExpr(scope, a) - | p = GrammarExpr(scope, a) - | p = ExternalRefExpr(scope, a) - | p = ListExpr(scope, a) - | p = MixedExpr(scope, a) - | p = ParenExpr(topLevel, scope, a) - | p = IdentifierExpr(scope, a) - | p = ParentExpr(scope, a) - | p = DataExpr(topLevel, scope, a, except) - | p = ValueExpr(topLevel, a) - | p = TextExpr(a) - | p = EmptyExpr(a) - | p = NotAllowedExpr(a)) - { return p; } -} - -ParsedPattern EmptyExpr(Annotations a) : -{ - Token t; -} -{ - t = "empty" - { return sb.makeEmpty(makeLocation(t), a); } -} - -ParsedPattern TextExpr(Annotations a) : -{ - Token t; -} -{ - t = "text" - { return sb.makeText(makeLocation(t), a); } -} - -ParsedPattern NotAllowedExpr(Annotations a) : -{ - Token t; -} -{ - t = "notAllowed" - { return sb.makeNotAllowed(makeLocation(t), a); } -} - -ParsedPattern Expr(boolean topLevel, Scope scope, Token t, Annotations a) : -{ - List patterns = new ArrayList(); - ParsedPattern p; - boolean[] hadOccur = new boolean[1]; - Token[] except = new Token[1]; -} -{ - p = UnaryExpr(topLevel, scope, hadOccur, except) - { patterns.add(p); } - ( - { checkExcept(except); } - (t = "|" p = UnaryExpr(topLevel, scope, null, except) - { patterns.add(p); checkExcept(except); } )+ - { p = sb.makeChoice(patterns, makeLocation(t), a); } - | (t = "&" p = UnaryExpr(topLevel, scope, null, except) - { patterns.add(p); checkExcept(except); } )+ - { p = sb.makeInterleave(patterns, makeLocation(t), a); } - | (t = "," p = UnaryExpr(topLevel, scope, null, except) - { patterns.add(p); checkExcept(except); } )+ - { p = sb.makeGroup(patterns, makeLocation(t), a); } - )? - { - if (patterns.size() == 1 && a != null) { - if (hadOccur[0]) - p = sb.annotate(p, a); - else - p = sb.makeGroup(patterns, makeLocation(t), a); - } - return p; - } -} - -ParsedPattern UnaryExpr(boolean topLevel, Scope scope, boolean[] hadOccur, Token[] except) : -{ - ParsedPattern p; - Token t; - ParsedElementAnnotation e; -} -{ - p = AnnotatedPrimaryExpr(topLevel, scope, except) - ( - { - if (hadOccur != null) hadOccur[0] = true; - p = afterComments(p); - } - (t = "+" { checkExcept(except); p = sb.makeOneOrMore(p, makeLocation(t), null); } - | t = "?" { checkExcept(except); p = sb.makeOptional(p, makeLocation(t), null); } - | t = "*" { checkExcept(except); p = sb.makeZeroOrMore(p, makeLocation(t), null); }) - ( t = e = AnnotationElement(false) { - if (topLevel) - error("top_level_follow_annotation", t); - else - p = sb.annotateAfter(p, e); - } )* - )? - { return p; } -} - -ParsedPattern ElementExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedNameClass nc; - ParsedPattern p; -} -{ - t = "element" - nc = NameClass(IN_ELEMENT, null) - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeElement(nc, p, makeLocation(t), a); } -} - -ParsedPattern AttributeExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedNameClass nc; - ParsedPattern p; -} -{ - t = "attribute" - nc = NameClass(IN_ATTRIBUTE, null) - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeAttribute(nc, p, makeLocation(t), a); } -} - -ParsedNameClass NameClass(int context, Annotations[] pa) : -{ - Annotations a; - ParsedNameClass nc; -} -{ - a = Annotations() - (nc = PrimaryNameClass(context, a) nc = AnnotateAfter(nc) nc = NameClassAlternatives(context, nc, pa) - | nc = AnyNameExceptClass(context, a, pa) - | nc = NsNameExceptClass(context, a, pa)) - { return nc; } -} - -ParsedNameClass AnnotateAfter(ParsedNameClass nc) : -{ - ParsedElementAnnotation e; -} -{ - ( e = AnnotationElement(false) { nc = ncb.annotateAfter(nc, e); })* - { return nc; } -} - -ParsedNameClass NameClassAlternatives(int context, ParsedNameClass nc, Annotations[] pa) : -{ - Token t; - ParsedNameClass[] nameClasses; - int nNameClasses; -} -{ - ( - { - nameClasses = new ParsedNameClass[2]; - nameClasses[0] = nc; - nNameClasses = 1; - } - (t = "|" nc = BasicNameClass(context) nc = AnnotateAfter(nc) - { - if (nNameClasses >= nameClasses.length) { - ParsedNameClass[] oldNameClasses = nameClasses; - nameClasses = new ParsedNameClass[oldNameClasses.length*2]; - System.arraycopy(oldNameClasses, 0, nameClasses, 0, oldNameClasses.length); - } - nameClasses[nNameClasses++] = nc; - })+ - { - Annotations a; - if (pa == null) - a = null; - else { - a = pa[0]; - pa[0] = null; - } - nc = ncb.makeChoice(Arrays.asList(nameClasses).subList(0,nNameClasses), makeLocation(t), a); - } - )? - { return nc; } -} - -ParsedNameClass BasicNameClass(int context) : -{ - Annotations a; - ParsedNameClass nc; -} -{ - a = Annotations() - (nc = PrimaryNameClass(context, a) - | nc = OpenNameClass(context, a)) - { return nc; } -} - -ParsedNameClass PrimaryNameClass(int context, Annotations a) : -{ - ParsedNameClass nc; -} -{ - (nc = UnprefixedNameClass(context, a) - | nc = PrefixedNameClass(a) - | nc = ParenNameClass(context, a)) - { return nc; } -} - -ParsedNameClass OpenNameClass(int context, Annotations a) : -{ - Token t; - LocatedString ns; -} -{ - ns = NsName() { checkNsName(context, ns); return ncb.makeNsName(ns.getString(), ns.getLocation(), a); } - | t = "*" { checkAnyName(context, t); return ncb.makeAnyName(makeLocation(t), a); } -} - - -ParsedNameClass UnprefixedNameClass(int context, Annotations a) : -{ - LocatedString name; -} -{ - name = UnprefixedName() - { - String ns; - if ((context & (IN_ATTRIBUTE|IN_ELEMENT)) == IN_ATTRIBUTE) - ns = ""; - else - ns = defaultNamespace; - return ncb.makeName(ns, name.getString(), null, name.getLocation(), a); - } -} - -ParsedNameClass PrefixedNameClass(Annotations a) : -{ - Token t; -} -{ - t = - { - String qn = t.image; - int colon = qn.indexOf(':'); - String prefix = qn.substring(0, colon); - return ncb.makeName(lookupPrefix(prefix, t), qn.substring(colon + 1), prefix, makeLocation(t), a); - } -} - -ParsedNameClass NsNameExceptClass(int context, Annotations a, Annotations[] pa) : -{ - LocatedString ns; - ParsedNameClass nc; -} -{ - ns = NsName() - { checkNsName(context, ns); } - (nc = ExceptNameClass(context | IN_NS_NAME) - { nc = ncb.makeNsName(ns.getString(), nc, ns.getLocation(), a); } - nc = AnnotateAfter(nc) - | { nc = ncb.makeNsName(ns.getString(), ns.getLocation(), a); } - nc = AnnotateAfter(nc) - nc = NameClassAlternatives(context, nc, pa)) - { return nc; } -} - -LocatedString NsName() : -{ - Token t; -} -{ - t = - { - String qn = t.image; - String prefix = qn.substring(0, qn.length() - 2); - return new LocatedString(lookupPrefix(prefix, t), t); - } -} - -ParsedNameClass AnyNameExceptClass(int context, Annotations a, Annotations[] pa) : -{ - Token t; - ParsedNameClass nc; -} -{ - t = "*" - { checkAnyName(context, t); } - (nc = ExceptNameClass(context | IN_ANY_NAME) - { nc = ncb.makeAnyName(nc, makeLocation(t), a); } - nc = AnnotateAfter(nc) - | { nc = ncb.makeAnyName(makeLocation(t), a); } - nc = AnnotateAfter(nc) - nc = NameClassAlternatives(context, nc, pa)) - { return nc; } -} - -ParsedNameClass ParenNameClass(int context, Annotations a) : -{ - Token t; - ParsedNameClass nc; - Annotations[] pa = new Annotations[]{ a }; -} -{ - t = "(" nc = NameClass(context, pa) { nc = afterComments(nc); } ")" - { - if (pa[0] != null) - nc = ncb.makeChoice(Collections.singletonList(nc), makeLocation(t), pa[0]); - return nc; - } -} - -ParsedNameClass ExceptNameClass(int context) : -{ - ParsedNameClass nc; -} -{ - "-" nc = BasicNameClass(context) - { return nc; } -} - -ParsedPattern ListExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedPattern p; -} -{ - t = "list" - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeList(p, makeLocation(t), a); } -} - -ParsedPattern MixedExpr(Scope scope, Annotations a) : -{ - Token t; - ParsedPattern p; -} -{ - t = "mixed" - "{" - p = Expr(false, scope, null, null) - { p = afterComments(p); } - "}" - { return sb.makeMixed(p, makeLocation(t), a); } -} - -ParsedPattern GrammarExpr(Scope scope, Annotations a) : -{ - Token t; - Grammar g; -} -{ - t = "grammar" { g = sb.makeGrammar(scope); } - "{" a = GrammarBody(g, g, a) { topLevelComments(g); } "}" - { return g.endGrammar(makeLocation(t), a); } -} - -ParsedPattern ParenExpr(boolean topLevel, Scope scope, Annotations a) : -{ - Token t; - ParsedPattern p; -} -{ - t = "(" p = Expr(topLevel, scope, t, a) { p = afterComments(p); } ")" - { return p; } -} - -Annotations GrammarBody(GrammarSection section, Scope scope, Annotations a) : -{ - ParsedElementAnnotation e; -} -{ - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() - { if (a == null) a = sb.makeAnnotations(null, getContext()); a.addElement(e); })* - (GrammarComponent(section, scope))* - { return a; } -} - -void GrammarComponent(GrammarSection section, Scope scope) : -{ - ParsedElementAnnotation e; - Annotations a; -} -{ - (a = Annotations() - (Definition(section, scope, a) - | Include(section, scope, a) - | Div(section, scope, a))) - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() { section.topLevelAnnotation(e); })* -} - -void Definition(GrammarSection section, Scope scope, Annotations a) : -{} -{ - (Define(section, scope, a) | Start(section, scope, a)) -} - -void Start(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - GrammarSection.Combine combine; - ParsedPattern p; -} -{ - t = "start" combine = AssignOp() p = Expr(false, scope, null, null) - { section.define(GrammarSection.START, combine, p, makeLocation(t), a); } -} - -void Define(GrammarSection section, Scope scope, Annotations a) : -{ - LocatedString name; - GrammarSection.Combine combine; - ParsedPattern p; -} -{ - name = Identifier() combine = AssignOp() p = Expr(false, scope, null, null) - { section.define(name.getString(), combine, p, name.getLocation(), a); } -} - -GrammarSection.Combine AssignOp() : -{} -{ - "=" { return null; } - | "|=" { return GrammarSection.COMBINE_CHOICE; } - | "&=" { return GrammarSection.COMBINE_INTERLEAVE; } -} - -void Include(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - String href; - String ns; - Include include = section.makeInclude(); -} -{ - t = "include" href = Literal() - ns = Inherit() - ("{" a = IncludeBody(include, scope, a) { topLevelComments(include); } "}")? - { - try { - include.endInclude(parseable, resolve(href), ns, makeLocation(t), a); - } - catch (IllegalSchemaException e) { } - } -} - -Annotations IncludeBody(GrammarSection section, Scope scope, Annotations a) : -{ - ParsedElementAnnotation e; -} -{ - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() - { if (a == null) a = sb.makeAnnotations(null, getContext()); a.addElement(e); })* - (IncludeComponent(section, scope))* - { return a; } -} - - -void IncludeComponent(GrammarSection section, Scope scope) : -{ - ParsedElementAnnotation e; - Annotations a; -} -{ - (a = Annotations() (Definition(section, scope, a) - | IncludeDiv(section, scope, a))) - (LOOKAHEAD(2) e = AnnotationElementNotKeyword() { section.topLevelAnnotation(e); })* -} - -void Div(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - Div div = section.makeDiv(); -} -{ - t = "div" "{" a = GrammarBody(div, scope, a) { topLevelComments(div); } "}" - { div.endDiv(makeLocation(t), a); } -} - -void IncludeDiv(GrammarSection section, Scope scope, Annotations a) : -{ - Token t; - Div div = section.makeDiv(); -} -{ - t = "div" "{" a = IncludeBody(div, scope, a) { topLevelComments(div); } "}" - { div.endDiv(makeLocation(t), a); } -} - -ParsedPattern ExternalRefExpr(Scope scope, Annotations a) : -{ - Token t; - String href; - String ns; -} -{ - t = "external" href = Literal() - ns = Inherit() - { - try { - return sb.makeExternalRef(parseable, resolve(href), ns, scope, makeLocation(t), a); - } - catch (IllegalSchemaException e) { - return sb.makeErrorPattern(); - } - } -} - -String Inherit() : -{ - String ns = null; -} -{ - ("inherit" "=" ns = Prefix())? - { - if (ns == null) - ns = defaultNamespace; - return ns; - } -} - -ParsedPattern ParentExpr(Scope scope, Annotations a) : -{ - LocatedString name; -} -{ - "parent" { a = addCommentsToChildAnnotations(a); } name = Identifier() - { - if(scope==null) { - error("parent_ref_outside_grammar",name.getToken()); - return sb.makeErrorPattern(); - } else { - return scope.makeParentRef(name.getString(), name.getLocation(), a); - } - } -} - -ParsedPattern IdentifierExpr(Scope scope, Annotations a) : -{ - LocatedString name; -} -{ - name = Identifier() - { - if(scope==null) { - error("ref_outside_grammar",name.getToken()); - return sb.makeErrorPattern(); - } else { - return scope.makeRef(name.getString(), name.getLocation(), a); - } - } -} - -ParsedPattern ValueExpr(boolean topLevel, Annotations a) : -{ - LocatedString s; -} -{ - s = LocatedLiteral() - { - if (topLevel && annotationsIncludeElements) { - error("top_level_follow_annotation", s.getToken()); - a = null; - } - return sb.makeValue("", "token", s.getString(), getContext(), defaultNamespace, s.getLocation(), a); - } -} - -ParsedPattern DataExpr(boolean topLevel, Scope scope, Annotations a, Token[] except) : -{ - Token datatypeToken; - Location loc; - String datatype; - String datatypeUri = null; - String s = null; - ParsedPattern e = null; - DataPatternBuilder dpb; -} -{ - datatypeToken = DatatypeName() - { - datatype = datatypeToken.image; - loc = makeLocation(datatypeToken); - int colon = datatype.indexOf(':'); - if (colon < 0) - datatypeUri = ""; - else { - String prefix = datatype.substring(0, colon); - datatypeUri = lookupDatatype(prefix, datatypeToken); - datatype = datatype.substring(colon + 1); - } - } - ((s = Literal() - { - if (topLevel && annotationsIncludeElements) { - error("top_level_follow_annotation", datatypeToken); - a = null; - } - return sb.makeValue(datatypeUri, datatype, s, getContext(), defaultNamespace, loc, a); - } - ) - | ( { dpb = sb.makeDataPatternBuilder(datatypeUri, datatype, loc); } - ( (Params(dpb) (e = Except(scope, except))?) - | (e = Except(scope, except))?) - { return e == null ? dpb.makePattern(loc, a) : dpb.makePattern(e, loc, a); })) -} - -Token DatatypeName() : -{ - Token t; -} -{ - (t = "string" | t = "token" | t = ) - { return t; } -} - -LocatedString Identifier() : -{ - LocatedString s; - Token t; -} -{ - (t = { s = new LocatedString(t.image, t); } - | t = { s = new LocatedString(t.image.substring(1), t); }) - { return s; } -} - -String Prefix() : -{ - Token t; - String prefix; -} -{ - (t = { prefix = t.image; } - | t = { prefix = t.image.substring(1); } - | t = Keyword() { prefix = t.image; }) - { return lookupPrefix(prefix, t); } -} - -LocatedString UnprefixedName() : -{ - LocatedString s; - Token t; -} -{ - (s = Identifier() - | t = Keyword() { s = new LocatedString(t.image, t); }) - { return s; } -} - -void Params(DataPatternBuilder dpb) : -{} -{ - "{" (Param(dpb))* "}" -} - -void Param(DataPatternBuilder dpb) : -{ - LocatedString name; - Annotations a; - String value; -} -{ - a = Annotations() name = UnprefixedName() "=" { a = addCommentsToLeadingAnnotations(a); } value = Literal() - { dpb.addParam(name.getString(), value, getContext(), defaultNamespace, name.getLocation(), a); } -} - -ParsedPattern Except(Scope scope, Token[] except) : -{ - Annotations a; - ParsedPattern p; - Token t; - Token[] innerExcept = new Token[1]; -} -{ - t = "-" a = Annotations() p = PrimaryExpr(false, scope, a, innerExcept) - { - checkExcept(innerExcept); - except[0] = t; - return p; - } -} - -ParsedElementAnnotation Documentation() : -{ - CommentList comments = getComments(); - ElementAnnotationBuilder eab; - Token t; -} -{ - (t = | t = ) - { - eab = sb.makeElementAnnotationBuilder(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_ANNOTATIONS, - "documentation", - getCompatibilityPrefix(), - makeLocation(t), - comments, - getContext()); - eab.addText(mungeComment(t.image), makeLocation(t), null); - } - (t = { eab.addText("\n" + mungeComment(t.image), makeLocation(t), null); })* - { return eab.makeElementAnnotation(); } -} - -Annotations Annotations() : -{ - CommentList comments = getComments(); - Annotations a = null; - ParsedElementAnnotation e; -} -{ - ( { a = sb.makeAnnotations(comments, getContext()); } - (e = Documentation() { a.addElement(e); })+ - { - comments = getComments(); - if (comments != null) - a.addLeadingComment(comments); - } - )? - ("[" { if (a == null) a = sb.makeAnnotations(comments, getContext()); clearAttributeList(); annotationsIncludeElements = false; } - (LOOKAHEAD(2) PrefixedAnnotationAttribute(a, false) )* - ( e = AnnotationElement(false) { a.addElement(e); annotationsIncludeElements = true; } )* - { a.addComment(getComments()); } - "]")? - { - if (a == null && comments != null) - a = sb.makeAnnotations(comments, getContext()); - return a; - } -} - -void AnnotationAttribute(Annotations a) : -{} -{ - PrefixedAnnotationAttribute(a, true) | UnprefixedAnnotationAttribute(a) -} - -void PrefixedAnnotationAttribute(Annotations a, boolean nested) : -{ - Token t; - String value; -} -{ - t = "=" value = Literal() - { - String qn = t.image; - int colon = qn.indexOf(':'); - String prefix = qn.substring(0, colon); - String ns = lookupPrefix(prefix, t); - if (ns == this.inheritedNs) - error("inherited_annotation_namespace", t); - else if (ns.length() == 0 && !nested) - error("unqualified_annotation_attribute", t); - else if (ns.equals(WellKnownNamespaces.RELAX_NG) && !nested) - error("relax_ng_namespace", t); - /*else if (ns.length() == 0 - && qn.length() - colon - 1 == 5 - && qn.regionMatches(colon + 1, "xmlns", 0, 5)) - error("xmlns_annotation_attribute", t);*/ - else if (ns.equals(WellKnownNamespaces.XMLNS)) - error("xmlns_annotation_attribute_uri", t); - else { - if (ns.length() == 0) - prefix = null; - addAttribute(a, ns, qn.substring(colon + 1), prefix, value, t); - } - } -} - -void UnprefixedAnnotationAttribute(Annotations a) : -{ - LocatedString name; - String value; -} -{ - name = UnprefixedName() "=" value = Literal() - { - if (name.getString().equals("xmlns")) - error("xmlns_annotation_attribute", name.getToken()); - else - addAttribute(a, "", name.getString(), null, value, name.getToken()); - } -} - -ParsedElementAnnotation AnnotationElement(boolean nested) : -{ - ParsedElementAnnotation a; -} -{ - (a = PrefixedAnnotationElement(nested) - | a = UnprefixedAnnotationElement()) - { return a; } -} - -ParsedElementAnnotation AnnotationElementNotKeyword() : -{ - ParsedElementAnnotation a; -} -{ - (a = PrefixedAnnotationElement(false) - | a = IdentifierAnnotationElement()) - { return a; } -} - -ParsedElementAnnotation PrefixedAnnotationElement(boolean nested) : -{ - CommentList comments = getComments(); - Token t; - ElementAnnotationBuilder eab; -} -{ - t = - { - String qn = t.image; - int colon = qn.indexOf(':'); - String prefix = qn.substring(0, colon); - String ns = lookupPrefix(prefix, t); - if (ns == this.inheritedNs) { - error("inherited_annotation_namespace", t); - ns = ""; - } - else if (!nested && ns.equals(WellKnownNamespaces.RELAX_NG)) { - error("relax_ng_namespace", t); - ns = ""; - } - else { - if (ns.length() == 0) - prefix = null; - } - eab = sb.makeElementAnnotationBuilder(ns, qn.substring(colon + 1), prefix, - makeLocation(t), comments, getContext()); - } - AnnotationElementContent(eab) - { return eab.makeElementAnnotation(); } -} - -ParsedElementAnnotation UnprefixedAnnotationElement() : -{ - CommentList comments = getComments(); - LocatedString name; - ElementAnnotationBuilder eab; -} -{ - name = UnprefixedName() - { - eab = sb.makeElementAnnotationBuilder("", name.getString(), null, - name.getLocation(), comments, getContext()); - } - AnnotationElementContent(eab) - { return eab.makeElementAnnotation(); } -} - -ParsedElementAnnotation IdentifierAnnotationElement() : -{ - CommentList comments = getComments(); - LocatedString name; - ElementAnnotationBuilder eab; -} -{ - name = Identifier() - { - eab = sb.makeElementAnnotationBuilder("", name.getString(), null, - name.getLocation(), comments, getContext()); - } - AnnotationElementContent(eab) - { return eab.makeElementAnnotation(); } -} - -void AnnotationElementContent(ElementAnnotationBuilder eab) : -{ - ParsedElementAnnotation e; -} -{ - "[" { clearAttributeList(); } - (LOOKAHEAD(2) AnnotationAttribute(eab))* - ((AnnotationElementLiteral(eab) - ("~" AnnotationElementLiteral(eab))*) - | e = AnnotationElement(true) { eab.addElement(e); })* - { eab.addComment(getComments()); } - "]" -} - -void AnnotationElementLiteral(ElementAnnotationBuilder eab) : -{ - Token t; - CommentList comments = getComments(); -} -{ - t = { eab.addText(unquote(t.image), makeLocation(t), comments); } -} - -String Literal() : -{ - Token t; - String s; - StringBuffer buf; -} -{ - t = - { - s = unquote(t.image); - } - ( - { buf = new StringBuffer(s); } - ("~" t = { buf.append(unquote(t.image)); })+ - { s = buf.toString(); } - )? - { return s; } -} - -LocatedString LocatedLiteral() : -{ - Token t; - Token t2; - String s; - StringBuffer buf; -} -{ - t = - { - s = unquote(t.image); - } - ( - { buf = new StringBuffer(s); } - ("~" t2 = { buf.append(unquote(t2.image)); })+ - { s = buf.toString(); } - )? - { return new LocatedString(s, t); } -} - -Token Keyword() : -{ - Token t; -} -{ - (t = "element" - | t = "attribute" - | t = "namespace" - | t = "list" - | t = "mixed" - | t = "grammar" - | t = "empty" - | t = "text" - | t = "parent" - | t = "external" - | t = "notAllowed" - | t = "start" - | t = "include" - | t = "default" - | t = "inherit" - | t = "string" - | t = "token" - | t = "datatypes" - | t = "div") - { return t; } -} - -<*> -SKIP: { - < #NEWLINE : [ "\u0000", "\n" ] > - | < #NOT_NEWLINE : ~[ "\u0000", "\n" ] > - | < WS: ([ "\u0000", " ", "\n", "\t" ])+ > : DEFAULT -} - -TOKEN : -{ - < DOCUMENTATION: "##" ()* > : AFTER_DOCUMENTATION -} - - -TOKEN : -{ - < DOCUMENTATION_CONTINUE: ([" ", "\t"])* > -} - -SPECIAL_TOKEN: -{ - < SINGLE_LINE_COMMENT: "#" ()* > : AFTER_SINGLE_LINE_COMMENT -} - - -TOKEN : -{ - < DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT: ([" ", "\t"])* > : AFTER_DOCUMENTATION -} - - -SPECIAL_TOKEN : -{ - < SINGLE_LINE_COMMENT_CONTINUE: ([" ", "\t"])* > -} - -TOKEN : -{ - < #BASE_CHAR : [ - "\u0041" - "\u005a", - "\u0061" - "\u007a", - "\u00c0" - "\u00d6", - "\u00d8" - "\u00f6", - "\u00f8" - "\u00ff", - "\u0100" - "\u0131", - "\u0134" - "\u013e", - "\u0141" - "\u0148", - "\u014a" - "\u017e", - "\u0180" - "\u01c3", - "\u01cd" - "\u01f0", - "\u01f4" - "\u01f5", - "\u01fa" - "\u0217", - "\u0250" - "\u02a8", - "\u02bb" - "\u02c1", - "\u0386", - "\u0388" - "\u038a", - "\u038c", - "\u038e" - "\u03a1", - "\u03a3" - "\u03ce", - "\u03d0" - "\u03d6", - "\u03da", - "\u03dc", - "\u03de", - "\u03e0", - "\u03e2" - "\u03f3", - "\u0401" - "\u040c", - "\u040e" - "\u044f", - "\u0451" - "\u045c", - "\u045e" - "\u0481", - "\u0490" - "\u04c4", - "\u04c7" - "\u04c8", - "\u04cb" - "\u04cc", - "\u04d0" - "\u04eb", - "\u04ee" - "\u04f5", - "\u04f8" - "\u04f9", - "\u0531" - "\u0556", - "\u0559", - "\u0561" - "\u0586", - "\u05d0" - "\u05ea", - "\u05f0" - "\u05f2", - "\u0621" - "\u063a", - "\u0641" - "\u064a", - "\u0671" - "\u06b7", - "\u06ba" - "\u06be", - "\u06c0" - "\u06ce", - "\u06d0" - "\u06d3", - "\u06d5", - "\u06e5" - "\u06e6", - "\u0905" - "\u0939", - "\u093d", - "\u0958" - "\u0961", - "\u0985" - "\u098c", - "\u098f" - "\u0990", - "\u0993" - "\u09a8", - "\u09aa" - "\u09b0", - "\u09b2", - "\u09b6" - "\u09b9", - "\u09dc" - "\u09dd", - "\u09df" - "\u09e1", - "\u09f0" - "\u09f1", - "\u0a05" - "\u0a0a", - "\u0a0f" - "\u0a10", - "\u0a13" - "\u0a28", - "\u0a2a" - "\u0a30", - "\u0a32" - "\u0a33", - "\u0a35" - "\u0a36", - "\u0a38" - "\u0a39", - "\u0a59" - "\u0a5c", - "\u0a5e", - "\u0a72" - "\u0a74", - "\u0a85" - "\u0a8b", - "\u0a8d", - "\u0a8f" - "\u0a91", - "\u0a93" - "\u0aa8", - "\u0aaa" - "\u0ab0", - "\u0ab2" - "\u0ab3", - "\u0ab5" - "\u0ab9", - "\u0abd", - "\u0ae0", - "\u0b05" - "\u0b0c", - "\u0b0f" - "\u0b10", - "\u0b13" - "\u0b28", - "\u0b2a" - "\u0b30", - "\u0b32" - "\u0b33", - "\u0b36" - "\u0b39", - "\u0b3d", - "\u0b5c" - "\u0b5d", - "\u0b5f" - "\u0b61", - "\u0b85" - "\u0b8a", - "\u0b8e" - "\u0b90", - "\u0b92" - "\u0b95", - "\u0b99" - "\u0b9a", - "\u0b9c", - "\u0b9e" - "\u0b9f", - "\u0ba3" - "\u0ba4", - "\u0ba8" - "\u0baa", - "\u0bae" - "\u0bb5", - "\u0bb7" - "\u0bb9", - "\u0c05" - "\u0c0c", - "\u0c0e" - "\u0c10", - "\u0c12" - "\u0c28", - "\u0c2a" - "\u0c33", - "\u0c35" - "\u0c39", - "\u0c60" - "\u0c61", - "\u0c85" - "\u0c8c", - "\u0c8e" - "\u0c90", - "\u0c92" - "\u0ca8", - "\u0caa" - "\u0cb3", - "\u0cb5" - "\u0cb9", - "\u0cde", - "\u0ce0" - "\u0ce1", - "\u0d05" - "\u0d0c", - "\u0d0e" - "\u0d10", - "\u0d12" - "\u0d28", - "\u0d2a" - "\u0d39", - "\u0d60" - "\u0d61", - "\u0e01" - "\u0e2e", - "\u0e30", - "\u0e32" - "\u0e33", - "\u0e40" - "\u0e45", - "\u0e81" - "\u0e82", - "\u0e84", - "\u0e87" - "\u0e88", - "\u0e8a", - "\u0e8d", - "\u0e94" - "\u0e97", - "\u0e99" - "\u0e9f", - "\u0ea1" - "\u0ea3", - "\u0ea5", - "\u0ea7", - "\u0eaa" - "\u0eab", - "\u0ead" - "\u0eae", - "\u0eb0", - "\u0eb2" - "\u0eb3", - "\u0ebd", - "\u0ec0" - "\u0ec4", - "\u0f40" - "\u0f47", - "\u0f49" - "\u0f69", - "\u10a0" - "\u10c5", - "\u10d0" - "\u10f6", - "\u1100", - "\u1102" - "\u1103", - "\u1105" - "\u1107", - "\u1109", - "\u110b" - "\u110c", - "\u110e" - "\u1112", - "\u113c", - "\u113e", - "\u1140", - "\u114c", - "\u114e", - "\u1150", - "\u1154" - "\u1155", - "\u1159", - "\u115f" - "\u1161", - "\u1163", - "\u1165", - "\u1167", - "\u1169", - "\u116d" - "\u116e", - "\u1172" - "\u1173", - "\u1175", - "\u119e", - "\u11a8", - "\u11ab", - "\u11ae" - "\u11af", - "\u11b7" - "\u11b8", - "\u11ba", - "\u11bc" - "\u11c2", - "\u11eb", - "\u11f0", - "\u11f9", - "\u1e00" - "\u1e9b", - "\u1ea0" - "\u1ef9", - "\u1f00" - "\u1f15", - "\u1f18" - "\u1f1d", - "\u1f20" - "\u1f45", - "\u1f48" - "\u1f4d", - "\u1f50" - "\u1f57", - "\u1f59", - "\u1f5b", - "\u1f5d", - "\u1f5f" - "\u1f7d", - "\u1f80" - "\u1fb4", - "\u1fb6" - "\u1fbc", - "\u1fbe", - "\u1fc2" - "\u1fc4", - "\u1fc6" - "\u1fcc", - "\u1fd0" - "\u1fd3", - "\u1fd6" - "\u1fdb", - "\u1fe0" - "\u1fec", - "\u1ff2" - "\u1ff4", - "\u1ff6" - "\u1ffc", - "\u2126", - "\u212a" - "\u212b", - "\u212e", - "\u2180" - "\u2182", - "\u3041" - "\u3094", - "\u30a1" - "\u30fa", - "\u3105" - "\u312c", - "\uac00" - "\ud7a3" - ] > - | < #IDEOGRAPHIC : [ - "\u4e00" - "\u9fa5", - "\u3007", - "\u3021" - "\u3029" - ] > - | < #LETTER : ( | ) > - | < #COMBINING_CHAR : [ - "\u0300" - "\u0345", - "\u0360" - "\u0361", - "\u0483" - "\u0486", - "\u0591" - "\u05a1", - "\u05a3" - "\u05b9", - "\u05bb" - "\u05bd", - "\u05bf", - "\u05c1" - "\u05c2", - "\u05c4", - "\u064b" - "\u0652", - "\u0670", - "\u06d6" - "\u06dc", - "\u06dd" - "\u06df", - "\u06e0" - "\u06e4", - "\u06e7" - "\u06e8", - "\u06ea" - "\u06ed", - "\u0901" - "\u0903", - "\u093c", - "\u093e" - "\u094c", - "\u094d", - "\u0951" - "\u0954", - "\u0962" - "\u0963", - "\u0981" - "\u0983", - "\u09bc", - "\u09be", - "\u09bf", - "\u09c0" - "\u09c4", - "\u09c7" - "\u09c8", - "\u09cb" - "\u09cd", - "\u09d7", - "\u09e2" - "\u09e3", - "\u0a02", - "\u0a3c", - "\u0a3e", - "\u0a3f", - "\u0a40" - "\u0a42", - "\u0a47" - "\u0a48", - "\u0a4b" - "\u0a4d", - "\u0a70" - "\u0a71", - "\u0a81" - "\u0a83", - "\u0abc", - "\u0abe" - "\u0ac5", - "\u0ac7" - "\u0ac9", - "\u0acb" - "\u0acd", - "\u0b01" - "\u0b03", - "\u0b3c", - "\u0b3e" - "\u0b43", - "\u0b47" - "\u0b48", - "\u0b4b" - "\u0b4d", - "\u0b56" - "\u0b57", - "\u0b82" - "\u0b83", - "\u0bbe" - "\u0bc2", - "\u0bc6" - "\u0bc8", - "\u0bca" - "\u0bcd", - "\u0bd7", - "\u0c01" - "\u0c03", - "\u0c3e" - "\u0c44", - "\u0c46" - "\u0c48", - "\u0c4a" - "\u0c4d", - "\u0c55" - "\u0c56", - "\u0c82" - "\u0c83", - "\u0cbe" - "\u0cc4", - "\u0cc6" - "\u0cc8", - "\u0cca" - "\u0ccd", - "\u0cd5" - "\u0cd6", - "\u0d02" - "\u0d03", - "\u0d3e" - "\u0d43", - "\u0d46" - "\u0d48", - "\u0d4a" - "\u0d4d", - "\u0d57", - "\u0e31", - "\u0e34" - "\u0e3a", - "\u0e47" - "\u0e4e", - "\u0eb1", - "\u0eb4" - "\u0eb9", - "\u0ebb" - "\u0ebc", - "\u0ec8" - "\u0ecd", - "\u0f18" - "\u0f19", - "\u0f35", - "\u0f37", - "\u0f39", - "\u0f3e", - "\u0f3f", - "\u0f71" - "\u0f84", - "\u0f86" - "\u0f8b", - "\u0f90" - "\u0f95", - "\u0f97", - "\u0f99" - "\u0fad", - "\u0fb1" - "\u0fb7", - "\u0fb9", - "\u20d0" - "\u20dc", - "\u20e1", - "\u302a" - "\u302f", - "\u3099", - "\u309a" - ] > - | < #DIGIT : [ - "\u0030" - "\u0039", - "\u0660" - "\u0669", - "\u06f0" - "\u06f9", - "\u0966" - "\u096f", - "\u09e6" - "\u09ef", - "\u0a66" - "\u0a6f", - "\u0ae6" - "\u0aef", - "\u0b66" - "\u0b6f", - "\u0be7" - "\u0bef", - "\u0c66" - "\u0c6f", - "\u0ce6" - "\u0cef", - "\u0d66" - "\u0d6f", - "\u0e50" - "\u0e59", - "\u0ed0" - "\u0ed9", - "\u0f20" - "\u0f29" - ] > - | < #EXTENDER : [ - "\u00b7", - "\u02d0", - "\u02d1", - "\u0387", - "\u0640", - "\u0e46", - "\u0ec6", - "\u3005", - "\u3031" - "\u3035", - "\u309d" - "\u309e", - "\u30fc" - "\u30fe" - ] > - | < #NMSTART : ( | "_") > - | < #NMCHAR : ( | | | | "." | "-" | "_") > - | < #NCNAME: ()* > -} - -TOKEN : -{ - < IDENTIFIER: > - | < ESCAPED_IDENTIFIER: "\\" > - | < PREFIX_STAR: ":*" > - | < PREFIXED_NAME: ":" > - | < LITERAL : ("\"" (~["\u0000", "\""])* "\"") - | ("'" (~["\u0000", "'"])* "'") - | ("\"\"\"" (~["\""] - | ("\"" ~["\""]) - | ("\"\"" ~["\""]))* "\"\"\"") - | ("'''" (~["'"] - | ("'" ~["'"]) - | ("''" ~["'"]))* "'''") > - | < FANNOTATE : ">>" > -} - -/* This avoids lexical errors from JavaCC. */ -<*> -TOKEN : -{ - < ILLEGAL_CHAR : [ "\u0000" - "\u0008", "\u000b" - "\uffff" ] > -} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/pacakge-info.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/package-info.java similarity index 95% rename from jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/pacakge-info.java rename to jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/package-info.java index c64df853e20..e3fff6d0645 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/pacakge-info.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java index 73cd2c46cd5..8600d0184a7 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/DefaultResourceInjector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ import javax.xml.ws.WebServiceContext; */ public final class DefaultResourceInjector extends ResourceInjector { public void inject(@NotNull WSWebServiceContext context, @NotNull Object instance) { - InjectionPlan.buildInjectionPlan( + InjectionPlan.buildInjectionPlan( instance.getClass(),WebServiceContext.class,false).inject(instance,context); } diff --git a/jdk/.hgtags b/jdk/.hgtags index fdf62aef521..1d0fd47c313 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -257,3 +257,5 @@ ab06ba2894313a47e4969ca37792ff119c49e711 jdk9-b10 83d9bc20973de232cae45b139fdff8a4549c130f jdk9-b12 c7c8002d02721e02131d104549ebeb8b379fb8d2 jdk9-b13 5c7a17a81afd0906b53ee31d95a3211c96ff6b25 jdk9-b14 +4537360f09fe23ab339ee588747b657feb12d0c8 jdk9-b15 +ab7d2c565b0de5bee1361d282d4029371327fc9e jdk9-b16 diff --git a/jdk/make/Bundles.gmk b/jdk/make/Bundles.gmk index 15538f0a11a..f6139ab6932 100644 --- a/jdk/make/Bundles.gmk +++ b/jdk/make/Bundles.gmk @@ -74,19 +74,16 @@ ifeq ($(OPENJDK_TARGET_OS), macosx) JDK_TARGET_LIST := $(subst $(JDK_IMAGE_DIR)/,$(JDK_BUNDLE_DIR)/Home/,$(JDK_FILE_LIST)) JRE_TARGET_LIST := $(subst $(JRE_IMAGE_DIR)/,$(JRE_BUNDLE_DIR)/Home/,$(JRE_FILE_LIST)) - # The old builds implementation of this did not preserve symlinks so - # make sure they are followed and the contents copied instead. - # To fix this, remove -L # Copy empty directories (jre/lib/applet). $(JDK_BUNDLE_DIR)/Home/%: $(JDK_IMAGE_DIR)/% $(ECHO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(MKDIR) -p $(@D) - if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -L '$<' '$@'; fi + if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -P '$<' '$@'; fi $(JRE_BUNDLE_DIR)/Home/%: $(JRE_IMAGE_DIR)/% $(ECHO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(MKDIR) -p $(@D) - if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -L '$<' '$@'; fi + if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -P '$<' '$@'; fi $(JDK_BUNDLE_DIR)/MacOS/libjli.dylib: $(ECHO) Creating link $(patsubst $(OUTPUT_ROOT)/%,%,$@) diff --git a/jdk/make/CompileJavaClasses.gmk b/jdk/make/CompileJavaClasses.gmk index 6d2acb6708f..67e8b6d4812 100644 --- a/jdk/make/CompileJavaClasses.gmk +++ b/jdk/make/CompileJavaClasses.gmk @@ -373,7 +373,7 @@ ifndef OPENJDK JAVAC_FLAGS := -cp $(JDK_OUTPUTDIR)/classes, \ SRC := $(JDK_OUTPUTDIR)/gensrc_ab/32bit, \ BIN := $(JDK_OUTPUTDIR)/classes_ab/32bit, \ - HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers)) + HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers_ab/32)) $(BUILD_ACCESSBRIDGE_32): $(BUILD_JDK) @@ -382,7 +382,7 @@ ifndef OPENJDK JAVAC_FLAGS := -cp $(JDK_OUTPUTDIR)/classes, \ SRC := $(JDK_OUTPUTDIR)/gensrc_ab/legacy, \ BIN := $(JDK_OUTPUTDIR)/classes_ab/legacy, \ - HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers)) + HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers_ab/legacy)) $(BUILD_ACCESSBRIDGE_LEGACY): $(BUILD_JDK) @@ -393,7 +393,7 @@ ifndef OPENJDK JAVAC_FLAGS := -cp $(JDK_OUTPUTDIR)/classes, \ SRC := $(JDK_OUTPUTDIR)/gensrc_ab/64bit, \ BIN := $(JDK_OUTPUTDIR)/classes_ab/64bit, \ - HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers)) + HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers_ab/64)) $(BUILD_ACCESSBRIDGE_64): $(BUILD_JDK) diff --git a/jdk/make/CompileLaunchers.gmk b/jdk/make/CompileLaunchers.gmk index 68786a0a5b3..bb995d8a6ab 100644 --- a/jdk/make/CompileLaunchers.gmk +++ b/jdk/make/CompileLaunchers.gmk @@ -428,7 +428,7 @@ ifeq ($(USE_EXTERNAL_LIBZ), true) UNPACKEXE_CFLAGS := -DSYSTEM_ZLIB UNPACKEXE_ZIPOBJS := -lz else - UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 + UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.8 UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \ $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \ $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \ @@ -442,11 +442,6 @@ else endif -ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) - UNPACKEXE_CFLAGS += -xregs=no%appl - UNPACKEXE_LDFLAGS_solaris += -xmemalign=4s -endif - UNPACKEXE_LANG := C ifeq ($(OPENJDK_TARGET_OS), solaris) UNPACKEXE_LANG := C++ diff --git a/jdk/make/CopyIntoClasses.gmk b/jdk/make/CopyIntoClasses.gmk index b3a216fb90e..fdf2a173aca 100644 --- a/jdk/make/CopyIntoClasses.gmk +++ b/jdk/make/CopyIntoClasses.gmk @@ -30,7 +30,6 @@ COPY_PATTERNS := .icu _dict .dat _options .js aliasmap .spp .wav .css \ # These directories should not be copied at all EXCLUDES += \ - com/sun/org/apache/xml/internal/security/resource/schema \ java/awt/doc-files \ java/lang/doc-files \ javax/swing/doc-files \ diff --git a/jdk/make/CreateJars.gmk b/jdk/make/CreateJars.gmk index eebdcf666f0..9d79394539c 100644 --- a/jdk/make/CreateJars.gmk +++ b/jdk/make/CreateJars.gmk @@ -552,40 +552,53 @@ $(eval $(call SetupArchive,BUILD_CT_SYM, $(IMAGES_OUTPUTDIR)/symbols/_the.symbol ########################################################################################## -SRC_ZIP_INCLUDES = \ - com/sun/corba \ - com/sun/image/codec/jpeg \ - com/sun/imageio \ - com/sun/java_cup \ - com/sun/javadoc \ - com/sun/java/swing \ - com/sun/jmx \ - com/sun/naming \ - com/sun/org/apache \ - com/sun/security/auth \ - com/sun/security/jgss \ - com/sun/source \ - java \ - javax/accessibility \ - javax/annotation \ - javax/imageio \ - javax/lang \ - javax/management \ - javax/naming \ - javax/print \ - javax/rmi \ - javax/script \ - javax/security \ - javax/sound \ - javax/sql \ - javax/swing \ - javax/tools \ - javax/xml \ - org/ietf \ - org/omg \ - org/w3c/dom \ - org/xml/sax \ - # +ifdef OPENJDK + SRC_ZIP_INCLUDES = \ + com \ + java \ + javax \ + jdk \ + org \ + sun \ + # + SRC_ZIP_EXCLUDES = +else + SRC_ZIP_INCLUDES = \ + com/sun/corba \ + com/sun/image/codec/jpeg \ + com/sun/imageio \ + com/sun/java_cup \ + com/sun/javadoc \ + com/sun/java/swing \ + com/sun/jmx \ + com/sun/naming \ + com/sun/org/apache \ + com/sun/security/auth \ + com/sun/security/jgss \ + com/sun/source \ + java \ + javax/accessibility \ + javax/annotation \ + javax/imageio \ + javax/lang \ + javax/management \ + javax/naming \ + javax/print \ + javax/rmi \ + javax/script \ + javax/security \ + javax/sound \ + javax/sql \ + javax/swing \ + javax/tools \ + javax/xml \ + org/ietf \ + org/omg \ + org/w3c/dom \ + org/xml/sax \ + # + SRC_ZIP_EXCLUDES = javax/swing/beaninfo +endif SRC_ZIP_SRCS = $(JDK_TOPDIR)/src/share/classes $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes SRC_ZIP_SRCS += $(JDK_OUTPUTDIR)/gensrc @@ -616,7 +629,7 @@ $(eval $(call MakeDir, $(IMAGES_OUTPUTDIR)/src)) $(eval $(call SetupZipArchive,BUILD_SRC_ZIP, \ SRC := $(SRC_ZIP_SRCS) $(IMAGES_OUTPUTDIR)/src, \ INCLUDES := $(SRC_ZIP_INCLUDES) launcher, \ - EXCLUDES := javax/swing/beaninfo, \ + EXCLUDES := $(SRC_ZIP_EXCLUDES), \ SUFFIXES := .java .c .h, \ ZIP := $(IMAGES_OUTPUTDIR)/src.zip, \ EXTRA_DEPS := $(LAUNCHER_ZIP_SRC))) diff --git a/jdk/make/Setup.gmk b/jdk/make/Setup.gmk index aab0adec464..123a03e2c17 100644 --- a/jdk/make/Setup.gmk +++ b/jdk/make/Setup.gmk @@ -27,7 +27,7 @@ DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,- # To build with all warnings enabled, do the following: # make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000" -JAVAC_WARNINGS := -Xlint:-unchecked,-deprecation,-overrides,auxiliaryclass,cast,classfile,dep-ann,divzero,empty,overloads,serial,static,try,varargs -Werror +JAVAC_WARNINGS := -Xlint:-unchecked,-deprecation,-overrides,auxiliaryclass,cast,classfile,dep-ann,divzero,empty,fallthrough,overloads,serial,static,try,varargs -Werror # Any java code executed during a JDK build to build other parts of the JDK must be # executed by the bootstrap JDK (probably with -Xbootclasspath/p: ) and for this diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index c473784f16e..7dbb9e9e2d9 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -1274,7 +1274,7 @@ ifndef BUILD_HEADLESS_ONLY LIBSPLASHSCREEN_LDFLAGS_SUFFIX := ifneq ($(USE_EXTERNAL_LIBZ), true) - LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 + LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.8 LIBSPLASHSCREEN_CFLAGS += $(ZLIB_CPPFLAGS) endif diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk index 2241d5d8d86..66ef38ec94f 100644 --- a/jdk/make/lib/CoreLibraries.gmk +++ b/jdk/make/lib/CoreLibraries.gmk @@ -231,9 +231,9 @@ $(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM) BUILD_LIBZIP_EXCLUDES := ifeq ($(USE_EXTERNAL_LIBZ), true) LIBZ := -lz - LIBZIP_EXCLUDES += zlib-1.2.5 + LIBZIP_EXCLUDES += zlib-1.2.8 else - ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 + ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.8 endif BUILD_LIBZIP_REORDER := @@ -410,7 +410,7 @@ ifeq ($(OPENJDK_TARGET_OS), macosx) endif ifneq ($(USE_EXTERNAL_LIBZ), true) - BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5 + BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.8 LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS) BUILD_LIBJLI_FILES += \ inflate.c \ diff --git a/jdk/make/lib/PlatformLibraries.gmk b/jdk/make/lib/PlatformLibraries.gmk index 336e4b1b3e4..e78a9833dd5 100644 --- a/jdk/make/lib/PlatformLibraries.gmk +++ b/jdk/make/lib/PlatformLibraries.gmk @@ -143,7 +143,8 @@ ifndef OPENJDK define SetupAccessBridge # Parameter 1 Suffix # Parameter 2 Machine - # Parameter 3 ACCESSBRIDGE_ARCH_ suffix + # Parameter 3 ACCESSBRIDGE_ARCH_ suffix and name of directory where gensrc headers + # are found. $(call SetupNativeCompilation,BUILD_JAWTACCESSBRIDGE$1, \ LIBRARY = JAWTAccessBridge$1, \ @@ -153,7 +154,8 @@ ifndef OPENJDK LANG := C++, \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) \ - -DACCESSBRIDGE_ARCH_$3, \ + -DACCESSBRIDGE_ARCH_$3 \ + -I$(JDK_OUTPUTDIR)/gensrc_headers_ab/$3, \ LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ winspool.lib jawt.lib comdlg32.lib advapi32.lib shell32.lib \ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ @@ -179,7 +181,8 @@ ifndef OPENJDK LANG := C++, \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) \ - -DACCESSBRIDGE_ARCH_$3, \ + -DACCESSBRIDGE_ARCH_$3 \ + -I$(JDK_OUTPUTDIR)/gensrc_headers_ab/$3, \ LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ winspool.lib comdlg32.lib advapi32.lib shell32.lib \ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ @@ -204,7 +207,8 @@ ifndef OPENJDK LANG := C++, \ OPTIMIZATION := LOW, \ CFLAGS := $(filter-out -MD, $(CFLAGS_JDKLIB)) -MT \ - -DACCESSBRIDGE_ARCH_$3, \ + -DACCESSBRIDGE_ARCH_$3 \ + -I$(JDK_OUTPUTDIR)/gensrc_headers_ab/$3, \ LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \ winspool.lib comdlg32.lib advapi32.lib shell32.lib \ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \ @@ -225,7 +229,7 @@ ifndef OPENJDK ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) $(eval $(call SetupAccessBridge,-32,I386,32)) - $(eval $(call SetupAccessBridge,,I386,LEGACY)) + $(eval $(call SetupAccessBridge,,I386,legacy)) else $(eval $(call SetupAccessBridge,-64,X64,64)) endif diff --git a/jdk/make/profile-rtjar-includes.txt b/jdk/make/profile-rtjar-includes.txt index b20031a017e..1e954ad625c 100644 --- a/jdk/make/profile-rtjar-includes.txt +++ b/jdk/make/profile-rtjar-includes.txt @@ -88,7 +88,7 @@ PROFILE_2_RTJAR_INCLUDE_PACKAGES := \ java/sql \ javax/rmi/ssl \ javax/sql \ - javax/transaction \ + javax/transaction/xa \ javax/xml \ org/w3c \ org/xml/sax \ @@ -223,7 +223,8 @@ FULL_JRE_RTJAR_INCLUDE_TYPES := \ javax/management/remote/rmi/_RMIConnection_Stub.class \ javax/management/remote/rmi/_RMIServerImpl_Tie.class \ javax/management/remote/rmi/_RMIServer_Stub.class \ - javax/rmi/*.class + javax/rmi/*.class \ + javax/transaction/*.class FULL_JRE_RTJAR_EXCLUDE_TYPES := diff --git a/jdk/src/aix/native/java/net/aix_close.c b/jdk/src/aix/native/java/net/aix_close.c index 148e05da0c8..0165c9a1959 100644 --- a/jdk/src/aix/native/java/net/aix_close.c +++ b/jdk/src/aix/native/java/net/aix_close.c @@ -370,7 +370,57 @@ int NET_Accept(int s, struct sockaddr *addr, int *addrlen) { } int NET_Connect(int s, struct sockaddr *addr, int addrlen) { - BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) ); + int crc = -1, prc = -1; + threadEntry_t self; + fdEntry_t* fdEntry = getFdEntry(s); + + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* On AIX, when the system call connect() is interrupted, the connection + * is not aborted and it will be established asynchronously by the kernel. + * Hence, no need to restart connect() when EINTR is received + */ + startOp(fdEntry, &self); + crc = connect(s, addr, addrlen); + endOp(fdEntry, &self); + + if (crc == -1 && errno == EINTR) { + struct pollfd s_pollfd; + int sockopt_arg = 0; + socklen_t len; + + s_pollfd.fd = s; + s_pollfd.events = POLLOUT | POLLERR; + + /* poll the file descriptor */ + do { + startOp(fdEntry, &self); + prc = poll(&s_pollfd, 1, -1); + endOp(fdEntry, &self); + } while (prc == -1 && errno == EINTR); + + if (prc < 0) + return prc; + + len = sizeof(sockopt_arg); + + /* Check whether the connection has been established */ + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &sockopt_arg, &len) == -1) + return -1; + + if (sockopt_arg != 0 ) { + errno = sockopt_arg; + return -1; + } + } else { + return crc; + } + + /* At this point, fd is connected. Set successful return code */ + return 0; } int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java b/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java index 57b0e7c3a0c..f8de6b43ff5 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,14 +131,14 @@ public final class DHParameters extends AlgorithmParametersSpi { protected String engineToString() { String LINE_SEP = System.getProperty("line.separator"); - StringBuffer strbuf - = new StringBuffer("SunJCE Diffie-Hellman Parameters:" + StringBuilder sb + = new StringBuilder("SunJCE Diffie-Hellman Parameters:" + LINE_SEP + "p:" + LINE_SEP + Debug.toHexString(this.p) + LINE_SEP + "g:" + LINE_SEP + Debug.toHexString(this.g)); if (this.l != 0) - strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); - return strbuf.toString(); + sb.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); + return sb.toString(); } } diff --git a/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java b/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java index 7293c945768..037589c8d53 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -260,8 +260,8 @@ javax.crypto.interfaces.DHPublicKey, Serializable { public String toString() { String LINE_SEP = System.getProperty("line.separator"); - StringBuffer strbuf - = new StringBuffer("SunJCE Diffie-Hellman Public Key:" + StringBuilder sb + = new StringBuilder("SunJCE Diffie-Hellman Public Key:" + LINE_SEP + "y:" + LINE_SEP + Debug.toHexString(this.y) + LINE_SEP + "p:" + LINE_SEP @@ -269,8 +269,8 @@ javax.crypto.interfaces.DHPublicKey, Serializable { + LINE_SEP + "g:" + LINE_SEP + Debug.toHexString(this.g)); if (this.l != 0) - strbuf.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); - return strbuf.toString(); + sb.append(LINE_SEP + "l:" + LINE_SEP + " " + this.l); + return sb.toString(); } private void parseKeyBits() throws InvalidKeyException { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java index 74b3cc408d9..1ea16cc62e1 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -238,7 +238,7 @@ public final class OAEPParameters extends AlgorithmParametersSpi { } protected String engineToString() { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("MD: " + mdName + "\n"); sb.append("MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n"); sb.append("PSource: PSpecified " + diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java index 4f64ef41b7a..aeb6b7736bb 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java @@ -512,7 +512,7 @@ class ConstantPool { } static String qualifiedStringValue(String s1, String s234) { // Qualification by dot must decompose uniquely. Second string might already be qualified. - assert(s1.indexOf(".") < 0); + assert(s1.indexOf('.') < 0); return s1+"."+s234; } diff --git a/jdk/src/share/classes/com/sun/jndi/cosnaming/CorbanameUrl.java b/jdk/src/share/classes/com/sun/jndi/cosnaming/CorbanameUrl.java index f24f87c947e..6b32bb17aa0 100644 --- a/jdk/src/share/classes/com/sun/jndi/cosnaming/CorbanameUrl.java +++ b/jdk/src/share/classes/com/sun/jndi/cosnaming/CorbanameUrl.java @@ -102,7 +102,7 @@ public final class CorbanameUrl { } location = url.substring(addrStart, addrEnd); - int keyStart = location.indexOf("/"); + int keyStart = location.indexOf('/'); if (keyStart >= 0) { // Has key string if (keyStart == (location.length() -1)) { diff --git a/jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java b/jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java index 2990ed8b549..a6de4af5cd8 100644 --- a/jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java +++ b/jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java @@ -336,7 +336,7 @@ public class RegistryContext implements Context, Referenceable { String url = "rmi://"; // Enclose IPv6 literal address in '[' and ']' - url = (host.indexOf(":") > -1) ? url + "[" + host + "]" : + url = (host.indexOf(':') > -1) ? url + "[" + host + "]" : url + host; if (port > 0) { url += ":" + Integer.toString(port); diff --git a/jdk/src/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java b/jdk/src/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java index 3e90b27bcce..cb5255d0a7b 100644 --- a/jdk/src/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java +++ b/jdk/src/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java @@ -149,7 +149,7 @@ abstract public class GenericURLContext implements Context { * foo:rest/of/name foo: */ protected String getURLPrefix(String url) throws NamingException { - int start = url.indexOf(":"); + int start = url.indexOf(':'); if (start < 0) { throw new OperationNotSupportedException("Invalid URL: " + url); @@ -160,7 +160,7 @@ abstract public class GenericURLContext implements Context { start += 2; // skip double slash // find last slash - int posn = url.indexOf("/", start); + int posn = url.indexOf('/', start); if (posn >= 0) { start = posn; } else { diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd deleted file mode 100644 index d69852ff842..00000000000 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.rng b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.rng deleted file mode 100644 index 895e033a626..00000000000 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.rng +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.xsd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.xsd deleted file mode 100644 index 85af68b5518..00000000000 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.xsd +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - ]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd deleted file mode 100644 index b2cc19f63a1..00000000000 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.rng b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.rng deleted file mode 100644 index 03330fb1fee..00000000000 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.rng +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd deleted file mode 100644 index e8288a526c3..00000000000 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd +++ /dev/null @@ -1,318 +0,0 @@ - - - - - - ]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java b/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java index 616922429b4..28119ef169f 100644 --- a/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java +++ b/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java @@ -303,7 +303,7 @@ public final class ExecOptionPermission extends Permission offset = pname.length() - 1; - while ((last = pname.lastIndexOf(".", offset)) != -1) { + while ((last = pname.lastIndexOf('.', offset)) != -1) { pname = pname.substring(0, last+1) + "*"; x = permissions.get(pname); @@ -318,7 +318,7 @@ public final class ExecOptionPermission extends Permission pname = p.getName(); offset = pname.length() - 1; - while ((last = pname.lastIndexOf("=", offset)) != -1) { + while ((last = pname.lastIndexOf('=', offset)) != -1) { pname = pname.substring(0, last+1) + "*"; x = permissions.get(pname); diff --git a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java index cfb728e9910..2d7cc6bf73c 100644 --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -6831,7 +6831,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern // table name else isolate table name. indexFrom = command.toLowerCase().indexOf("from"); - indexComma = command.indexOf(",", indexFrom); + indexComma = command.indexOf(',', indexFrom); if(indexComma == -1) { // implies only one table diff --git a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java index 46637217d1f..ef281db9b10 100644 --- a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java @@ -910,7 +910,7 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { // now remove the last "," strWhereClause = strWhereClause.substring - (0, strWhereClause.lastIndexOf(",")); + (0, strWhereClause.lastIndexOf(',')); // Add from clause strWhereClause = strWhereClause.concat(" from "); @@ -920,7 +920,7 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { //Remove the last "," strWhereClause = strWhereClause.substring - (0, strWhereClause.lastIndexOf(",")); + (0, strWhereClause.lastIndexOf(',')); // Add the where clause strWhereClause = strWhereClause.concat(" where "); diff --git a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java index 3b04d1c748c..d3c22eaf128 100644 --- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java +++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java @@ -240,7 +240,7 @@ public class WebRowSetXmlWriter implements XmlWriter, Serializable { // Remove the string after "@xxxx" // before writing it to the xml file. String strProviderInstance = (caller.getSyncProvider()).toString(); - String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@")); + String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf('@')); propString("sync-provider-name", strProvider); propString("sync-provider-vendor", "Oracle Corporation"); diff --git a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java index 31d714187aa..45aeecc2341 100644 --- a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java +++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java @@ -1147,7 +1147,7 @@ public class XmlReaderContentHandler extends DefaultHandler { if (nullValue) { rs.setSyncProvider(null); } else { - String str = s.substring(0,s.indexOf("@")+1); + String str = s.substring(0,s.indexOf('@')+1); rs.setSyncProvider(str); } break; diff --git a/jdk/src/share/classes/com/sun/rowset/internal/XmlResolver.java b/jdk/src/share/classes/com/sun/rowset/internal/XmlResolver.java index a51df227d51..a3fa6afc9a2 100644 --- a/jdk/src/share/classes/com/sun/rowset/internal/XmlResolver.java +++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlResolver.java @@ -39,7 +39,7 @@ import org.xml.sax.InputSource; public class XmlResolver implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) { - String schemaName = systemId.substring(systemId.lastIndexOf("/")); + String schemaName = systemId.substring(systemId.lastIndexOf('/')); if(systemId.startsWith("http://java.sun.com/xml/ns/jdbc")) { return new InputSource(this.getClass().getResourceAsStream(schemaName)); diff --git a/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java index 6bce9361380..e287f858804 100644 --- a/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java +++ b/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java @@ -694,7 +694,7 @@ public class JndiLoginModule implements LoginModule { throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user"); - String protocol = userProvider.substring(0, userProvider.indexOf(":")); + String protocol = userProvider.substring(0, userProvider.indexOf(':')); Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback(protocol + " " diff --git a/jdk/src/share/classes/com/sun/security/auth/module/LdapLoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/LdapLoginModule.java index e161b0ee8de..1de82aa98b6 100644 --- a/jdk/src/share/classes/com/sun/security/auth/module/LdapLoginModule.java +++ b/jdk/src/share/classes/com/sun/security/auth/module/LdapLoginModule.java @@ -400,7 +400,7 @@ public class LdapLoginModule implements LoginModule { // Add any JNDI properties to the environment for (String key : options.keySet()) { - if (key.indexOf(".") > -1) { + if (key.indexOf('.') > -1) { ldapEnvironment.put(key, options.get(key)); } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java index 034a986eac2..8b7e88facac 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java @@ -857,7 +857,7 @@ public class CommandInterpreter { bpSpec = runtime.createClassLineBreakpoint(classId, lineNumber); } else { // Try stripping method from class.method token. - int idot = token.lastIndexOf("."); + int idot = token.lastIndexOf('.'); if ( (idot <= 0) || /* No dot or dot in first char */ (idot >= token.length() - 1) ) { /* dot in last char */ return null; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java index 640a8c53ed9..33f6e3ddf7f 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java @@ -1079,7 +1079,7 @@ class Commands { } } else { // Try stripping method from class.method token. - int idot = token.lastIndexOf("."); + int idot = token.lastIndexOf('.'); if ( (idot <= 0) || /* No dot or dot in first char */ (idot >= token.length() - 1) ) { /* dot in last char */ printBreakpointCommandUsage(atForm, inForm); diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java index 64d5abe848a..d453d82c38c 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/AllClassesQuery.java @@ -67,7 +67,7 @@ class AllClassesQuery extends QueryHandler { continue; } String name = clazz.getName(); - int pos = name.lastIndexOf("."); + int pos = name.lastIndexOf('.'); String pkg; if (name.startsWith("[")) { // Only in ancient heap dumps pkg = ""; diff --git a/jdk/src/share/classes/java/applet/Applet.java b/jdk/src/share/classes/java/applet/Applet.java index 889e618a55e..9dccb7c9a7e 100644 --- a/jdk/src/share/classes/java/applet/Applet.java +++ b/jdk/src/share/classes/java/applet/Applet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,6 +86,7 @@ public class Applet extends Panel { /** * Read an applet from an object input stream. + * @param s an object input stream. * @exception HeadlessException if * GraphicsEnvironment.isHeadless() returns * true diff --git a/jdk/src/share/classes/java/applet/AppletContext.java b/jdk/src/share/classes/java/applet/AppletContext.java index c031686acc0..47fec71cb5b 100644 --- a/jdk/src/share/classes/java/applet/AppletContext.java +++ b/jdk/src/share/classes/java/applet/AppletContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -152,7 +152,7 @@ public interface AppletContext { * For security reasons, mapping of streams and keys exists for each * codebase. In other words, applet from one codebase cannot access * the streams created by an applet from a different codebase - *

+ * * @param key key with which the specified value is to be associated. * @param stream stream to be associated with the specified key. If this * parameter is null, the specified key is removed @@ -172,7 +172,7 @@ public interface AppletContext { * For security reasons, mapping of streams and keys exists for each * codebase. In other words, applet from one codebase cannot access * the streams created by an applet from a different codebase - *

+ * * @return the stream to which this applet context maps the key * @param key key whose associated stream is to be returned. * @since 1.4 @@ -185,7 +185,7 @@ public interface AppletContext { * For security reasons, mapping of streams and keys exists for each * codebase. In other words, applet from one codebase cannot access * the streams created by an applet from a different codebase - *

+ * * @return an Iterator of all the names of the streams in this applet * context. * @since 1.4 diff --git a/jdk/src/share/classes/java/awt/geom/Path2D.java b/jdk/src/share/classes/java/awt/geom/Path2D.java index 9f7df213546..7a401d36cf4 100644 --- a/jdk/src/share/classes/java/awt/geom/Path2D.java +++ b/jdk/src/share/classes/java/awt/geom/Path2D.java @@ -1926,9 +1926,9 @@ public abstract class Path2D implements Shape, Cloneable { * maintains, but it may contain no more precision either. * If the tradeoff of precision vs. storage size in the result is * important then the convenience constructors in the - * {@link Path2D.Float#Path2D.Float(Shape, AffineTransform) Path2D.Float} + * {@link Path2D.Float#Float(Shape, AffineTransform) Path2D.Float} * and - * {@link Path2D.Double#Path2D.Double(Shape, AffineTransform) Path2D.Double} + * {@link Path2D.Double#Double(Shape, AffineTransform) Path2D.Double} * subclasses should be used to make the choice explicit. * * @param at the {@code AffineTransform} used to transform a diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index a8aee7ffe62..262a126fafc 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -1296,7 +1296,7 @@ public final class Class implements java.io.Serializable, String simpleName = getSimpleBinaryName(); if (simpleName == null) { // top level class simpleName = getName(); - return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name + return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name } // According to JLS3 "Binary Compatibility" (13.1) the binary // name of non-package classes (not top level) is the binary diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index 078c1502176..876b1855012 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -2133,7 +2133,7 @@ public abstract class ClassLoader { return result.booleanValue(); // Check for most specific package entry - int dotIndex = className.lastIndexOf("."); + int dotIndex = className.lastIndexOf('.'); if (dotIndex < 0) { // default package result = packageAssertionStatus.get(null); if (result != null) @@ -2144,7 +2144,7 @@ public abstract class ClassLoader { result = packageAssertionStatus.get(className); if (result != null) return result.booleanValue(); - dotIndex = className.lastIndexOf(".", dotIndex-1); + dotIndex = className.lastIndexOf('.', dotIndex-1); } // Return the classloader default diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 7bcdfaf5e89..d881fe5d18d 100644 --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -85,7 +85,7 @@ class InvokerBytecodeGenerator { private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize, String className, String invokerName, MethodType invokerType) { if (invokerName.contains(".")) { - int p = invokerName.indexOf("."); + int p = invokerName.indexOf('.'); className = invokerName.substring(0, p); invokerName = invokerName.substring(p+1); } diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java index 36630459b88..0676b7b3ab0 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java @@ -607,7 +607,7 @@ class LambdaForm { assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_')))); LambdaForm form = new LambdaForm(sig); form.vmentry = m; - mt.form().setCachedLambdaForm(MethodTypeForm.LF_COUNTER, form); + form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_COUNTER, form); // FIXME: get rid of PREPARED_FORMS; use MethodTypeForm cache only forms.put(sig, form); } diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java index 5bea02055ef..b6ef976c515 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java @@ -313,7 +313,8 @@ public class LambdaMetafactory { * reference expression features of the Java Programming Language. * *

This is the general, more flexible metafactory; a streamlined version - * is provided by {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}. + * is provided by {@link #metafactory(java.lang.invoke.MethodHandles.Lookup, + * String, MethodType, MethodType, MethodHandle, MethodType)}. * A general description of the behavior of this method is provided * {@link LambdaMetafactory above}. * diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 6abceb5ad19..abd8999aeaa 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -692,8 +692,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; lform = new LambdaForm("guardWithCatch", lambdaType.parameterCount(), names); - basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform); - return lform; + return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform); } static diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 48a937c1998..0c5931d23be 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -1612,23 +1612,30 @@ return mh1; checkSecurityManager(refc, method); assert(!method.isMethodHandleInvoke()); - Class refcAsSuper; if (refKind == REF_invokeSpecial && refc != lookupClass() && !refc.isInterface() && - refc != (refcAsSuper = lookupClass().getSuperclass()) && + refc != lookupClass().getSuperclass() && refc.isAssignableFrom(lookupClass())) { assert(!method.getName().equals("")); // not this code path // Per JVMS 6.5, desc. of invokespecial instruction: // If the method is in a superclass of the LC, // and if our original search was above LC.super, - // repeat the search (symbolic lookup) from LC.super. + // repeat the search (symbolic lookup) from LC.super + // and continue with the direct superclass of that class, + // and so forth, until a match is found or no further superclasses exist. // FIXME: MemberName.resolve should handle this instead. - MemberName m2 = new MemberName(refcAsSuper, - method.getName(), - method.getMethodType(), - REF_invokeSpecial); - m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull()); + Class refcAsSuper = lookupClass(); + MemberName m2; + do { + refcAsSuper = refcAsSuper.getSuperclass(); + m2 = new MemberName(refcAsSuper, + method.getName(), + method.getMethodType(), + REF_invokeSpecial); + m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull()); + } while (m2 == null && // no method is found yet + refc != refcAsSuper); // search up to refc if (m2 == null) throw new InternalError(method.toString()); method = m2; refc = refcAsSuper; diff --git a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java index ee5e6221b11..d34a2998cab 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java @@ -91,8 +91,10 @@ final class MethodTypeForm { return lambdaForms[which]; } - public LambdaForm setCachedLambdaForm(int which, LambdaForm form) { - // Should we perform some sort of CAS, to avoid racy duplication? + synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) { + // Simulate a CAS, to avoid racy duplication of results. + LambdaForm prev = lambdaForms[which]; + if (prev != null) return prev; return lambdaForms[which] = form; } diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index 60e059e8e77..8493d10eaa4 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -633,7 +633,7 @@ public abstract class Executable extends AccessibleObject getConstantPool(getDeclaringClass()), this, getDeclaringClass(), - getParameterTypes(), + getGenericParameterTypes(), TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER); } diff --git a/jdk/src/share/classes/java/net/CookieManager.java b/jdk/src/share/classes/java/net/CookieManager.java index f2d29cda82b..15d4cc33e08 100644 --- a/jdk/src/share/classes/java/net/CookieManager.java +++ b/jdk/src/share/classes/java/net/CookieManager.java @@ -294,7 +294,7 @@ public class CookieManager extends CookieHandler // the path is the directory of the page/doc String path = uri.getPath(); if (!path.endsWith("/")) { - int i = path.lastIndexOf("/"); + int i = path.lastIndexOf('/'); if (i > 0) { path = path.substring(0, i + 1); } else { @@ -364,7 +364,7 @@ public class CookieManager extends CookieHandler static private boolean isInPortList(String lst, int port) { - int i = lst.indexOf(","); + int i = lst.indexOf(','); int val = -1; while (i > 0) { try { @@ -375,7 +375,7 @@ public class CookieManager extends CookieHandler } catch (NumberFormatException numberFormatException) { } lst = lst.substring(i+1); - i = lst.indexOf(","); + i = lst.indexOf(','); } if (!lst.isEmpty()) { try { diff --git a/jdk/src/share/classes/java/net/InetAddress.java b/jdk/src/share/classes/java/net/InetAddress.java index 77c6a1f6c57..5bbdf0fd187 100644 --- a/jdk/src/share/classes/java/net/InetAddress.java +++ b/jdk/src/share/classes/java/net/InetAddress.java @@ -1138,7 +1138,7 @@ class InetAddress implements java.io.Serializable { // This is supposed to be an IPv6 literal // Check if a numeric or string zone id is present int pos; - if ((pos=host.indexOf ("%")) != -1) { + if ((pos=host.indexOf ('%')) != -1) { numericZone = checkNumericZone (host); if (numericZone == -1) { /* remainder of string must be an ifname */ ifname = host.substring (pos+1); diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index d4b7656ce5e..43fe4bfd940 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -1017,7 +1017,7 @@ class Socket implements java.io.Closeable { if (isClosed()) throw new SocketException("Socket is closed"); if (!on) { - getImpl().setOption(SocketOptions.SO_LINGER, new Boolean(on)); + getImpl().setOption(SocketOptions.SO_LINGER, on); } else { if (linger < 0) { throw new IllegalArgumentException("invalid value for SO_LINGER"); diff --git a/jdk/src/share/classes/java/net/SocketPermission.java b/jdk/src/share/classes/java/net/SocketPermission.java index 51777d90385..d44c8471613 100644 --- a/jdk/src/share/classes/java/net/SocketPermission.java +++ b/jdk/src/share/classes/java/net/SocketPermission.java @@ -777,7 +777,7 @@ public final class SocketPermission extends Permission // Literal IPv6 address host = getName().substring(1, getName().indexOf(']')); } else { - int i = getName().indexOf(":"); + int i = getName().indexOf(':'); if (i == -1) host = getName(); else { diff --git a/jdk/src/share/classes/java/net/SocksSocketImpl.java b/jdk/src/share/classes/java/net/SocksSocketImpl.java index b05a4d4c853..7c0f899b8e6 100644 --- a/jdk/src/share/classes/java/net/SocksSocketImpl.java +++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java @@ -368,7 +368,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { String host = epoint.getHostString(); // IPv6 litteral? if (epoint.getAddress() instanceof Inet6Address && - (!host.startsWith("[")) && (host.indexOf(":") >= 0)) { + (!host.startsWith("[")) && (host.indexOf(':') >= 0)) { host = "[" + host + "]"; } try { @@ -688,7 +688,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { String host = saddr.getHostString(); // IPv6 litteral? if (saddr.getAddress() instanceof Inet6Address && - (!host.startsWith("[")) && (host.indexOf(":") >= 0)) { + (!host.startsWith("[")) && (host.indexOf(':') >= 0)) { host = "[" + host + "]"; } try { diff --git a/jdk/src/share/classes/java/net/URI.java b/jdk/src/share/classes/java/net/URI.java index 0a05793b9a9..0035d00ead7 100644 --- a/jdk/src/share/classes/java/net/URI.java +++ b/jdk/src/share/classes/java/net/URI.java @@ -1851,9 +1851,9 @@ public final class URI sb.append("//"); if (authority.startsWith("[")) { // authority should (but may not) contain an embedded IPv6 address - int end = authority.indexOf("]"); + int end = authority.indexOf(']'); String doquote = authority, dontquote = ""; - if (end != -1 && authority.indexOf(":") != -1) { + if (end != -1 && authority.indexOf(':') != -1) { // the authority contains an IPv6 address if (end == authority.length()) { dontquote = authority; @@ -1889,8 +1889,8 @@ public final class URI * because we must not quote a literal IPv6 address */ if (opaquePart.startsWith("//[")) { - int end = opaquePart.indexOf("]"); - if (end != -1 && opaquePart.indexOf(":")!=-1) { + int end = opaquePart.indexOf(']'); + if (end != -1 && opaquePart.indexOf(':')!=-1) { String doquote, dontquote; if (end == opaquePart.length()) { dontquote = opaquePart; diff --git a/jdk/src/share/classes/java/security/AccessController.java b/jdk/src/share/classes/java/security/AccessController.java index 36408a8d633..e2b8e584560 100644 --- a/jdk/src/share/classes/java/security/AccessController.java +++ b/jdk/src/share/classes/java/security/AccessController.java @@ -592,14 +592,24 @@ public final class AccessController { System.getSecurityManager() != null && !callerPD.impliesCreateAccessControlContext()) { - ProtectionDomain nullPD = new ProtectionDomain(null, null); - return new AccessControlContext(new ProtectionDomain[] { nullPD }); + return getInnocuousAcc(); } else { return new AccessControlContext(callerPD, combiner, parent, context, perms); } } + private static class AccHolder { + // An AccessControlContext with no granted permissions. + // Only initialized on demand when getInnocuousAcc() is called. + static final AccessControlContext innocuousAcc = + new AccessControlContext(new ProtectionDomain[] { + new ProtectionDomain(null, null) }); + } + private static AccessControlContext getInnocuousAcc() { + return AccHolder.innocuousAcc; + } + private static ProtectionDomain getCallerPD(final Class caller) { ProtectionDomain callerPd = doPrivileged (new PrivilegedAction() { diff --git a/jdk/src/share/classes/java/security/BasicPermission.java b/jdk/src/share/classes/java/security/BasicPermission.java index 89cc2f92152..0abbfa7c047 100644 --- a/jdk/src/share/classes/java/security/BasicPermission.java +++ b/jdk/src/share/classes/java/security/BasicPermission.java @@ -430,7 +430,7 @@ final class BasicPermissionCollection offset = path.length()-1; - while ((last = path.lastIndexOf(".", offset)) != -1) { + while ((last = path.lastIndexOf('.', offset)) != -1) { path = path.substring(0, last+1) + "*"; //System.out.println("check "+path); diff --git a/jdk/src/share/classes/java/security/Provider.java b/jdk/src/share/classes/java/security/Provider.java index e8c7a081b5a..346aca9474c 100644 --- a/jdk/src/share/classes/java/security/Provider.java +++ b/jdk/src/share/classes/java/security/Provider.java @@ -931,7 +931,7 @@ public abstract class Provider extends Properties { } private String[] getTypeAndAlgorithm(String key) { - int i = key.indexOf("."); + int i = key.indexOf('.'); if (i < 1) { if (debug != null) { debug.println("Ignoring invalid entry in provider " diff --git a/jdk/src/share/classes/java/security/Security.java b/jdk/src/share/classes/java/security/Security.java index 0db09da7061..e24c0023f77 100644 --- a/jdk/src/share/classes/java/security/Security.java +++ b/jdk/src/share/classes/java/security/Security.java @@ -1114,7 +1114,7 @@ public final class Security { // implementation of an algorithm. We are only interested // in entries which lead to the implementation // classes. - if (currentKey.indexOf(" ") < 0) { + if (currentKey.indexOf(' ') < 0) { result.add(currentKey.substring( serviceName.length() + 1)); } diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index a59c98d4acf..d3b1df4a9e8 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -1967,7 +1967,7 @@ public class HashMap extends AbstractMap dir = -1; else if (ph < h) dir = 1; - else if ((pk = p.key) == k || (pk != null && k.equals(pk))) + else if ((pk = p.key) == k || (k != null && k.equals(pk))) return p; else if ((kc == null && (kc = comparableClassFor(k)) == null) || diff --git a/jdk/src/share/classes/java/util/PropertyPermission.java b/jdk/src/share/classes/java/util/PropertyPermission.java index b772e1b12f8..d532bddabf6 100644 --- a/jdk/src/share/classes/java/util/PropertyPermission.java +++ b/jdk/src/share/classes/java/util/PropertyPermission.java @@ -546,7 +546,7 @@ final class PropertyPermissionCollection extends PermissionCollection offset = name.length()-1; - while ((last = name.lastIndexOf(".", offset)) != -1) { + while ((last = name.lastIndexOf('.', offset)) != -1) { name = name.substring(0, last+1) + "*"; //System.out.println("check "+name); diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java index 0c24af26f28..c1468a1be1c 100644 --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java @@ -276,7 +276,7 @@ class JarVerifier { // now we are parsing a signature block file - String key = uname.substring(0, uname.lastIndexOf(".")); + String key = uname.substring(0, uname.lastIndexOf('.')); if (signerCache == null) signerCache = new ArrayList<>(); diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java index d2f7004bb27..ffd9d96300d 100644 --- a/jdk/src/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/share/classes/java/util/logging/LogManager.java @@ -779,7 +779,7 @@ public class LogManager { int ix = 1; for (;;) { - int ix2 = name.indexOf(".", ix); + int ix2 = name.indexOf('.', ix); if (ix2 < 0) { break; } @@ -802,7 +802,7 @@ public class LogManager { } LogNode node = root; while (name.length() > 0) { - int ix = name.indexOf("."); + int ix = name.indexOf('.'); String head; if (ix > 0) { head = name.substring(0, ix); diff --git a/jdk/src/share/classes/java/util/logging/XMLFormatter.java b/jdk/src/share/classes/java/util/logging/XMLFormatter.java index 541c73fafff..075da9a3681 100644 --- a/jdk/src/share/classes/java/util/logging/XMLFormatter.java +++ b/jdk/src/share/classes/java/util/logging/XMLFormatter.java @@ -174,7 +174,7 @@ public class XMLFormatter extends Formatter { // Check to see if the parameter was not a messagetext format // or was not null or empty if (parameters != null && parameters.length != 0 - && record.getMessage().indexOf("{") == -1 ) { + && record.getMessage().indexOf('{') == -1 ) { for (Object parameter : parameters) { sb.append(" "); try { diff --git a/jdk/src/share/classes/java/util/zip/ZipInputStream.java b/jdk/src/share/classes/java/util/zip/ZipInputStream.java index 77a598df818..7b4ccc86c76 100644 --- a/jdk/src/share/classes/java/util/zip/ZipInputStream.java +++ b/jdk/src/share/classes/java/util/zip/ZipInputStream.java @@ -319,7 +319,8 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants { if (len > 0) { byte[] extra = new byte[len]; readFully(extra, 0, len); - e.setExtra0(extra, true); + e.setExtra0(extra, + e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL); } return e; } diff --git a/jdk/src/share/classes/javax/management/MBeanPermission.java b/jdk/src/share/classes/javax/management/MBeanPermission.java index 3c998e4ea01..4a3442511a3 100644 --- a/jdk/src/share/classes/javax/management/MBeanPermission.java +++ b/jdk/src/share/classes/javax/management/MBeanPermission.java @@ -290,7 +290,7 @@ public class MBeanPermission extends Permission { // Parse ObjectName - int openingBracket = name.indexOf("["); + int openingBracket = name.indexOf('['); if (openingBracket == -1) { // If "[on]" missing then ObjectName("*:*") // @@ -329,7 +329,7 @@ public class MBeanPermission extends Permission { // Parse member - int poundSign = name.indexOf("#"); + int poundSign = name.indexOf('#'); if (poundSign == -1) setMember("*"); diff --git a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java index 0605713bf7a..f2534a62269 100644 --- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java +++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java @@ -329,7 +329,7 @@ public class DescriptorSupport inFld = false; } else if (inFld && inDesc) { // want kw=value, eg, name="myname" value="myvalue" - int eq_separator = tok.indexOf("="); + int eq_separator = tok.indexOf('='); if (eq_separator > 0) { String kwPart = tok.substring(0,eq_separator); String valPart = tok.substring(eq_separator+1); @@ -458,7 +458,7 @@ public class DescriptorSupport if ((fields[i] == null) || (fields[i].equals(""))) { continue; } - int eq_separator = fields[i].indexOf("="); + int eq_separator = fields[i].indexOf('='); if (eq_separator < 0) { // illegal if no = or is first character if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) { diff --git a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java index d19aa48fde6..7483ab13188 100644 --- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java +++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java @@ -934,7 +934,7 @@ public class RequiredModelMBean String opMethodName; // Parse for class name and method - int opSplitter = opName.lastIndexOf("."); + int opSplitter = opName.lastIndexOf('.'); if (opSplitter > 0) { opClassName = opName.substring(0,opSplitter); opMethodName = opName.substring(opSplitter+1); @@ -943,7 +943,7 @@ public class RequiredModelMBean /* Ignore anything after a left paren. We keep this for compatibility but it isn't specified. */ - opSplitter = opMethodName.indexOf("("); + opSplitter = opMethodName.indexOf('('); if (opSplitter > 0) opMethodName = opMethodName.substring(0,opSplitter); diff --git a/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java b/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java index 37a2660cb03..9aa0e6352a2 100644 --- a/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java +++ b/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java @@ -495,7 +495,7 @@ public final class PrivateCredentialPermission extends Permission { // perform new initialization from the permission name - if (getName().indexOf(" ") == -1 && getName().indexOf("\"") == -1) { + if (getName().indexOf(' ') == -1 && getName().indexOf('"') == -1) { // name only has a credential class specified credentialClass = getName(); diff --git a/jdk/src/share/classes/javax/security/sasl/Sasl.java b/jdk/src/share/classes/javax/security/sasl/Sasl.java index 1ce36c74311..74f21c1b215 100644 --- a/jdk/src/share/classes/javax/security/sasl/Sasl.java +++ b/jdk/src/share/classes/javax/security/sasl/Sasl.java @@ -600,7 +600,7 @@ public class Sasl { // implementation of an algorithm. We are only interested // in entries which lead to the implementation // classes. - if (currentKey.indexOf(" ") < 0) { + if (currentKey.indexOf(' ') < 0) { String className = providers[i].getProperty(currentKey); if (!classes.contains(className)) { classes.add(className); diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java index 66e8e7e3f11..f5b24254ece 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java @@ -785,11 +785,29 @@ public class ClassWriter extends ClassVisitor { if (innerClasses == null) { innerClasses = new ByteVector(); } - ++innerClassesCount; - innerClasses.putShort(name == null ? 0 : newClass(name)); - innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); - innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); - innerClasses.putShort(access); + // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the + // constant_pool table which represents a class or interface C that is + // not a package member must have exactly one corresponding entry in the + // classes array". To avoid duplicates we keep track in the intVal field + // of the Item of each CONSTANT_Class_info entry C whether an inner + // class entry has already been added for C (this field is unused for + // class entries, and changing its value does not change the hashcode + // and equality tests). If so we store the index of this inner class + // entry (plus one) in intVal. This hack allows duplicate detection in + // O(1) time. + Item nameItem = newClassItem(name); + if (nameItem.intVal == 0) { + ++innerClassesCount; + innerClasses.putShort(nameItem.index); + innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); + innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); + innerClasses.putShort(access); + nameItem.intVal = innerClassesCount; + } else { + // Compare the inner classes entry nameItem.intVal - 1 with the + // arguments of this method and throw an exception if there is a + // difference? + } } @Override diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java index e32a13af942..811b74c7242 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java @@ -1455,16 +1455,20 @@ final class Frame { | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); } else { // if u and t are array types, but not with the same element - // type, merge(u,t)=java/lang/Object - v = OBJECT | cw.addType("java/lang/Object"); + // type, merge(u,t) = dim(u) - 1 | java/lang/Object + int vdim = ELEMENT_OF + (u & DIM); + v = vdim | OBJECT | cw.addType("java/lang/Object"); } } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { // if t is any other reference or array type, the merged type - // is Object, or min(dim(u), dim(t)) | java/lang/Object is u - // and t have different array dimensions - int tdim = t & DIM; - int udim = u & DIM; - v = (udim != tdim ? Math.min(tdim, udim) : 0) | OBJECT + // is min(udim, tdim) | java/lang/Object, where udim is the + // array dimension of u, minus 1 if u is an array type with a + // primitive element type (and similarly for tdim). + int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 + : ELEMENT_OF) + (t & DIM); + int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 + : ELEMENT_OF) + (u & DIM); + v = Math.min(tdim, udim) | OBJECT | cw.addType("java/lang/Object"); } else { // if t is any other type, merge(u,t)=TOP diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java index 90ff74377ff..25ed37718dd 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Item.java @@ -230,6 +230,7 @@ final class Item { * @param strVal3 * third part of the value of this item. */ + @SuppressWarnings("fallthrough") void set(final int type, final String strVal1, final String strVal2, final String strVal3) { this.type = type; @@ -237,9 +238,10 @@ final class Item { this.strVal2 = strVal2; this.strVal3 = strVal3; switch (type) { + case ClassWriter.CLASS: + this.intVal = 0; // intVal of a class must be zero, see visitInnerClass case ClassWriter.UTF8: case ClassWriter.STR: - case ClassWriter.CLASS: case ClassWriter.MTYPE: case ClassWriter.TYPE_NORMAL: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java index f4bc30df4bd..bbea0001235 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Label.java @@ -502,7 +502,7 @@ public class Label { void addToSubroutine(final long id, final int nbSubroutines) { if ((status & VISITED) == 0) { status |= VISITED; - srcAndRefPositions = new int[(nbSubroutines - 1) / 32 + 1]; + srcAndRefPositions = new int[nbSubroutines / 32 + 1]; } srcAndRefPositions[(int) (id >>> 32)] |= (int) id; } diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java index 81a82804d6e..e02fad465d9 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java @@ -1430,6 +1430,14 @@ class MethodWriter extends MethodVisitor { @Override public void visitMaxs(final int maxStack, final int maxLocals) { + if (resize) { + // replaces the temporary jump opcodes introduced by Label.resolve. + if (ClassReader.RESIZE) { + resizeInstructions(); + } else { + throw new RuntimeException("Method code too large!"); + } + } if (ClassReader.FRAMES && compute == FRAMES) { // completes the control flow graph with exception handler blocks Handler handler = firstHandler; @@ -1987,43 +1995,43 @@ class MethodWriter extends MethodVisitor { stackMap.putByte(v); } } else { - StringBuffer buf = new StringBuffer(); + StringBuilder sb = new StringBuilder(); d >>= 28; while (d-- > 0) { - buf.append('['); + sb.append('['); } if ((t & Frame.BASE_KIND) == Frame.OBJECT) { - buf.append('L'); - buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); - buf.append(';'); + sb.append('L'); + sb.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); + sb.append(';'); } else { switch (t & 0xF) { case 1: - buf.append('I'); + sb.append('I'); break; case 2: - buf.append('F'); + sb.append('F'); break; case 3: - buf.append('D'); + sb.append('D'); break; case 9: - buf.append('Z'); + sb.append('Z'); break; case 10: - buf.append('B'); + sb.append('B'); break; case 11: - buf.append('C'); + sb.append('C'); break; case 12: - buf.append('S'); + sb.append('S'); break; default: - buf.append('J'); + sb.append('J'); } } - stackMap.putByte(7).putShort(cw.newClass(buf.toString())); + stackMap.putByte(7).putShort(cw.newClass(sb.toString())); } } } @@ -2051,14 +2059,6 @@ class MethodWriter extends MethodVisitor { if (classReaderOffset != 0) { return 6 + classReaderLength; } - if (resize) { - // replaces the temporary jump opcodes introduced by Label.resolve. - if (ClassReader.RESIZE) { - resizeInstructions(); - } else { - throw new RuntimeException("Method code too large!"); - } - } int size = 8; if (code.length > 0) { if (code.length > 65536) { @@ -2715,49 +2715,50 @@ class MethodWriter extends MethodVisitor { } } - // recomputes the stack map frames - if (frameCount > 0) { - if (compute == FRAMES) { - frameCount = 0; - stackMap = null; - previousFrame = null; - frame = null; - Frame f = new Frame(); - f.owner = labels; - Type[] args = Type.getArgumentTypes(descriptor); - f.initInputFrame(cw, access, args, maxLocals); - visitFrame(f); - Label l = labels; - while (l != null) { - /* - * here we need the original label position. getNewOffset - * must therefore never have been called for this label. - */ - u = l.position - 3; - if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) { - getNewOffset(allIndexes, allSizes, l); - // TODO update offsets in UNINITIALIZED values - visitFrame(l.frame); - } - l = l.successor; - } - } else { + // updates the stack map frame labels + if (compute == FRAMES) { + Label l = labels; + while (l != null) { /* - * Resizing an existing stack map frame table is really hard. - * Not only the table must be parsed to update the offets, but - * new frames may be needed for jump instructions that were - * inserted by this method. And updating the offsets or - * inserting frames can change the format of the following - * frames, in case of packed frames. In practice the whole table - * must be recomputed. For this the frames are marked as - * potentially invalid. This will cause the whole class to be - * reread and rewritten with the COMPUTE_FRAMES option (see the - * ClassWriter.toByteArray method). This is not very efficient - * but is much easier and requires much less code than any other - * method I can think of. + * Detects the labels that are just after an IF instruction that + * has been resized with the IFNOT GOTO_W pattern. These labels + * are now the target of a jump instruction (the IFNOT + * instruction). Note that we need the original label position + * here. getNewOffset must therefore never have been called for + * this label. */ - cw.invalidFrames = true; + u = l.position - 3; + if (u >= 0 && resize[u]) { + l.status |= Label.TARGET; + } + getNewOffset(allIndexes, allSizes, l); + l = l.successor; } + // Update the offsets in the uninitialized types + for (i = 0; i < cw.typeTable.length; ++i) { + Item item = cw.typeTable[i]; + if (item != null && item.type == ClassWriter.TYPE_UNINIT) { + item.intVal = getNewOffset(allIndexes, allSizes, 0, + item.intVal); + } + } + // The stack map frames are not serialized yet, so we don't need + // to update them. They will be serialized in visitMaxs. + } else if (frameCount > 0) { + /* + * Resizing an existing stack map frame table is really hard. Not + * only the table must be parsed to update the offets, but new + * frames may be needed for jump instructions that were inserted by + * this method. And updating the offsets or inserting frames can + * change the format of the following frames, in case of packed + * frames. In practice the whole table must be recomputed. For this + * the frames are marked as potentially invalid. This will cause the + * whole class to be reread and rewritten with the COMPUTE_FRAMES + * option (see the ClassWriter.toByteArray method). This is not very + * efficient but is much easier and requires much less code than any + * other method I can think of. + */ + cw.invalidFrames = true; } // updates the exception handler block labels Handler h = firstHandler; diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java index e385f9f6491..633a4a024ea 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Type.java @@ -585,11 +585,11 @@ public class Type { case DOUBLE: return "double"; case ARRAY: - StringBuffer b = new StringBuffer(getElementType().getClassName()); + StringBuilder sb = new StringBuilder(getElementType().getClassName()); for (int i = getDimensions(); i > 0; --i) { - b.append("[]"); + sb.append("[]"); } - return b.toString(); + return sb.toString(); case OBJECT: return new String(buf, off, len).replace('/', '.'); default: diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java index 4ece2dba90d..2c54ea475fd 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java @@ -1089,7 +1089,7 @@ public class InstructionAdapter extends MethodVisitor { @Deprecated public void invokestatic(final String owner, final String name, final String desc) { - if (api < Opcodes.ASM5) { + if (api >= Opcodes.ASM5) { invokestatic(owner, name, desc, false); return; } diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java index df97a36575f..92a83ff8ecc 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java @@ -205,7 +205,7 @@ public class Method { } String returnType = method.substring(0, space); String methodName = method.substring(space + 1, start - 1).trim(); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append('('); int p; do { @@ -229,7 +229,7 @@ public class Method { return type; } - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); int index = 0; while ((index = type.indexOf("[]", index) + 1) > 0) { sb.append('['); diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java index 2b4f7201d69..d5edd06363f 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java @@ -147,17 +147,17 @@ public abstract class Remapper { } Type[] args = Type.getArgumentTypes(desc); - StringBuffer s = new StringBuffer("("); + StringBuilder sb = new StringBuilder("("); for (int i = 0; i < args.length; i++) { - s.append(mapDesc(args[i].getDescriptor())); + sb.append(mapDesc(args[i].getDescriptor())); } Type returnType = Type.getReturnType(desc); if (returnType == Type.VOID_TYPE) { - s.append(")V"); - return s.toString(); + sb.append(")V"); + return sb.toString(); } - s.append(')').append(mapDesc(returnType.getDescriptor())); - return s.toString(); + sb.append(')').append(mapDesc(returnType.getDescriptor())); + return sb.toString(); } public Object mapValue(Object value) { diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java index de8915125ff..51fcb4c46f6 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java @@ -239,7 +239,9 @@ public class SerialVersionUIDAdder extends ClassVisitor { if (computeSVUID) { this.name = name; this.access = access; - this.interfaces = Arrays.copyOf(interfaces, interfaces.length); + this.interfaces = new String[interfaces.length]; + System.arraycopy(interfaces, 0, this.interfaces, 0, + interfaces.length); } super.visit(version, access, name, signature, superName, interfaces); diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java index b6e2075de8b..bb01f7a7a3d 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java @@ -351,7 +351,7 @@ public class MethodNode extends MethodVisitor { } @Override - @SuppressWarnings("serial") // Anonymous class + @SuppressWarnings("serial") public AnnotationVisitor visitAnnotationDefault() { return new AnnotationNode(new ArrayList(0) { @Override diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java index 92b570b17f0..fc22dc3200a 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java @@ -66,7 +66,7 @@ import jdk.internal.org.objectweb.asm.tree.AbstractInsnNode; * @author Bing Ran * @author Eric Bruneton */ -@SuppressWarnings("serial") // implementation class +@SuppressWarnings("serial") public class AnalyzerException extends Exception { public final AbstractInsnNode node; diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java index f6b8db3ddfb..cbb5f86f534 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java @@ -754,14 +754,14 @@ public class Frame { */ @Override public String toString() { - StringBuffer b = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < getLocals(); ++i) { - b.append(getLocal(i)); + sb.append(getLocal(i)); } - b.append(' '); + sb.append(' '); for (int i = 0; i < getStackSize(); ++i) { - b.append(getStack(i).toString()); + sb.append(getStack(i).toString()); } - return b.toString(); + return sb.toString(); } } diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java index a9487e16f5e..26e208a4cef 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java @@ -206,7 +206,6 @@ public class ASMifier extends Printer { } text.add("import java.util.*;\n"); text.add("import jdk.internal.org.objectweb.asm.*;\n"); - text.add("import jdk.internal.org.objectweb.asm.attrs.*;\n"); text.add("public class " + simpleName + "Dump implements Opcodes {\n\n"); text.add("public static byte[] dump () throws Exception {\n\n"); text.add("ClassWriter cw = new ClassWriter(0);\n"); diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java index 5105db7f9c2..22dddf2d5e1 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java @@ -298,26 +298,26 @@ public class CheckClassAdapter extends ClassVisitor { for (int j = 0; j < method.instructions.size(); ++j) { method.instructions.get(j).accept(mv); - StringBuffer s = new StringBuffer(); + StringBuilder sb = new StringBuilder(); Frame f = frames[j]; if (f == null) { - s.append('?'); + sb.append('?'); } else { for (int k = 0; k < f.getLocals(); ++k) { - s.append(getShortName(f.getLocal(k).toString())) + sb.append(getShortName(f.getLocal(k).toString())) .append(' '); } - s.append(" : "); + sb.append(" : "); for (int k = 0; k < f.getStackSize(); ++k) { - s.append(getShortName(f.getStack(k).toString())) + sb.append(getShortName(f.getStack(k).toString())) .append(' '); } } - while (s.length() < method.maxStack + method.maxLocals + 1) { - s.append(' '); + while (sb.length() < method.maxStack + method.maxLocals + 1) { + sb.append(' '); } pw.print(Integer.toString(j + 100000).substring(1)); - pw.print(" " + s + " : " + t.text.get(t.text.size() - 1)); + pw.print(" " + sb + " : " + t.text.get(t.text.size() - 1)); } for (int j = 0; j < method.tryCatchBlocks.size(); ++j) { method.tryCatchBlocks.get(j).accept(mv); diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java index 5c2c8bf4776..c210e2c4033 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java @@ -443,7 +443,7 @@ public class Textifier extends Printer { } buf.append(tab); - appendAccess(access); + appendAccess(access & ~Opcodes.ACC_VOLATILE); if ((access & Opcodes.ACC_NATIVE) != 0) { buf.append("native "); } diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt index c6f8ad648af..b1d916092e5 100644 --- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt +++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt @@ -1,12 +1,12 @@ Path: . -Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-03-12 +Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-05-27 URL: file:///svnroot/asm/trunk/asm Repository Root: file:///svnroot/asm Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9 -Revision: 1721 +Revision: 1748 Node Kind: directory Schedule: normal Last Changed Author: ebruneton -Last Changed Rev: 1721 -Last Changed Date: 2014-03-02 17:25:35 +0100 (Sun, 02 Mar 2014) +Last Changed Rev: 1747 +Last Changed Date: 2014-05-24 10:22:13 +0200 (Sat, 24 May 2014) diff --git a/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java b/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java index 7eb918d7b7b..6db4d4fdb6d 100644 --- a/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java +++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java @@ -2860,14 +2860,25 @@ public abstract class Parser { } else { // Get encoding from BOM or the xml text decl. reader = bom(is.getByteStream(), ' '); + /** + * [#4.3.3] requires BOM for UTF-16, however, it's not uncommon + * that it may be missing. A mature technique exists in Xerces + * to further check for possible UTF-16 encoding + */ + if (reader == null) { + reader = utf16(is.getByteStream()); + } + if (reader == null) { // Encoding is defined by the xml text decl. reader = enc("UTF-8", is.getByteStream()); expenc = xml(reader); - if (expenc.startsWith("UTF-16")) { - panic(FAULT); // UTF-16 must have BOM [#4.3.3] + if (!expenc.equals("UTF-8")) { + if (expenc.startsWith("UTF-16")) { + panic(FAULT); // UTF-16 must have BOM [#4.3.3] + } + reader = enc(expenc, is.getByteStream()); } - reader = enc(expenc, is.getByteStream()); } else { // Encoding is defined by the BOM. xml(reader); @@ -2956,6 +2967,49 @@ public abstract class Parser { } } + + /** + * Using a mature technique from Xerces, this method checks further after + * the bom method above to see if the encoding is UTF-16 + * + * @param is A byte stream of the entity. + * @return a reader, may be null + * @exception Exception is parser specific exception form panic method. + * @exception IOException + */ + private Reader utf16(InputStream is) + throws Exception { + if (mChIdx != 0) { + //The bom method has read ONE byte into the buffer. + byte b0 = (byte)mChars[0]; + if (b0 == 0x00 || b0 == 0x3C) { + int b1 = is.read(); + int b2 = is.read(); + int b3 = is.read(); + if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { + // UTF-16, big-endian, no BOM + mChars[0] = (char)(b1); + mChars[mChIdx++] = (char)(b3); + return new ReaderUTF16(is, 'b'); + } else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { + // UTF-16, little-endian, no BOM + mChars[0] = (char)(b0); + mChars[mChIdx++] = (char)(b2); + return new ReaderUTF16(is, 'l'); + } else { + /**not every InputStream supports reset, so we have to remember + * the state for further parsing + **/ + mChars[0] = (char)(b0); + mChars[mChIdx++] = (char)(b1); + mChars[mChIdx++] = (char)(b2); + mChars[mChIdx++] = (char)(b3); + } + + } + } + return null; + } /** * Parses the xml text declaration. * @@ -2974,17 +3028,17 @@ public abstract class Parser { String enc = "UTF-8"; char ch; int val; - short st; - // Read the xml text declaration into the buffer - if (mChIdx != 0) { - // The bom method have read ONE char into the buffer. - st = (short) ((mChars[0] == '<') ? 1 : -1); - } else { - st = 0; - } + short st = 0; + int byteRead = mChIdx; //number of bytes read prior to entering this method + while (st >= 0 && mChIdx < mChars.length) { - ch = ((val = reader.read()) >= 0) ? (char) val : EOS; - mChars[mChIdx++] = ch; + if (st < byteRead) { + ch = mChars[st]; + } else { + ch = ((val = reader.read()) >= 0) ? (char) val : EOS; + mChars[mChIdx++] = ch; + } + switch (st) { case 0: // read '<' of xml declaration switch (ch) { diff --git a/jdk/src/share/classes/jdk/net/ExtendedSocketOptions.java b/jdk/src/share/classes/jdk/net/ExtendedSocketOptions.java index 8be1fe6a5dc..a44560b4597 100644 --- a/jdk/src/share/classes/jdk/net/ExtendedSocketOptions.java +++ b/jdk/src/share/classes/jdk/net/ExtendedSocketOptions.java @@ -32,7 +32,7 @@ import java.net.SocketOption; * {@link java.net.StandardSocketOptions}. These options may be platform * specific. * - * @since 1.9 + * @since 1.8 */ @jdk.Exported public final class ExtendedSocketOptions { diff --git a/jdk/src/share/classes/jdk/net/NetworkPermission.java b/jdk/src/share/classes/jdk/net/NetworkPermission.java index 0e853f0d527..01aa1a89653 100644 --- a/jdk/src/share/classes/jdk/net/NetworkPermission.java +++ b/jdk/src/share/classes/jdk/net/NetworkPermission.java @@ -58,7 +58,7 @@ import java.security.BasicPermission; * * @see jdk.net.ExtendedSocketOptions * - * @since 1.9 + * @since 1.8 */ @jdk.Exported diff --git a/jdk/src/share/classes/jdk/net/SocketFlow.java b/jdk/src/share/classes/jdk/net/SocketFlow.java index a102a3f35a0..3d673d1fc44 100644 --- a/jdk/src/share/classes/jdk/net/SocketFlow.java +++ b/jdk/src/share/classes/jdk/net/SocketFlow.java @@ -43,7 +43,7 @@ import java.lang.annotation.Native; * When a security manager is installed, a {@link NetworkPermission} * is required to set or get this option. * - * @since 1.9 + * @since 1.8 */ @jdk.Exported public class SocketFlow { @@ -66,7 +66,7 @@ public class SocketFlow { * one of these statuses, which reflect the state of socket's * flow. * - * @since 1.9 + * @since 1.8 */ @jdk.Exported public enum Status { diff --git a/jdk/src/share/classes/jdk/net/Sockets.java b/jdk/src/share/classes/jdk/net/Sockets.java index 9f7d94a0323..2f2da459e45 100644 --- a/jdk/src/share/classes/jdk/net/Sockets.java +++ b/jdk/src/share/classes/jdk/net/Sockets.java @@ -51,7 +51,7 @@ import sun.net.ExtendedOptionsImpl; * When a security manager is installed, some non-standard socket options * may require a security permission before being set or get. * The details are specified in {@link ExtendedSocketOptions}. No permission - * is required for {@link java.net.StandardSocketOption}s. + * is required for {@link java.net.StandardSocketOptions}. * * @see java.nio.channels.NetworkChannel */ diff --git a/jdk/src/share/classes/jdk/net/package-info.java b/jdk/src/share/classes/jdk/net/package-info.java index 236d640dbfa..fd824f6fd1d 100644 --- a/jdk/src/share/classes/jdk/net/package-info.java +++ b/jdk/src/share/classes/jdk/net/package-info.java @@ -27,7 +27,7 @@ * Platform specific socket options for the {@code java.net} and {@code java.nio.channels} * socket classes. * - * @since 1.9 + * @since 1.8 */ @jdk.Exported diff --git a/jdk/src/share/classes/sun/jvmstat/monitor/AbstractMonitor.java b/jdk/src/share/classes/sun/jvmstat/monitor/AbstractMonitor.java index 80789de60c5..c615df26eb5 100644 --- a/jdk/src/share/classes/sun/jvmstat/monitor/AbstractMonitor.java +++ b/jdk/src/share/classes/sun/jvmstat/monitor/AbstractMonitor.java @@ -84,7 +84,7 @@ public abstract class AbstractMonitor implements Monitor { * {@inheritDoc} */ public String getBaseName() { - int baseIndex = name.lastIndexOf(".")+1; + int baseIndex = name.lastIndexOf('.') + 1; return name.substring(baseIndex); } diff --git a/jdk/src/share/classes/sun/jvmstat/monitor/HostIdentifier.java b/jdk/src/share/classes/sun/jvmstat/monitor/HostIdentifier.java index 4ac28a1034a..470de36e64a 100644 --- a/jdk/src/share/classes/sun/jvmstat/monitor/HostIdentifier.java +++ b/jdk/src/share/classes/sun/jvmstat/monitor/HostIdentifier.java @@ -138,8 +138,8 @@ public class HostIdentifier { String frag = u.getFragment(); URI u2 = null; - int c1index = uriString.indexOf(":"); - int c2index = uriString.lastIndexOf(":"); + int c1index = uriString.indexOf(':'); + int c2index = uriString.lastIndexOf(':'); if (c2index != c1index) { /* * this is the scheme:hostname:port case. Attempt to diff --git a/jdk/src/share/classes/sun/management/StackTraceElementCompositeData.java b/jdk/src/share/classes/sun/management/StackTraceElementCompositeData.java index 27eed847dac..cb863fe27ba 100644 --- a/jdk/src/share/classes/sun/management/StackTraceElementCompositeData.java +++ b/jdk/src/share/classes/sun/management/StackTraceElementCompositeData.java @@ -68,7 +68,7 @@ public class StackTraceElementCompositeData extends LazyCompositeData { ste.getMethodName(), ste.getFileName(), new Integer(ste.getLineNumber()), - new Boolean(ste.isNativeMethod()), + ste.isNativeMethod(), }; try { return new CompositeDataSupport(stackTraceElementCompositeType, diff --git a/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java b/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java index 2e12104dced..cef28271e7e 100644 --- a/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java +++ b/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java @@ -120,8 +120,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData { new Long(threadInfo.getLockOwnerId()), threadInfo.getLockOwnerName(), stackTraceData, - new Boolean(threadInfo.isSuspended()), - new Boolean(threadInfo.isInNative()), + threadInfo.isSuspended(), + threadInfo.isInNative(), lockedMonitorsData, lockedSyncsData, }; diff --git a/jdk/src/share/classes/sun/management/VMOptionCompositeData.java b/jdk/src/share/classes/sun/management/VMOptionCompositeData.java index 51d8181451a..6eeac787000 100644 --- a/jdk/src/share/classes/sun/management/VMOptionCompositeData.java +++ b/jdk/src/share/classes/sun/management/VMOptionCompositeData.java @@ -59,7 +59,7 @@ public class VMOptionCompositeData extends LazyCompositeData { final Object[] vmOptionItemValues = { option.getName(), option.getValue(), - new Boolean(option.isWriteable()), + option.isWriteable(), option.getOrigin().toString(), }; diff --git a/jdk/src/share/classes/sun/management/snmp/jvminstr/NotificationTargetImpl.java b/jdk/src/share/classes/sun/management/snmp/jvminstr/NotificationTargetImpl.java index 9e080001ad0..d6574e3ebf9 100644 --- a/jdk/src/share/classes/sun/management/snmp/jvminstr/NotificationTargetImpl.java +++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/NotificationTargetImpl.java @@ -70,8 +70,8 @@ public class NotificationTargetImpl implements NotificationTarget { String addrStr; if (target.startsWith("[")) { - final int index = target.indexOf("]"); - final int index2 = target.lastIndexOf(":"); + final int index = target.indexOf(']'); + final int index2 = target.lastIndexOf(':'); if(index == -1) throw new IllegalArgumentException("Host starts with [ but " + "does not end with ]"); @@ -85,8 +85,8 @@ public class NotificationTargetImpl implements NotificationTarget { if (addrStr.startsWith("[")) throw new IllegalArgumentException("More than one [[...]]"); } else { - final int index = target.indexOf(":"); - final int index2 = target.lastIndexOf(":"); + final int index = target.indexOf(':'); + final int index2 = target.lastIndexOf(':'); if(index == -1) throw new IllegalArgumentException("Missing port separator \":\""); addrStr = target.substring(0, index); @@ -98,7 +98,7 @@ public class NotificationTargetImpl implements NotificationTarget { address = InetAddress.getByName(addrStr); //THE CHECK SHOULD BE STRONGER!!! - final int index = target.lastIndexOf(":"); + final int index = target.lastIndexOf(':'); community = target.substring(index + 1, target.length()); diff --git a/jdk/src/share/classes/sun/misc/ExtensionInfo.java b/jdk/src/share/classes/sun/misc/ExtensionInfo.java index 8b536379558..3fc17bf7339 100644 --- a/jdk/src/share/classes/sun/misc/ExtensionInfo.java +++ b/jdk/src/share/classes/sun/misc/ExtensionInfo.java @@ -273,8 +273,8 @@ public class ExtensionInfo { else { // Look for index of "." in the string - int sIdx = source.indexOf("."); - int tIdx = target.indexOf("."); + int sIdx = source.indexOf('.'); + int tIdx = target.indexOf('.'); if (sIdx == -1) sIdx = source.length() - 1; @@ -304,10 +304,10 @@ public class ExtensionInfo { String versionError = mf.format(args); // Look for "-" for pre-release - int prIndex = token.indexOf("-"); + int prIndex = token.indexOf('-'); // Look for "_" for patch release - int patchIndex = token.indexOf("_"); + int patchIndex = token.indexOf('_'); if (prIndex == -1 && patchIndex == -1) { diff --git a/jdk/src/share/classes/sun/misc/JarIndex.java b/jdk/src/share/classes/sun/misc/JarIndex.java index e43b9ee7f2e..d459751186b 100644 --- a/jdk/src/share/classes/sun/misc/JarIndex.java +++ b/jdk/src/share/classes/sun/misc/JarIndex.java @@ -172,7 +172,7 @@ public class JarIndex { if ((jarFiles = indexMap.get(fileName)) == null) { /* try the package name again */ int pos; - if((pos = fileName.lastIndexOf("/")) != -1) { + if((pos = fileName.lastIndexOf('/')) != -1) { jarFiles = indexMap.get(fileName.substring(0, pos)); } } @@ -195,7 +195,7 @@ public class JarIndex { public void add(String fileName, String jarName) { String packageName; int pos; - if((pos = fileName.lastIndexOf("/")) != -1) { + if((pos = fileName.lastIndexOf('/')) != -1) { packageName = fileName.substring(0, pos); } else { packageName = fileName; diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java index 11dae819751..dca817148a5 100644 --- a/jdk/src/share/classes/sun/misc/URLClassPath.java +++ b/jdk/src/share/classes/sun/misc/URLClassPath.java @@ -793,7 +793,7 @@ public class URLClassPath { boolean validIndex(final String name) { String packageName = name; int pos; - if((pos = name.lastIndexOf("/")) != -1) { + if((pos = name.lastIndexOf('/')) != -1) { packageName = name.substring(0, pos); } @@ -803,7 +803,7 @@ public class URLClassPath { while (enum_.hasMoreElements()) { entry = enum_.nextElement(); entryName = entry.getName(); - if((pos = entryName.lastIndexOf("/")) != -1) + if((pos = entryName.lastIndexOf('/')) != -1) entryName = entryName.substring(0, pos); if (entryName.equals(packageName)) { return true; @@ -900,7 +900,7 @@ public class URLClassPath { */ JarIndex newIndex = newLoader.getIndex(); if(newIndex != null) { - int pos = jarName.lastIndexOf("/"); + int pos = jarName.lastIndexOf('/'); newIndex.merge(this.index, (pos == -1 ? null : jarName.substring(0, pos + 1))); } diff --git a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java index 9c3fb964f0a..b490caa8f5e 100644 --- a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java @@ -258,7 +258,7 @@ public class FtpClient extends sun.net.ftp.FtpClient { d = null; } if (d != null && time != null) { - int c = time.indexOf(":"); + int c = time.indexOf(':'); now.setTime(d); now.set(Calendar.HOUR, Integer.parseInt(time.substring(0, c))); now.set(Calendar.MINUTE, Integer.parseInt(time.substring(c + 1))); @@ -294,7 +294,7 @@ public class FtpClient extends sun.net.ftp.FtpClient { public FtpDirEntry parseLine(String line) { String name = null; - int i = line.lastIndexOf(";"); + int i = line.lastIndexOf(';'); if (i > 0) { name = line.substring(i + 1).trim(); line = line.substring(0, i); @@ -305,7 +305,7 @@ public class FtpClient extends sun.net.ftp.FtpClient { FtpDirEntry file = new FtpDirEntry(name); while (!line.isEmpty()) { String s; - i = line.indexOf(";"); + i = line.indexOf(';'); if (i > 0) { s = line.substring(0, i); line = line.substring(i + 1); @@ -313,7 +313,7 @@ public class FtpClient extends sun.net.ftp.FtpClient { s = line; line = ""; } - i = s.indexOf("="); + i = s.indexOf('='); if (i > 0) { String fact = s.substring(0, i); String value = s.substring(i + 1); diff --git a/jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java b/jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java index aa28e556adf..2abeddc5d88 100644 --- a/jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java +++ b/jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java @@ -325,7 +325,7 @@ public final class DNSNameService implements NameService { while (i.hasNext()) { String parentDomain = i.next(); int start = 0; - while ((start = parentDomain.indexOf(".")) != -1 + while ((start = parentDomain.indexOf('.')) != -1 && start < parentDomain.length() -1) { try { results = resolve(ctx, host+"."+parentDomain, ids, 0); diff --git a/jdk/src/share/classes/sun/net/util/IPAddressUtil.java b/jdk/src/share/classes/sun/net/util/IPAddressUtil.java index 4dafa8a1d0b..a4cc9842a2b 100644 --- a/jdk/src/share/classes/sun/net/util/IPAddressUtil.java +++ b/jdk/src/share/classes/sun/net/util/IPAddressUtil.java @@ -132,7 +132,7 @@ public class IPAddressUtil { byte[] dst = new byte[INADDR16SZ]; int srcb_length = srcb.length; - int pc = src.indexOf ("%"); + int pc = src.indexOf ('%'); if (pc == srcb_length -1) { return null; } diff --git a/jdk/src/share/classes/sun/net/www/ParseUtil.java b/jdk/src/share/classes/sun/net/www/ParseUtil.java index d671c077291..cb8311996b1 100644 --- a/jdk/src/share/classes/sun/net/www/ParseUtil.java +++ b/jdk/src/share/classes/sun/net/www/ParseUtil.java @@ -356,8 +356,8 @@ public class ParseUtil { * because we must not quote a literal IPv6 address */ if (opaquePart.startsWith("//[")) { - int end = opaquePart.indexOf("]"); - if (end != -1 && opaquePart.indexOf(":")!=-1) { + int end = opaquePart.indexOf(']'); + if (end != -1 && opaquePart.indexOf(':')!=-1) { String doquote, dontquote; if (end == opaquePart.length()) { dontquote = opaquePart; @@ -408,8 +408,8 @@ public class ParseUtil { } else if (authority != null) { sb.append("//"); if (authority.startsWith("[")) { - int end = authority.indexOf("]"); - if (end != -1 && authority.indexOf(":")!=-1) { + int end = authority.indexOf(']'); + if (end != -1 && authority.indexOf(':')!=-1) { String doquote, dontquote; if (end == authority.length()) { dontquote = authority; diff --git a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java index 4357ffc4e73..e7a2cbb73be 100644 --- a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java +++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java @@ -93,9 +93,9 @@ public class ServerSocketAdaptor // package-private public Socket accept() throws IOException { synchronized (ssc.blockingLock()) { - if (!ssc.isBound()) - throw new IllegalBlockingModeException(); try { + if (!ssc.isBound()) + throw new NotYetBoundException(); if (timeout == 0) { SocketChannel sc = ssc.accept(); if (sc == null && !ssc.isBlocking()) diff --git a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java index 482f6b5ca2a..aa41880319b 100644 --- a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java +++ b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java @@ -341,6 +341,6 @@ public final class ReflectUtil { * (not to be confused with a Java Language anonymous inner class). */ public static boolean isVMAnonymousClass(Class cls) { - return cls.getName().indexOf("/") > -1; + return cls.getName().indexOf('/') > -1; } } diff --git a/jdk/src/share/classes/sun/rmi/runtime/Log.java b/jdk/src/share/classes/sun/rmi/runtime/Log.java index 507622a3acd..9a152b69e2c 100644 --- a/jdk/src/share/classes/sun/rmi/runtime/Log.java +++ b/jdk/src/share/classes/sun/rmi/runtime/Log.java @@ -426,7 +426,7 @@ public abstract class Log { * Mimic old log messages that only contain unqualified names. */ private static String unqualifiedName(String name) { - int lastDot = name.lastIndexOf("."); + int lastDot = name.lastIndexOf('.'); if (lastDot >= 0) { name = name.substring(lastDot + 1); } diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java index c561216b985..343810da8ae 100644 --- a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java +++ b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java @@ -141,7 +141,7 @@ public final class CGIHandler { { try { String command, param; - int delim = QueryString.indexOf("="); + int delim = QueryString.indexOf('='); if (delim == -1) { command = QueryString; param = ""; diff --git a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java index 602f1807d05..736ef98fcd8 100644 --- a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java +++ b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java @@ -50,8 +50,8 @@ public class GSSManagerImpl extends GSSManager { if (osname.startsWith("SunOS") || osname.contains("OS X") || osname.startsWith("Linux")) { - return new Boolean(System.getProperty - (USE_NATIVE_PROP)); + return Boolean.valueOf(System.getProperty + (USE_NATIVE_PROP)); } return Boolean.FALSE; } diff --git a/jdk/src/share/classes/sun/security/jgss/wrapper/Krb5Util.java b/jdk/src/share/classes/sun/security/jgss/wrapper/Krb5Util.java index 730c6fa17fa..77d5a3598e8 100644 --- a/jdk/src/share/classes/sun/security/jgss/wrapper/Krb5Util.java +++ b/jdk/src/share/classes/sun/security/jgss/wrapper/Krb5Util.java @@ -39,7 +39,7 @@ class Krb5Util { static String getTGSName(GSSNameElement name) throws GSSException { String krbPrinc = name.getKrbName(); - int atIndex = krbPrinc.indexOf("@"); + int atIndex = krbPrinc.indexOf('@'); String realm = krbPrinc.substring(atIndex + 1); StringBuffer buf = new StringBuffer("krbtgt/"); buf.append(realm).append('@').append(realm); diff --git a/jdk/src/share/classes/sun/security/krb5/KdcComm.java b/jdk/src/share/classes/sun/security/krb5/KdcComm.java index caaf20a86f8..721c105d345 100644 --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,7 +144,8 @@ public final class KdcComm { try { Config cfg = Config.getInstance(); String temp = cfg.get("libdefaults", "kdc_timeout"); - timeout = parsePositiveIntString(temp); + timeout = parseTimeString(temp); + temp = cfg.get("libdefaults", "max_retries"); max_retries = parsePositiveIntString(temp); temp = cfg.get("libdefaults", "udp_preference_limit"); @@ -425,6 +426,25 @@ public final class KdcComm { } } + /** + * Parses a time value string. If it ends with "s", parses as seconds. + * Otherwise, parses as milliseconds. + * @param s the time string + * @return the integer value in milliseconds, or -1 if input is null or + * has an invalid format + */ + private static int parseTimeString(String s) { + if (s == null) { + return -1; + } + if (s.endsWith("s")) { + int seconds = parsePositiveIntString(s.substring(0, s.length()-1)); + return (seconds < 0) ? -1 : (seconds*1000); + } else { + return parsePositiveIntString(s); + } + } + /** * Returns krb5.conf setting of {@code key} for a specific realm, * which can be: @@ -446,7 +466,11 @@ public final class KdcComm { try { String value = Config.getInstance().get("realms", realm, key); - temp = parsePositiveIntString(value); + if (key.equals("kdc_timeout")) { + temp = parseTimeString(value); + } else { + temp = parsePositiveIntString(value); + } } catch (Exception exc) { // Ignored, defValue will be picked up } diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Util.java b/jdk/src/share/classes/sun/security/pkcs11/P11Util.java index 38da9401f33..b5787a712f9 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Util.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,7 +166,7 @@ public final class P11Util { if (b == null) { return "(null)"; } - StringBuffer sb = new StringBuffer(b.length * 3); + StringBuilder sb = new StringBuilder(b.length * 3); for (int i = 0; i < b.length; i++) { int k = b[i] & 0xff; if (i != 0) { diff --git a/jdk/src/share/classes/sun/security/provider/PolicyFile.java b/jdk/src/share/classes/sun/security/provider/PolicyFile.java index ec3b54c2dcb..70fae4361fa 100644 --- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java +++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java @@ -1271,7 +1271,7 @@ public class PolicyFile extends java.security.Policy { Boolean imp = AccessController.doPrivileged (new PrivilegedAction() { public Boolean run() { - return new Boolean(entry.getCodeSource().implies(cs)); + return entry.getCodeSource().implies(cs); } }); if (!imp.booleanValue()) { @@ -1856,7 +1856,7 @@ public class PolicyFile extends java.security.Policy { int colonIndex; String prefix = value; String suffix; - if ((colonIndex = value.indexOf(":")) != -1) { + if ((colonIndex = value.indexOf(':')) != -1) { prefix = value.substring(0, colonIndex); } diff --git a/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java b/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java index 40cc25596fa..322726f9c35 100644 --- a/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java +++ b/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java @@ -246,7 +246,7 @@ final class CardImpl extends Card { } checkExclusive(); try { - SCardDisconnect(cardId, (reset ? SCARD_LEAVE_CARD : SCARD_RESET_CARD)); + SCardDisconnect(cardId, (reset ? SCARD_RESET_CARD : SCARD_LEAVE_CARD)); } catch (PCSCException e) { throw new CardException("disconnect() failed", e); } finally { diff --git a/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java b/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java index 46e0678fb0c..7cdffffecf9 100644 --- a/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java @@ -338,7 +338,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { } String sigType; if (keyType.contains("_")) { - int k = keyType.indexOf("_"); + int k = keyType.indexOf('_'); sigType = keyType.substring(k + 1); keyType = keyType.substring(0, k); } else { diff --git a/jdk/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java b/jdk/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java index b6a5034cad8..b817cde7fd7 100644 --- a/jdk/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java @@ -302,7 +302,7 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager final String sigKeyAlgorithm; KeyType(String algorithm) { - int k = algorithm.indexOf("_"); + int k = algorithm.indexOf('_'); if (k == -1) { keyAlgorithm = algorithm; sigKeyAlgorithm = null; diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java index ec2247d81b6..63afd87af31 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java @@ -1560,8 +1560,7 @@ public class Main { first = false; } try { - CertPath cp = certificateFactory.generateCertPath(certs); - validator.validate(cp, pkixParameters); + validateCertChain(certs); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -1871,8 +1870,7 @@ public class Main { printCert("", certChain[0], true, null, true); try { - CertPath cp = certificateFactory.generateCertPath(Arrays.asList(certChain)); - validator.validate(cp, pkixParameters); + validateCertChain(Arrays.asList(certChain)); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -1937,6 +1935,22 @@ public class Main { System.exit(1); } + void validateCertChain(List certs) throws Exception { + int cpLen = 0; + out: for (; cpLen 0) { + CertPath cp = certificateFactory.generateCertPath( + (cpLen == certs.size())? certs: certs.subList(0, cpLen)); + validator.validate(cp, pkixParameters); + } + } + char[] getPass(String prompt) { System.err.print(prompt); diff --git a/jdk/src/share/classes/sun/security/util/HostnameChecker.java b/jdk/src/share/classes/sun/security/util/HostnameChecker.java index 77f17f71a10..1a6f3c2a446 100644 --- a/jdk/src/share/classes/sun/security/util/HostnameChecker.java +++ b/jdk/src/share/classes/sun/security/util/HostnameChecker.java @@ -300,8 +300,8 @@ public class HostnameChecker { template = template.toLowerCase(Locale.ENGLISH); // Retreive leftmost component - int templateIdx = template.indexOf("."); - int nameIdx = name.indexOf("."); + int templateIdx = template.indexOf('.'); + int nameIdx = name.indexOf('.'); if (templateIdx == -1) templateIdx = template.length(); @@ -326,7 +326,7 @@ public class HostnameChecker { */ private static boolean matchWildCards(String name, String template) { - int wildcardIdx = template.indexOf("*"); + int wildcardIdx = template.indexOf('*'); if (wildcardIdx == -1) return name.equals(template); @@ -349,7 +349,7 @@ public class HostnameChecker { // update the match scope name = name.substring(beforeStartIdx + beforeWildcard.length()); - wildcardIdx = afterWildcard.indexOf("*"); + wildcardIdx = afterWildcard.indexOf('*'); } return name.endsWith(afterWildcard); } diff --git a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java index 083e23a3700..5222e8a04c5 100644 --- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java +++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java @@ -98,7 +98,7 @@ public class SignatureFileVerifier { } finally { Providers.stopJarVerification(obj); } - this.name = name.substring(0, name.lastIndexOf(".")) + this.name = name.substring(0, name.lastIndexOf('.')) .toUpperCase(Locale.ENGLISH); this.md = md; this.signerCache = signerCache; diff --git a/jdk/src/share/classes/sun/security/validator/PKIXValidator.java b/jdk/src/share/classes/sun/security/validator/PKIXValidator.java index d11e44e9077..f3e71a793b3 100644 --- a/jdk/src/share/classes/sun/security/validator/PKIXValidator.java +++ b/jdk/src/share/classes/sun/security/validator/PKIXValidator.java @@ -86,12 +86,12 @@ public final class PKIXValidator extends Validator { factory = CertificateFactory.getInstance("X.509"); } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException("Unexpected error: " + e.toString(), e); - } catch (CertificateException e) { - throw new RuntimeException("Internal error", e); - } + } catch (CertificateException e) { + throw new RuntimeException("Internal error", e); + } setDefaultParameters(variant); - plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING); + plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING); trustedSubjects = setTrustedSubjects(); } @@ -107,13 +107,13 @@ public final class PKIXValidator extends Validator { } parameterTemplate = params; - try { - factory = CertificateFactory.getInstance("X.509"); - } catch (CertificateException e) { - throw new RuntimeException("Internal error", e); - } + try { + factory = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + throw new RuntimeException("Internal error", e); + } - plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING); + plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING); trustedSubjects = setTrustedSubjects(); } @@ -133,10 +133,10 @@ public final class PKIXValidator extends Validator { List keys; if (subjectMap.containsKey(dn)) { keys = subjectMap.get(dn); - } else { + } else { keys = new ArrayList(); subjectMap.put(dn, keys); - } + } keys.add(cert.getPublicKey()); } @@ -202,75 +202,74 @@ public final class PKIXValidator extends Validator { pkixParameters.addCertPathChecker(algorithmChecker); } - // check that chain is in correct order and check if chain contains - // trust anchor - X500Principal prevIssuer = null; - for (int i = 0; i < chain.length; i++) { - X509Certificate cert = chain[i]; - X500Principal dn = cert.getSubjectX500Principal(); - if (i != 0 && - !dn.equals(prevIssuer)) { - // chain is not ordered correctly, call builder instead - return doBuild(chain, otherCerts, pkixParameters); - } - - // Check if chain[i] is already trusted. It may be inside - // trustedCerts, or has the same dn and public key as a cert - // inside trustedCerts. The latter happens when a CA has - // updated its cert with a stronger signature algorithm in JRE - // but the weak one is still in circulation. - - if (trustedCerts.contains(cert) || // trusted cert - (trustedSubjects.containsKey(dn) && // replacing ... - trustedSubjects.get(dn).contains( // ... weak cert - cert.getPublicKey()))) { - if (i == 0) { - return new X509Certificate[] {chain[0]}; - } - // Remove and call validator on partial chain [0 .. i-1] - X509Certificate[] newChain = new X509Certificate[i]; - System.arraycopy(chain, 0, newChain, 0, i); - return doValidate(newChain, pkixParameters); - } - prevIssuer = cert.getIssuerX500Principal(); + // check that chain is in correct order and check if chain contains + // trust anchor + X500Principal prevIssuer = null; + for (int i = 0; i < chain.length; i++) { + X509Certificate cert = chain[i]; + X500Principal dn = cert.getSubjectX500Principal(); + if (i != 0 && !dn.equals(prevIssuer)) { + // chain is not ordered correctly, call builder instead + return doBuild(chain, otherCerts, pkixParameters); } - // apparently issued by trust anchor? - X509Certificate last = chain[chain.length - 1]; - X500Principal issuer = last.getIssuerX500Principal(); - X500Principal subject = last.getSubjectX500Principal(); - if (trustedSubjects.containsKey(issuer) && - isSignatureValid(trustedSubjects.get(issuer), last)) { - return doValidate(chain, pkixParameters); - } + // Check if chain[i] is already trusted. It may be inside + // trustedCerts, or has the same dn and public key as a cert + // inside trustedCerts. The latter happens when a CA has + // updated its cert with a stronger signature algorithm in JRE + // but the weak one is still in circulation. - // don't fallback to builder if called from plugin/webstart - if (plugin) { - // Validate chain even if no trust anchor is found. This - // allows plugin/webstart to make sure the chain is - // otherwise valid - if (chain.length > 1) { - X509Certificate[] newChain = - new X509Certificate[chain.length-1]; - System.arraycopy(chain, 0, newChain, 0, newChain.length); - - // temporarily set last cert as sole trust anchor - try { - pkixParameters.setTrustAnchors - (Collections.singleton(new TrustAnchor - (chain[chain.length-1], null))); - } catch (InvalidAlgorithmParameterException iape) { - // should never occur, but ... - throw new CertificateException(iape); - } - doValidate(newChain, pkixParameters); + if (trustedCerts.contains(cert) || // trusted cert + (trustedSubjects.containsKey(dn) && // replacing ... + trustedSubjects.get(dn).contains( // ... weak cert + cert.getPublicKey()))) { + if (i == 0) { + return new X509Certificate[] {chain[0]}; } - // if the rest of the chain is valid, throw exception - // indicating no trust anchor was found - throw new ValidatorException - (ValidatorException.T_NO_TRUST_ANCHOR); + // Remove and call validator on partial chain [0 .. i-1] + X509Certificate[] newChain = new X509Certificate[i]; + System.arraycopy(chain, 0, newChain, 0, i); + return doValidate(newChain, pkixParameters); } - // otherwise, fall back to builder + prevIssuer = cert.getIssuerX500Principal(); + } + + // apparently issued by trust anchor? + X509Certificate last = chain[chain.length - 1]; + X500Principal issuer = last.getIssuerX500Principal(); + X500Principal subject = last.getSubjectX500Principal(); + if (trustedSubjects.containsKey(issuer) && + isSignatureValid(trustedSubjects.get(issuer), last)) { + return doValidate(chain, pkixParameters); + } + + // don't fallback to builder if called from plugin/webstart + if (plugin) { + // Validate chain even if no trust anchor is found. This + // allows plugin/webstart to make sure the chain is + // otherwise valid + if (chain.length > 1) { + X509Certificate[] newChain = + new X509Certificate[chain.length-1]; + System.arraycopy(chain, 0, newChain, 0, newChain.length); + + // temporarily set last cert as sole trust anchor + try { + pkixParameters.setTrustAnchors + (Collections.singleton(new TrustAnchor + (chain[chain.length-1], null))); + } catch (InvalidAlgorithmParameterException iape) { + // should never occur, but ... + throw new CertificateException(iape); + } + doValidate(newChain, pkixParameters); + } + // if the rest of the chain is valid, throw exception + // indicating no trust anchor was found + throw new ValidatorException + (ValidatorException.T_NO_TRUST_ANCHOR); + } + // otherwise, fall back to builder return doBuild(chain, otherCerts, pkixParameters); } diff --git a/jdk/src/share/classes/sun/security/x509/CRLExtensions.java b/jdk/src/share/classes/sun/security/x509/CRLExtensions.java index 628e1125add..834f78fa642 100644 --- a/jdk/src/share/classes/sun/security/x509/CRLExtensions.java +++ b/jdk/src/share/classes/sun/security/x509/CRLExtensions.java @@ -185,7 +185,7 @@ public class CRLExtensions { String name; String id = attr.getPrefix(); if (id.equalsIgnoreCase(X509CertImpl.NAME)) { // fully qualified - int index = alias.lastIndexOf("."); + int index = alias.lastIndexOf('.'); name = alias.substring(index + 1); } else name = alias; diff --git a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java index 3198fd6cd6a..70125a07b2d 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java +++ b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java @@ -325,7 +325,7 @@ public class ConnectDialog extends InternalDialog } else { String host = remoteTF.getText().trim(); String port = "0"; - int index = host.lastIndexOf(":"); + int index = host.lastIndexOf(':'); if (index >= 0) { port = host.substring(index + 1); host = host.substring(0, index); diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java index ebdda0bbdbc..eb1f6b1be80 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java @@ -210,7 +210,7 @@ public class Utils { public static String getArrayClassName(String name) { String className = null; if (name.startsWith("[")) { - int index = name.lastIndexOf("["); + int index = name.lastIndexOf('['); className = name.substring(index, name.length()); if (className.startsWith("[L")) { className = className.substring(2, className.length() - 1); @@ -241,7 +241,7 @@ public class Utils { if (className == null) { return name; } - int index = name.lastIndexOf("["); + int index = name.lastIndexOf('['); StringBuilder brackets = new StringBuilder(className); for (int i = 0; i <= index; i++) { brackets.append("[]"); diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java index c29be4b9f0e..45538a28bc3 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java @@ -113,7 +113,7 @@ public abstract class XOperations extends JPanel implements ActionListener { if (methodLabel.getText().length() > 20) { methodLabel.setText(methodLabel.getText(). substring(methodLabel.getText(). - lastIndexOf(".") + 1, + lastIndexOf('.') + 1, methodLabel.getText().length())); } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java index 26d968fa506..ed5658cc9ae 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java @@ -475,7 +475,7 @@ public class XTree extends JTree { private static Map extractKeyValuePairs( String props, ObjectName mbean) { Map map = new LinkedHashMap(); - int eq = props.indexOf("="); + int eq = props.indexOf('='); while (eq != -1) { String key = props.substring(0, eq); String value = mbean.getKeyProperty(key); @@ -484,7 +484,7 @@ public class XTree extends JTree { if (props.startsWith(",")) { props = props.substring(1); } - eq = props.indexOf("="); + eq = props.indexOf('='); } return map; } @@ -821,7 +821,7 @@ public class XTree extends JTree { } private void buildKeyValue() { - int index = tokenValue.indexOf("="); + int index = tokenValue.indexOf('='); if (index < 0) { key = tokenValue; value = tokenValue; diff --git a/jdk/src/share/classes/sun/tools/serialver/resources/serialver_ja.properties b/jdk/src/share/classes/sun/tools/serialver/resources/serialver_ja.properties index 0feef1009ce..e468e9c9d65 100644 --- a/jdk/src/share/classes/sun/tools/serialver/resources/serialver_ja.properties +++ b/jdk/src/share/classes/sun/tools/serialver/resources/serialver_ja.properties @@ -1,13 +1,6 @@ -SerialVersionInspector=\u30B7\u30EA\u30A2\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u30FB\u30A4\u30F3\u30B9\u30DA\u30AF\u30BF -File=\u30D5\u30A1\u30A4\u30EB -Exit=\u7D42\u4E86 -Show=\u8868\u793A -FullClassName=\u5B8C\u5168\u30AF\u30E9\u30B9\u540D: -SerialVersion=\u30B7\u30EA\u30A2\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3: NotSerializable=\u30AF\u30E9\u30B9{0}\u306F\u76F4\u5217\u5316\u3067\u304D\u307E\u305B\u3093\u3002 ClassNotFound=\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002 error.parsing.classpath=\u30AF\u30E9\u30B9\u30D1\u30B9{0}\u306E\u89E3\u6790\u30A8\u30E9\u30FC\u3067\u3059\u3002 error.missing.classpath=-classpath\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 invalid.flag=\u7121\u52B9\u306A\u30D5\u30E9\u30B0{0}\u3002 -ignoring.classes=-show\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6301\u3064\u30AF\u30E9\u30B9\u5F15\u6570\u3092\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093 -usage=\u4F7F\u7528\u65B9\u6CD5: serialver [-classpath classpath] [-show] [classname...] +usage=\u4F7F\u7528\u65B9\u6CD5: serialver [-classpath classpath] [classname...] diff --git a/jdk/src/share/classes/sun/tools/serialver/resources/serialver_zh_CN.properties b/jdk/src/share/classes/sun/tools/serialver/resources/serialver_zh_CN.properties index 526a1e3bb98..87a6eb7fa53 100644 --- a/jdk/src/share/classes/sun/tools/serialver/resources/serialver_zh_CN.properties +++ b/jdk/src/share/classes/sun/tools/serialver/resources/serialver_zh_CN.properties @@ -1,13 +1,6 @@ -SerialVersionInspector=\u5E8F\u5217\u7248\u672C\u68C0\u67E5\u5668 -File=\u6587\u4EF6 -Exit=\u9000\u51FA -Show=\u663E\u793A -FullClassName=\u5B8C\u6574\u7684\u7C7B\u540D: -SerialVersion=\u5E8F\u5217\u7248\u672C: NotSerializable=\u7C7B{0}\u65E0\u6CD5\u5E8F\u5217\u5316\u3002 ClassNotFound=\u627E\u4E0D\u5230\u7C7B{0}\u3002 error.parsing.classpath=\u89E3\u6790\u7C7B\u8DEF\u5F84 {0} \u65F6\u51FA\u9519\u3002 error.missing.classpath=\u7F3A\u5C11 -classpath \u9009\u9879\u7684\u53C2\u6570 invalid.flag=\u65E0\u6548\u6807\u8BB0{0}\u3002 -ignoring.classes=\u65E0\u6CD5\u4F7F\u7528 -show \u9009\u9879\u6307\u5B9A\u7C7B\u53C2\u6570 -usage=\u7528\u6CD5: serialver [-classpath \u7C7B\u8DEF\u5F84] [-show] [\u7C7B\u540D\u79F0...] +usage=\u7528\u6CD5: serialver [-classpath \u7C7B\u8DEF\u5F84] [\u7C7B\u540D\u79F0...] diff --git a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg index 74096efea5f..c120c5e3242 100644 --- a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg +++ b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg @@ -18,18 +18,5 @@ attributes = compatibility disabledMechanisms = { CKM_DSA_KEY_PAIR_GEN -# the following mechanisms are disabled due to performance issues -# (Solaris bug 6337157) - CKM_DSA_SHA1 - CKM_MD5_RSA_PKCS - CKM_SHA1_RSA_PKCS - CKM_SHA256_RSA_PKCS - CKM_SHA384_RSA_PKCS - CKM_SHA512_RSA_PKCS -# the following mechanisms are disabled to ensure backward compatibility -# (Solaris bug 6545046) - CKM_DES_CBC_PAD - CKM_DES3_CBC_PAD - CKM_AES_CBC_PAD } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/ChangeLog b/jdk/src/share/native/java/util/zip/zlib-1.2.8/ChangeLog similarity index 81% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/ChangeLog rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/ChangeLog index f310bb0fcdb..f22aabaef53 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/ChangeLog +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/ChangeLog @@ -1,12 +1,276 @@ ChangeLog file for zlib +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Ro§] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix unintialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Suport i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no libary use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminancy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assmebler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + Changes in 1.2.5 (19 Apr 2010) - Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] - Default to libdir as sharedlibdir in configure [Nieder] - Update copyright dates on modified source files - Update trees.c to be able to generate modified trees.h - Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] Changes in 1.2.4.5 (18 Apr 2010) - Set sharedlibdir in configure [Torok] @@ -261,7 +525,7 @@ Changes in 1.2.3.4 (21 Dec 2009) - Clear bytes after deflate lookahead to avoid use of uninitialized data - Change a limit in inftrees.c to be more transparent to Coverity Prevent - Update win32/zlib.def with exported symbols from zlib.h -- Correct spelling error in zlib.h [Willem] +- Correct spelling errors in zlib.h [Willem, Sobrado] - Allow Z_BLOCK for deflate() to force a new block - Allow negative bits in inflatePrime() to delete existing bit buffer - Add Z_TREES flush option to inflate() to return at end of trees diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/README b/jdk/src/share/native/java/util/zip/zlib-1.2.8/README similarity index 87% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/README rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/README index d4219bf889f..5ca9d127eda 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/README +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/README @@ -1,22 +1,22 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.5 is a general purpose data compression library. All the code is +zlib 1.2.8 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). All functions of the compression library are documented in the file zlib.h (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The -compression library itself is composed of all source files except example.c and -minigzip.c. +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. To compile all files and run the test program, follow the instructions given at the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use one -of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use make_vms.com. Questions about zlib should be sent to , or to Gilles Vollant @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.5 are documented in the file ChangeLog. +The changes made in version 1.2.8 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -44,7 +44,7 @@ http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html . +http://docs.python.org/library/zlib.html . zlib is built into tcl: http://wiki.tcl.tk/4610 . @@ -84,7 +84,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2010 Jean-loup Gailly and Mark Adler + (C) 1995-2013 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/compress.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/compress.c similarity index 98% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/compress.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/compress.c index 9d8713f9446..cdc51e08172 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/compress.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/compress.c @@ -53,7 +53,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K /* Check for source > 64K on 16-bit machine: */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/crc32.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/crc32.h similarity index 99% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/crc32.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/crc32.h index 2383bdc847d..94df2aaf287 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/crc32.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/crc32.h @@ -26,7 +26,7 @@ * Generated automatically by crc32.c */ -local const unsigned long FAR crc_table[TBLS][256] = +local const z_crc_t FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/deflate.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/deflate.c similarity index 91% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/deflate.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/deflate.c index 1dce5b0d055..5cc66c5e537 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/deflate.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/deflate.c @@ -23,7 +23,7 @@ */ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -61,7 +61,7 @@ * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt + * Available in http://tools.ietf.org/html/rfc1951 * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. @@ -76,7 +76,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -179,6 +179,9 @@ local const config configuration_table[10] = { struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive @@ -259,10 +262,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, strm->msg = Z_NULL; if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; +#endif } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif #ifdef FASTEST if (level != 0) level = 1; @@ -317,7 +329,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + strm->msg = ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } @@ -338,43 +350,70 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) uInt dictLength; { deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) return Z_STREAM_ERROR; - s = strm->state; - if (s->wrap) + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - if (length < MIN_MATCH) return Z_OK; - if (length > s->w_size) { - length = s->w_size; - dictionary += dictLength - length; /* use the tail of the dictionary */ + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); } - if (hash_head) hash_head = 0; /* to make compiler happy */ + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; return Z_OK; } /* ========================================================================= */ -int ZEXPORT deflateReset (strm) +int ZEXPORT deflateResetKeep (strm) z_streamp strm; { deflate_state *s; @@ -404,11 +443,22 @@ int ZEXPORT deflateReset (strm) s->last_flush = Z_NO_FLUSH; _tr_init(s); - lm_init(s); return Z_OK; } +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + /* ========================================================================= */ int ZEXPORT deflateSetHeader (strm, head) z_streamp strm; @@ -420,15 +470,43 @@ int ZEXPORT deflateSetHeader (strm, head) return Z_OK; } +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + /* ========================================================================= */ int ZEXPORT deflatePrime (strm, bits, value) z_streamp strm; int bits; int value; { + deflate_state *s; + int put; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); return Z_OK; } @@ -459,6 +537,8 @@ int ZEXPORT deflateParams(strm, level, strategy) strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_BLOCK); + if (err == Z_BUF_ERROR && s->pending == 0) + err = Z_OK; } if (s->level != level) { s->level = level; @@ -586,19 +666,22 @@ local void putShortMSB (s, b) local void flush_pending(strm) z_streamp strm; { - unsigned len = strm->state->pending; + unsigned len; + deflate_state *s = strm->state; + _tr_flush_bits(s); + len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; - zmemcpy(strm->next_out, strm->state->pending_out, len); + zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; - strm->state->pending_out += len; + s->pending_out += len; strm->total_out += len; strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; } } @@ -825,7 +908,7 @@ int ZEXPORT deflate (strm, flush) * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ - } else if (strm->avail_in == 0 && flush <= old_flush && + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } @@ -874,6 +957,7 @@ int ZEXPORT deflate (strm, flush) if (s->lookahead == 0) { s->strstart = 0; s->block_start = 0L; + s->insert = 0; } } } @@ -969,12 +1053,12 @@ int ZEXPORT deflateCopy (dest, source) ss = source->state; - zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); @@ -990,8 +1074,8 @@ int ZEXPORT deflateCopy (dest, source) } /* following zmemcpy do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); @@ -1025,15 +1109,15 @@ local int read_buf(strm, buf, size) strm->avail_in -= len; + zmemcpy(buf, strm->next_in, len); if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); + strm->adler = adler32(strm->adler, buf, len); } #ifdef GZIP else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); + strm->adler = crc32(strm->adler, buf, len); } #endif - zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; @@ -1060,6 +1144,7 @@ local void lm_init (s) s->strstart = 0; s->block_start = 0L; s->lookahead = 0; + s->insert = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; @@ -1334,6 +1419,8 @@ local void fill_window(s) unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); @@ -1386,7 +1473,7 @@ local void fill_window(s) #endif more += wsize; } - if (s->strm->avail_in == 0) return; + if (s->strm->avail_in == 0) break; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && @@ -1405,12 +1492,24 @@ local void fill_window(s) s->lookahead += n; /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. @@ -1451,6 +1550,9 @@ local void fill_window(s) s->high_water += init; } } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); } /* =========================================================================== @@ -1530,8 +1632,14 @@ local block_state deflate_stored(s, flush) FLUSH_BLOCK(s, 0); } } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; } /* =========================================================================== @@ -1627,8 +1735,14 @@ local block_state deflate_fast(s, flush) } if (bflush) FLUSH_BLOCK(s, 0); } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } #ifndef FASTEST @@ -1752,8 +1866,14 @@ local block_state deflate_slow(s, flush) _tr_tally_lit(s, s->window[s->strstart-1], bflush); s->match_available = 0; } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } #endif /* FASTEST */ @@ -1773,11 +1893,11 @@ local block_state deflate_rle(s, flush) for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. + * for the longest run, plus one for the unrolled loop. */ - if (s->lookahead < MAX_MATCH) { + if (s->lookahead <= MAX_MATCH) { fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ @@ -1800,6 +1920,7 @@ local block_state deflate_rle(s, flush) if (s->match_length > s->lookahead) s->match_length = s->lookahead; } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ @@ -1820,8 +1941,14 @@ local block_state deflate_rle(s, flush) } if (bflush) FLUSH_BLOCK(s, 0); } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } /* =========================================================================== @@ -1853,6 +1980,12 @@ local block_state deflate_huff(s, flush) s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/deflate.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/deflate.h similarity index 97% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/deflate.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/deflate.h index 652be480efd..8be47fa013b 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/deflate.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/deflate.h @@ -23,7 +23,7 @@ */ /* deflate.h -- internal compression state - * Copyright (C) 1995-2010 Jean-loup Gailly + * Copyright (C) 1995-2012 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -72,6 +72,9 @@ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + #define INIT_STATE 42 #define EXTRA_STATE 69 #define NAME_STATE 73 @@ -125,7 +128,7 @@ typedef struct internal_state { int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ + Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ @@ -212,7 +215,7 @@ typedef struct internal_state { int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ + /* Didn't use ct_data typedef below to suppress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ @@ -268,7 +271,7 @@ typedef struct internal_state { ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ + uInt insert; /* bytes at end of window left to insert */ #ifdef DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ @@ -318,6 +321,7 @@ void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzclose.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzclose.c similarity index 100% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/gzclose.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/gzclose.c diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzguts.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzguts.h similarity index 68% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/gzguts.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/gzguts.h index d8fbf1e4c4b..5889f45c784 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzguts.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzguts.h @@ -23,7 +23,7 @@ */ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -36,7 +36,7 @@ # endif #endif -#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +#ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL @@ -51,13 +51,80 @@ #endif #include +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + #ifdef NO_DEFLATE /* for compatibility with old definition */ # define NO_GZCOMPRESS #endif +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ #ifdef _MSC_VER -# include -# define vsnprintf _vsnprintf +# define snprintf _snprintf #endif #ifndef local @@ -76,7 +143,7 @@ # include # define zstrerror() gz_strwinerror((DWORD)GetLastError()) #else -# ifdef STDC +# ifndef NO_STRERROR # include # define zstrerror() strerror(errno) # else @@ -92,7 +159,15 @@ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); #endif -/* default i/o buffer size -- double this for output when reading */ +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ #define GZBUFSIZE 8192 /* gzip modes, also provide a little integrity check on the passed structure */ @@ -108,23 +183,25 @@ /* internal gzip file state data structure */ typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ /* used for both reading and writing */ int mode; /* see gzip modes above */ int fd; /* file descriptor */ char *path; /* path or fd for error messages */ - z_off64_t pos; /* current position in uncompressed data */ unsigned size; /* buffer size, zero if not allocated yet */ unsigned want; /* requested buffer size, default is GZBUFSIZE */ unsigned char *in; /* input buffer */ unsigned char *out; /* output buffer (double-sized when reading) */ - unsigned char *next; /* next output data to deliver or write */ + int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ - unsigned have; /* amount of output data unused at next */ - int eof; /* true if end of input file reached */ - z_off64_t start; /* where the gzip data started, for rewinding */ - z_off64_t raw; /* where the raw data started, for seeking */ int how; /* 0: get header, 1: copy, 2: decompress */ - int direct; /* true if last read direct, false if gzip */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ /* just for writing */ int level; /* compression level */ int strategy; /* compression strategy */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzlib.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzlib.c similarity index 74% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/gzlib.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/gzlib.c index 9a3db2efe0c..4dce9b96ef7 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzlib.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzlib.c @@ -22,22 +22,26 @@ * questions. */ -/* - * Copyright (C) 2004, 2010 Mark Adler +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 # define LSEEK lseek64 #else # define LSEEK lseek #endif +#endif /* Local functions */ local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const char *, int, const char *)); +local gzFile gz_open OF((const void *, int, const char *)); #if defined UNDER_CE @@ -95,28 +99,40 @@ char ZLIB_INTERNAL *gz_strwinerror (error) local void gz_reset(state) gz_statep state; { + state->x.have = 0; /* no output data available */ if (state->mode == GZ_READ) { /* for reading ... */ - state->have = 0; /* no output data available */ state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ state->how = LOOK; /* look for gzip header */ - state->direct = 1; /* default for empty file */ } state->seek = 0; /* no seek request pending */ gz_error(state, Z_OK, NULL); /* clear error */ - state->pos = 0; /* no uncompressed data yet */ + state->x.pos = 0; /* no uncompressed data yet */ state->strm.avail_in = 0; /* no input data yet */ } /* Open a gzip file either by name or file descriptor. */ local gzFile gz_open(path, fd, mode) - const char *path; + const void *path; int fd; const char *mode; { gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; /* allocate gzFile structure to return */ - state = malloc(sizeof(gz_state)); + state = (gz_statep)malloc(sizeof(gz_state)); if (state == NULL) return NULL; state->size = 0; /* no buffers allocated yet */ @@ -127,6 +143,7 @@ local gzFile gz_open(path, fd, mode) state->mode = GZ_NONE; state->level = Z_DEFAULT_COMPRESSION; state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; while (*mode) { if (*mode >= '0' && *mode <= '9') state->level = *mode - '0'; @@ -148,6 +165,16 @@ local gzFile gz_open(path, fd, mode) return NULL; case 'b': /* ignore -- will request binary anyway */ break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif case 'f': state->strategy = Z_FILTERED; break; @@ -159,6 +186,10 @@ local gzFile gz_open(path, fd, mode) break; case 'F': state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; default: /* could consider as an error, but just ignore */ ; } @@ -171,30 +202,71 @@ local gzFile gz_open(path, fd, mode) return NULL; } + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + /* save the path name for error messages */ - state->path = malloc(strlen(path) + 1); +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); if (state->path == NULL) { free(state); return NULL; } - strcpy(state->path, path); +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif - /* open the file with the appropriate mode (or just use fd) */ - state->fd = fd != -1 ? fd : - open(path, + /* compute the flags for open() */ + oflag = #ifdef O_LARGEFILE - O_LARGEFILE | + O_LARGEFILE | #endif #ifdef O_BINARY - O_BINARY | + O_BINARY | #endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | ( - state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))), - 0666); +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); if (state->fd == -1) { free(state->path); free(state); @@ -240,14 +312,28 @@ gzFile ZEXPORT gzdopen(fd, mode) char *path; /* identifier for error messages */ gzFile gz; - if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ +#else sprintf(path, "", fd); /* for debugging */ +#endif gz = gz_open(path, fd, mode); free(path); return gz; } +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + /* -- see zlib.h -- */ int ZEXPORT gzbuffer(file, size) gzFile file; @@ -267,8 +353,8 @@ int ZEXPORT gzbuffer(file, size) return -1; /* check and set requested size */ - if (size == 0) - return -1; + if (size < 2) + size = 2; /* need two bytes to check magic header */ state->want = size; return 0; } @@ -285,7 +371,8 @@ int ZEXPORT gzrewind(file) state = (gz_statep)file; /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* back up and start over */ @@ -313,7 +400,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) return -1; /* check that there's no error */ - if (state->err != Z_OK) + if (state->err != Z_OK && state->err != Z_BUF_ERROR) return -1; /* can only seek from start or relative to current position */ @@ -322,31 +409,32 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) /* normalize offset to a SEEK_CUR specification */ if (whence == SEEK_SET) - offset -= state->pos; + offset -= state->x.pos; else if (state->seek) offset += state->skip; state->seek = 0; /* if within raw area while reading, just go there */ if (state->mode == GZ_READ && state->how == COPY && - state->pos + offset >= state->raw) { - ret = LSEEK(state->fd, offset - state->have, SEEK_CUR); + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); if (ret == -1) return -1; - state->have = 0; + state->x.have = 0; state->eof = 0; + state->past = 0; state->seek = 0; gz_error(state, Z_OK, NULL); state->strm.avail_in = 0; - state->pos += offset; - return state->pos; + state->x.pos += offset; + return state->x.pos; } /* calculate skip amount, rewinding if needed for back seek when reading */ if (offset < 0) { if (state->mode != GZ_READ) /* writing -- can't go backwards */ return -1; - offset += state->pos; + offset += state->x.pos; if (offset < 0) /* before start of file! */ return -1; if (gzrewind(file) == -1) /* rewind, then skip to offset */ @@ -355,11 +443,11 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) /* if reading, skip what's in output buffer (one less gzgetc() check) */ if (state->mode == GZ_READ) { - n = GT_OFF(state->have) || (z_off64_t)state->have > offset ? - (unsigned)offset : state->have; - state->have -= n; - state->next += n; - state->pos += n; + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; offset -= n; } @@ -368,7 +456,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) state->seek = 1; state->skip = offset; } - return state->pos + offset; + return state->x.pos + offset; } /* -- see zlib.h -- */ @@ -397,7 +485,7 @@ z_off64_t ZEXPORT gztell64(file) return -1; /* return position */ - return state->pos + (state->seek ? state->skip : 0); + return state->x.pos + (state->seek ? state->skip : 0); } /* -- see zlib.h -- */ @@ -457,8 +545,7 @@ int ZEXPORT gzeof(file) return 0; /* return end-of-file state */ - return state->mode == GZ_READ ? - (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; + return state->mode == GZ_READ ? state->past : 0; } /* -- see zlib.h -- */ @@ -478,7 +565,8 @@ const char * ZEXPORT gzerror(file, errnum) /* return error information */ if (errnum != NULL) *errnum = state->err; - return state->msg == NULL ? "" : state->msg; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); } /* -- see zlib.h -- */ @@ -495,8 +583,10 @@ void ZEXPORT gzclearerr(file) return; /* clear error and end-of-file */ - if (state->mode == GZ_READ) + if (state->mode == GZ_READ) { state->eof = 0; + state->past = 0; + } gz_error(state, Z_OK, NULL); } @@ -518,26 +608,33 @@ void ZLIB_INTERNAL gz_error(state, err, msg) state->msg = NULL; } + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + /* set error code, and if no message, then done */ state->err = err; if (msg == NULL) return; - /* for an out of memory error, save as static string */ - if (err == Z_MEM_ERROR) { - state->msg = (char *)msg; + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) return; - } /* construct error message with path */ - if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { state->err = Z_MEM_ERROR; - state->msg = (char *)"out of memory"; return; } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else strcpy(state->msg, state->path); strcat(state->msg, ": "); strcat(state->msg, msg); +#endif return; } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzread.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzread.c similarity index 54% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/gzread.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/gzread.c index 15e85028cfd..cd87098b95a 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzread.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzread.c @@ -23,7 +23,7 @@ */ /* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -32,10 +32,9 @@ /* Local functions */ local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); local int gz_avail OF((gz_statep)); -local int gz_next4 OF((gz_statep, unsigned long *)); -local int gz_head OF((gz_statep)); +local int gz_look OF((gz_statep)); local int gz_decomp OF((gz_statep)); -local int gz_make OF((gz_statep)); +local int gz_fetch OF((gz_statep)); local int gz_skip OF((gz_statep, z_off64_t)); /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from @@ -70,73 +69,54 @@ local int gz_load(state, buf, len, have) error, 0 otherwise. Note that the eof flag is set when the end of the input file is reached, even though there may be unused data in the buffer. Once that data has been used, no more attempts will be made to read the file. - gz_avail() assumes that strm->avail_in == 0. */ + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ local int gz_avail(state) gz_statep state; { + unsigned got; z_streamp strm = &(state->strm); - if (state->err != Z_OK) + if (state->err != Z_OK && state->err != Z_BUF_ERROR) return -1; if (state->eof == 0) { - if (gz_load(state, state->in, state->size, - (unsigned *)&(strm->avail_in)) == -1) + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) return -1; + strm->avail_in += got; strm->next_in = state->in; } return 0; } -/* Get next byte from input, or -1 if end or error. */ -#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ - (strm->avail_in == 0 ? -1 : \ - (strm->avail_in--, *(strm->next_in)++))) - -/* Get a four-byte little-endian integer and return 0 on success and the value - in *ret. Otherwise -1 is returned and *ret is not modified. */ -local int gz_next4(state, ret) - gz_statep state; - unsigned long *ret; -{ - int ch; - unsigned long val; - z_streamp strm = &(state->strm); - - val = NEXT(); - val += (unsigned)NEXT() << 8; - val += (unsigned long)NEXT() << 16; - ch = NEXT(); - if (ch == -1) - return -1; - val += (unsigned long)ch << 24; - *ret = val; - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->have must be zero. +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. If this is the first time in, allocate required memory. state->how will be left unchanged if there is no more input data available, will be set to COPY if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression, and the gzip header will be skipped so - that the next available input data is the raw deflate stream. If direct - copying, then leftover input data from the input buffer will be copied to - the output buffer. In that case, all further file reads will be directly to - either the output buffer or a user buffer. If decompressing, the inflate - state and the check value will be initialized. gz_head() will return 0 on - success or -1 on failure. Failures may include read errors or gzip header - errors. */ -local int gz_head(state) + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) gz_statep state; { z_streamp strm = &(state->strm); - int flags; - unsigned len; /* allocate read buffers and inflate memory */ if (state->size == 0) { /* allocate buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want << 1); + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); if (state->in == NULL || state->out == NULL) { if (state->out != NULL) free(state->out); @@ -153,7 +133,7 @@ local int gz_head(state) state->strm.opaque = Z_NULL; state->strm.avail_in = 0; state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ free(state->out); free(state->in); state->size = 0; @@ -162,83 +142,45 @@ local int gz_head(state) } } - /* get some data in the input buffer */ - if (strm->avail_in == 0) { + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { if (gz_avail(state) == -1) return -1; if (strm->avail_in == 0) return 0; } - /* look for the gzip magic header bytes 31 and 139 */ - if (strm->next_in[0] == 31) { - strm->avail_in--; - strm->next_in++; - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in && strm->next_in[0] == 139) { - /* we have a gzip header, woo hoo! */ - strm->avail_in--; - strm->next_in++; - - /* skip rest of header */ - if (NEXT() != 8) { /* compression method */ - gz_error(state, Z_DATA_ERROR, "unknown compression method"); - return -1; - } - flags = NEXT(); - if (flags & 0xe0) { /* reserved flag bits */ - gz_error(state, Z_DATA_ERROR, "unknown header flags set"); - return -1; - } - NEXT(); /* modification time */ - NEXT(); - NEXT(); - NEXT(); - NEXT(); /* extra flags */ - NEXT(); /* operating system */ - if (flags & 4) { /* extra field */ - len = (unsigned)NEXT(); - len += (unsigned)NEXT() << 8; - while (len--) - if (NEXT() < 0) - break; - } - if (flags & 8) /* file name */ - while (NEXT() > 0) - ; - if (flags & 16) /* comment */ - while (NEXT() > 0) - ; - if (flags & 2) { /* header crc */ - NEXT(); - NEXT(); - } - /* an unexpected end of file is not checked for here -- it will be - noticed on the first request for uncompressed data */ - - /* set up for decompression */ - inflateReset(strm); - strm->adler = crc32(0L, Z_NULL, 0); - state->how = GZIP; - state->direct = 0; - return 0; - } - else { - /* not a gzip file -- save first byte (31) and fall to raw i/o */ - state->out[0] = 31; - state->have = 1; - } + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; } - /* doing raw i/o, save start of raw data for seeking, copy any leftover - input to output -- this assumes that the output buffer is larger than - the input buffer, which also assures space for gzungetc() */ - state->raw = state->pos; - state->next = state->out; + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; if (strm->avail_in) { - memcpy(state->next + state->have, strm->next_in, strm->avail_in); - state->have += strm->avail_in; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; strm->avail_in = 0; } state->how = COPY; @@ -247,19 +189,15 @@ local int gz_head(state) } /* Decompress from input to the provided next_out and avail_out in the state. - If the end of the compressed data is reached, then verify the gzip trailer - check value and length (modulo 2^32). state->have and state->next are set - to point to the just decompressed data, and the crc is updated. If the - trailer is verified, state->how is reset to LOOK to look for the next gzip - stream or raw data, once state->have is depleted. Returns 0 on success, -1 - on failure. Failures may include invalid compressed data or a failed gzip - trailer verification. */ + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ local int gz_decomp(state) gz_statep state; { - int ret; + int ret = Z_OK; unsigned had; - unsigned long crc, len; z_streamp strm = &(state->strm); /* fill output buffer up to end of deflate stream */ @@ -269,15 +207,15 @@ local int gz_decomp(state) if (strm->avail_in == 0 && gz_avail(state) == -1) return -1; if (strm->avail_in == 0) { - gz_error(state, Z_DATA_ERROR, "unexpected end of file"); - return -1; + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; } /* decompress and handle errors */ ret = inflate(strm, Z_NO_FLUSH); if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); + "internal error: inflate stream corrupt"); return -1; } if (ret == Z_MEM_ERROR) { @@ -286,67 +224,55 @@ local int gz_decomp(state) } if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); + strm->msg == NULL ? "compressed data error" : strm->msg); return -1; } } while (strm->avail_out && ret != Z_STREAM_END); - /* update available output and crc check value */ - state->have = had - strm->avail_out; - state->next = strm->next_out - state->have; - strm->adler = crc32(strm->adler, state->next, state->have); + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; - /* check gzip trailer if at end of deflate stream */ - if (ret == Z_STREAM_END) { - if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { - gz_error(state, Z_DATA_ERROR, "unexpected end of file"); - return -1; - } - if (crc != strm->adler) { - gz_error(state, Z_DATA_ERROR, "incorrect data check"); - return -1; - } - if (len != (strm->total_out & 0xffffffffL)) { - gz_error(state, Z_DATA_ERROR, "incorrect length check"); - return -1; - } - state->how = LOOK; /* ready for next stream, once have is 0 (leave - state->direct unchanged to remember how) */ - } + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; /* good decompression */ return 0; } -/* Make data and put in the output buffer. Assumes that state->have == 0. +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. Data is either copied from the input file or decompressed from the input file depending on state->how. If state->how is LOOK, then a gzip header is - looked for (and skipped if found) to determine wither to copy or decompress. - Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY - or GZIP unless the end of the input file has been reached and all data has - been processed. */ -local int gz_make(state) + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) gz_statep state; { z_streamp strm = &(state->strm); - if (state->how == LOOK) { /* look for gzip header */ - if (gz_head(state) == -1) - return -1; - if (state->have) /* got some data from gz_head() */ + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; return 0; - } - if (state->how == COPY) { /* straight copy */ - if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) - return -1; - state->next = state->out; - } - else if (state->how == GZIP) { /* decompress */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); return 0; } @@ -360,12 +286,12 @@ local int gz_skip(state, len) /* skip over len bytes or reach end-of-file, whichever comes first */ while (len) /* skip over whatever is in output buffer */ - if (state->have) { - n = GT_OFF(state->have) || (z_off64_t)state->have > len ? - (unsigned)len : state->have; - state->have -= n; - state->next += n; - state->pos += n; + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; len -= n; } @@ -376,7 +302,7 @@ local int gz_skip(state, len) /* need more data to skip -- load up output buffer */ else { /* get more output, looking for header if required */ - if (gz_make(state) == -1) + if (gz_fetch(state) == -1) return -1; } return 0; @@ -398,14 +324,15 @@ int ZEXPORT gzread(file, buf, len) state = (gz_statep)file; strm = &(state->strm); - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ if ((int)len < 0) { - gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); return -1; } @@ -424,49 +351,51 @@ int ZEXPORT gzread(file, buf, len) got = 0; do { /* first just try copying data from the output buffer */ - if (state->have) { - n = state->have > len ? len : state->have; - memcpy(buf, state->next, n); - state->next += n; - state->have -= n; + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ break; + } /* need output data -- for small len or new stream load up our output buffer */ else if (state->how == LOOK || len < (state->size << 1)) { /* get more output, looking for header if required */ - if (gz_make(state) == -1) + if (gz_fetch(state) == -1) return -1; - continue; /* no progress yet -- go back to memcpy() above */ + continue; /* no progress yet -- go back to copy above */ /* the copy above assures that we will leave with space in the output buffer, allowing at least one gzungetc() to succeed */ } /* large len -- read directly into user buffer */ else if (state->how == COPY) { /* read directly */ - if (gz_load(state, buf, len, &n) == -1) + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) return -1; } /* large len -- decompress directly into user buffer */ else { /* state->how == GZIP */ strm->avail_out = len; - strm->next_out = buf; + strm->next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) return -1; - n = state->have; - state->have = 0; + n = state->x.have; + state->x.have = 0; } /* update progress */ len -= n; buf = (char *)buf + n; got += n; - state->pos += n; + state->x.pos += n; } while (len); /* return number of bytes read into user buffer (will fit in int) */ @@ -474,6 +403,11 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif int ZEXPORT gzgetc(file) gzFile file; { @@ -486,15 +420,16 @@ int ZEXPORT gzgetc(file) return -1; state = (gz_statep)file; - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* try output buffer (no need to check for skip request) */ - if (state->have) { - state->have--; - state->pos++; - return *(state->next)++; + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; } /* nothing there -- try gzread() */ @@ -502,6 +437,12 @@ int ZEXPORT gzgetc(file) return ret < 1 ? -1 : buf[0]; } +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + /* -- see zlib.h -- */ int ZEXPORT gzungetc(c, file) int c; @@ -514,8 +455,9 @@ int ZEXPORT gzungetc(c, file) return -1; state = (gz_statep)file; - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* process a skip request */ @@ -530,32 +472,34 @@ int ZEXPORT gzungetc(c, file) return -1; /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->have == 0) { - state->have = 1; - state->next = state->out + (state->size << 1) - 1; - state->next[0] = c; - state->pos--; + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; return c; } /* if no room, give up (must have already done a gzungetc()) */ - if (state->have == (state->size << 1)) { - gz_error(state, Z_BUF_ERROR, "out of room to push characters"); + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); return -1; } /* slide output data if needed and insert byte before existing data */ - if (state->next == state->out) { - unsigned char *src = state->out + state->have; + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; unsigned char *dest = state->out + (state->size << 1); while (src > state->out) *--dest = *--src; - state->next = dest; + state->x.next = dest; } - state->have++; - state->next--; - state->next[0] = c; - state->pos--; + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; return c; } @@ -575,8 +519,9 @@ char * ZEXPORT gzgets(file, buf, len) return NULL; state = (gz_statep)file; - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) return NULL; /* process a skip request */ @@ -593,32 +538,31 @@ char * ZEXPORT gzgets(file, buf, len) left = (unsigned)len - 1; if (left) do { /* assure that something is in the output buffer */ - if (state->have == 0) { - if (gz_make(state) == -1) - return NULL; /* error */ - if (state->have == 0) { /* end of file */ - if (buf == str) /* got bupkus */ - return NULL; - break; /* got something -- return it */ - } + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ } /* look for end-of-line in current output buffer */ - n = state->have > left ? left : state->have; - eol = memchr(state->next, '\n', n); + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); if (eol != NULL) - n = (unsigned)(eol - state->next) + 1; + n = (unsigned)(eol - state->x.next) + 1; /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->next, n); - state->have -= n; - state->next += n; - state->pos += n; + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; left -= n; buf += n; } while (left && eol == NULL); - /* found end-of-line or out of space -- terminate string and return it */ + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; buf[0] = 0; return str; } @@ -634,16 +578,12 @@ int ZEXPORT gzdirect(file) return 0; state = (gz_statep)file; - /* check that we're reading */ - if (state->mode != GZ_READ) - return 0; - /* if the state is not known, but we can find out, then do so (this is mainly for right after a gzopen() or gzdopen()) */ - if (state->how == LOOK && state->have == 0) - (void)gz_head(state); + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); - /* return 1 if reading direct, 0 if decompressing a gzip stream */ + /* return 1 if transparent, 0 if processing a gzip stream */ return state->direct; } @@ -651,7 +591,7 @@ int ZEXPORT gzdirect(file) int ZEXPORT gzclose_r(file) gzFile file; { - int ret; + int ret, err; gz_statep state; /* get internal structure */ @@ -669,9 +609,10 @@ int ZEXPORT gzclose_r(file) free(state->out); free(state->in); } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; gz_error(state, Z_OK, NULL); free(state->path); ret = close(state->fd); free(state); - return ret ? Z_ERRNO : Z_OK; + return ret ? Z_ERRNO : err; } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzwrite.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzwrite.c similarity index 75% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/gzwrite.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/gzwrite.c index bff643e0667..1955cf763b4 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/gzwrite.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/gzwrite.c @@ -23,7 +23,7 @@ */ /* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -42,44 +42,55 @@ local int gz_init(state) int ret; z_streamp strm = &(state->strm); - /* allocate input and output buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); + /* allocate input buffer */ + state->in = (unsigned char *)malloc(state->want); + if (state->in == NULL) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - 15 + 16, 8, state->strategy); - if (ret != Z_OK) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } } /* mark state as initialized */ state->size = state->want; - /* initialize write buffer */ - strm->avail_out = state->size; - strm->next_out = state->out; - state->next = strm->next_out; + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } return 0; } /* Compress whatever is at avail_in and next_in and write to the output file. Return -1 if there is an error writing to the output file, otherwise 0. flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, - then the deflate() state is reset to start a new gzip stream. */ + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ local int gz_comp(state, flush) gz_statep state; int flush; @@ -92,6 +103,17 @@ local int gz_comp(state, flush) if (state->size == 0 && gz_init(state) == -1) return -1; + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + /* run deflate() on provided input until it produces no more output */ ret = Z_OK; do { @@ -99,8 +121,8 @@ local int gz_comp(state, flush) doing Z_FINISH then don't write until we get to Z_STREAM_END */ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->next); - if (have && ((got = write(state->fd, state->next, have)) < 0 || + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || (unsigned)got != have)) { gz_error(state, Z_ERRNO, zstrerror()); return -1; @@ -109,7 +131,7 @@ local int gz_comp(state, flush) strm->avail_out = state->size; strm->next_out = state->out; } - state->next = strm->next_out; + state->x.next = strm->next_out; } /* compress */ @@ -155,7 +177,7 @@ local int gz_zero(state, len) } strm->avail_in = n; strm->next_in = state->in; - state->pos += n; + state->x.pos += n; if (gz_comp(state, Z_NO_FLUSH) == -1) return -1; len -= n; @@ -170,7 +192,6 @@ int ZEXPORT gzwrite(file, buf, len) unsigned len; { unsigned put = len; - unsigned n; gz_statep state; z_streamp strm; @@ -187,7 +208,7 @@ int ZEXPORT gzwrite(file, buf, len) /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ if ((int)len < 0) { - gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); return 0; } @@ -210,16 +231,19 @@ int ZEXPORT gzwrite(file, buf, len) if (len < state->size) { /* copy to input buffer, compress when full */ do { + unsigned have, copy; + if (strm->avail_in == 0) strm->next_in = state->in; - n = state->size - strm->avail_in; - if (n > len) - n = len; - memcpy(strm->next_in + strm->avail_in, buf, n); - strm->avail_in += n; - state->pos += n; - buf = (char *)buf + n; - len -= n; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + strm->avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; if (len && gz_comp(state, Z_NO_FLUSH) == -1) return 0; } while (len); @@ -231,8 +255,8 @@ int ZEXPORT gzwrite(file, buf, len) /* directly compress user buffer to file */ strm->avail_in = len; - strm->next_in = (voidp)buf; - state->pos += len; + strm->next_in = (z_const Bytef *)buf; + state->x.pos += len; if (gz_comp(state, Z_NO_FLUSH) == -1) return 0; } @@ -246,6 +270,7 @@ int ZEXPORT gzputc(file, c) gzFile file; int c; { + unsigned have; unsigned char buf[1]; gz_statep state; z_streamp strm; @@ -269,19 +294,23 @@ int ZEXPORT gzputc(file, c) /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ - if (strm->avail_in < state->size) { + if (state->size) { if (strm->avail_in == 0) strm->next_in = state->in; - strm->next_in[strm->avail_in++] = c; - state->pos++; - return c; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } } /* no room in buffer or not initialized, use gz_write() */ buf[0] = c; if (gzwrite(file, buf, 1) != 1) return -1; - return c; + return c & 0xff; } /* -- see zlib.h -- */ @@ -298,16 +327,15 @@ int ZEXPORT gzputs(file, str) return ret == 0 && len != 0 ? -1 : ret; } -#ifdef STDC +#if defined(STDC) || defined(Z_HAVE_STDARG_H) #include /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { int size, len; gz_statep state; z_streamp strm; - va_list va; /* get internal structure */ if (file == NULL) @@ -337,25 +365,20 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) /* do the printf() into the input buffer, put length in len */ size = (int)(state->size); state->in[size - 1] = 0; - va_start(va, format); #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void - (void)vsprintf(state->in, format, va); - va_end(va); + (void)vsprintf((char *)(state->in), format, va); for (len = 0; len < size; len++) if (state->in[len] == 0) break; # else - len = vsprintf(state->in, format, va); - va_end(va); + len = vsprintf((char *)(state->in), format, va); # endif #else # ifdef HAS_vsnprintf_void - (void)vsnprintf(state->in, size, format, va); - va_end(va); - len = strlen(state->in); + (void)vsnprintf((char *)(state->in), size, format, va); + len = strlen((char *)(state->in)); # else len = vsnprintf((char *)(state->in), size, format, va); - va_end(va); # endif #endif @@ -366,11 +389,22 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; strm->next_in = state->in; - state->pos += len; + state->x.pos += len; return len; } -#else /* !STDC */ +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, @@ -390,6 +424,10 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, state = (gz_statep)file; strm = &(state->strm); + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return 0; @@ -414,22 +452,23 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, state->in[size - 1] = 0; #ifdef NO_snprintf # ifdef HAS_sprintf_void - sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); for (len = 0; len < size; len++) if (state->in[len] == 0) break; # else - len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #else # ifdef HAS_snprintf_void - snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(state->in); + len = strlen((char *)(state->in)); # else - len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); # endif #endif @@ -440,7 +479,7 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; strm->next_in = state->in; - state->pos += len; + state->x.pos += len; return len; } @@ -524,7 +563,7 @@ int ZEXPORT gzsetparams(file, level, strategy) int ZEXPORT gzclose_w(file) gzFile file; { - int ret = 0; + int ret = Z_OK; gz_statep state; /* get internal structure */ @@ -539,17 +578,24 @@ int ZEXPORT gzclose_w(file) /* check for seek request */ if (state->seek) { state->seek = 0; - ret += gz_zero(state, state->skip); + if (gz_zero(state, state->skip) == -1) + ret = state->err; } /* flush, free memory, and close file */ - ret += gz_comp(state, Z_FINISH); - (void)deflateEnd(&(state->strm)); - free(state->out); - free(state->in); + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } gz_error(state, Z_OK, NULL); free(state->path); - ret += close(state->fd); + if (close(state->fd) == -1) + ret = Z_ERRNO; free(state); - return ret ? Z_ERRNO : Z_OK; + return ret; } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/infback.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/infback.c similarity index 98% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/infback.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/infback.c index 783274e4c26..7001b4bfe62 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/infback.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/infback.c @@ -23,7 +23,7 @@ */ /* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2009 Mark Adler + * Copyright (C) 1995-2011 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -66,10 +66,19 @@ int stream_size; return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; +#endif } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; @@ -270,7 +279,7 @@ out_func out; void FAR *out_desc; { struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ + z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ @@ -418,7 +427,6 @@ void FAR *out_desc; PULLBYTE(); } if (here.val < 16) { - NEEDBITS(here.bits); DROPBITS(here.bits); state->lens[state->have++] = here.val; } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inffast.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inffast.c similarity index 98% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inffast.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inffast.c index e6a05723be4..4b9cddd7040 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inffast.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inffast.c @@ -23,7 +23,7 @@ */ /* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler + * Copyright (C) 1995-2008, 2010, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -93,8 +93,8 @@ z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inffast.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inffast.h similarity index 100% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inffast.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inffast.h diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inffixed.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inffixed.h similarity index 97% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inffixed.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inffixed.h index f44fee25112..f0a4ef1c4e8 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inffixed.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inffixed.h @@ -26,9 +26,9 @@ * Generated automatically by makefixed(). */ - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. */ static const code lenfix[512] = { diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inflate.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inflate.c similarity index 94% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inflate.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inflate.c index 6e172217b3f..b159c1543a6 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inflate.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inflate.c @@ -23,7 +23,7 @@ */ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2010 Mark Adler + * Copyright (C) 1995-2012 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -117,14 +117,15 @@ /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); #ifdef BUILDFIXED void makefixed OF((void)); #endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, unsigned len)); -int ZEXPORT inflateReset(strm) +int ZEXPORT inflateResetKeep(strm) z_streamp strm; { struct inflate_state FAR *state; @@ -133,15 +134,13 @@ z_streamp strm; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; state->mode = HEAD; state->last = 0; state->havedict = 0; state->dmax = 32768U; state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; @@ -151,6 +150,19 @@ z_streamp strm; return Z_OK; } +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + int ZEXPORT inflateReset2(strm, windowBits) z_streamp strm; int windowBits; @@ -204,10 +216,19 @@ int stream_size; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; +#endif } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; @@ -345,8 +366,8 @@ void makefixed() low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); if (++low == size) break; putchar(','); } @@ -379,12 +400,13 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, out) +local int updatewindow(strm, end, copy) z_streamp strm; -unsigned out; +const Bytef *end; +unsigned copy; { struct inflate_state FAR *state; - unsigned copy, dist; + unsigned dist; state = (struct inflate_state FAR *)strm->state; @@ -404,19 +426,18 @@ unsigned out; } /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + zmemcpy(state->window, end - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + zmemcpy(state->window + state->wnext, end - copy, dist); copy -= dist; if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); + zmemcpy(state->window, end - copy, copy); state->wnext = copy; state->whave = state->wsize; } @@ -523,11 +544,6 @@ unsigned out; bits -= bits & 7; \ } while (0) -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is @@ -615,7 +631,7 @@ z_streamp strm; int flush; { struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ + z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ @@ -821,7 +837,7 @@ int flush; #endif case DICTID: NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); + strm->adler = state->check = ZSWAP32(hold); INITBITS(); state->mode = DICT; case DICT: @@ -929,7 +945,7 @@ int flush; while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; - state->lencode = (code const FAR *)(state->next); + state->lencode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); @@ -949,7 +965,6 @@ int flush; PULLBYTE(); } if (here.val < 16) { - NEEDBITS(here.bits); DROPBITS(here.bits); state->lens[state->have++] = here.val; } @@ -1004,7 +1019,7 @@ int flush; values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; - state->lencode = (code const FAR *)(state->next); + state->lencode = (const code FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); @@ -1013,7 +1028,7 @@ int flush; state->mode = BAD; break; } - state->distcode = (code const FAR *)(state->next); + state->distcode = (const code FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); @@ -1194,7 +1209,7 @@ int flush; #ifdef GUNZIP state->flags ? hold : #endif - REVERSE(hold)) != state->check) { + ZSWAP32(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; @@ -1238,8 +1253,9 @@ int flush; */ inf_leave: RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } @@ -1273,13 +1289,37 @@ z_streamp strm; return Z_OK; } +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; - unsigned long id; + unsigned long dictid; + int ret; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; @@ -1287,29 +1327,21 @@ uInt dictLength; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; - /* check for correct dictionary id */ + /* check for correct dictionary identifier */ if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) return Z_DATA_ERROR; } - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { state->mode = MEM; return Z_MEM_ERROR; } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; @@ -1345,7 +1377,7 @@ gz_headerp head; */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; -unsigned char FAR *buf; +const unsigned char FAR *buf; unsigned len; { unsigned got; @@ -1457,8 +1489,8 @@ z_streamp source; } /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inflate.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inflate.h similarity index 100% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inflate.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inflate.h diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inftrees.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inftrees.c similarity index 89% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inftrees.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inftrees.c index 9842631ccdf..c4b0bf2dd4a 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inftrees.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inftrees.c @@ -23,7 +23,7 @@ */ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2010 Mark Adler + * Copyright (C) 1995-2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -33,7 +33,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -86,7 +86,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, @@ -232,8 +232,8 @@ unsigned short FAR *work; mask = used - 1; /* mask for comparing low */ /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ @@ -301,8 +301,8 @@ unsigned short FAR *work; /* check for enough space */ used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ @@ -313,38 +313,14 @@ unsigned short FAR *work; } } - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - here.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = here; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; } /* set return parameters */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/inftrees.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/inftrees.h similarity index 100% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/inftrees.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/inftrees.h diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/patches/ChangeLog_java b/jdk/src/share/native/java/util/zip/zlib-1.2.8/patches/ChangeLog_java similarity index 100% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/patches/ChangeLog_java rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/patches/ChangeLog_java diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/trees.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/trees.c similarity index 96% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/trees.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/trees.c index 04da4d709f3..e4ecffea093 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/trees.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/trees.c @@ -23,7 +23,7 @@ */ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2010 Jean-loup Gailly + * Copyright (C) 1995-2012 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -98,11 +98,6 @@ local const uch bl_order[BL_CODES] * probability, to avoid transmitting the lengths for unused bit length codes. */ -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - /* =========================================================================== * Local data. These are initialized only once. */ @@ -175,8 +170,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); @@ -423,7 +418,6 @@ void ZLIB_INTERNAL _tr_init(s) s->bi_buf = 0; s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG s->compressed_len = 0L; s->bits_sent = 0L; @@ -906,16 +900,18 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. */ void ZLIB_INTERNAL _tr_align(s) deflate_state *s; @@ -926,20 +922,6 @@ void ZLIB_INTERNAL _tr_align(s) s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; } /* =========================================================================== @@ -1014,7 +996,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif @@ -1022,7 +1005,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif @@ -1099,8 +1083,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) */ local void compress_block(s, ltree, dtree) deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ @@ -1142,7 +1126,6 @@ local void compress_block(s, ltree, dtree) } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== @@ -1250,7 +1233,6 @@ local void copy_block(s, buf, len, header) int header; /* true if block header must be written */ { bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/trees.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/trees.h similarity index 100% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/trees.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/trees.h diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/uncompr.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/uncompr.c similarity index 97% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/uncompr.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/uncompr.c index e71d018f8d0..1bcf06feeb0 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/uncompr.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/uncompr.c @@ -54,7 +54,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen) z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; @@ -76,7 +76,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen) return Z_DATA_ERROR; return err; } - *destLen = (uLong)stream.total_out; + *destLen = stream.total_out; err = inflateEnd(&stream); return err; diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zadler32.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zadler32.c similarity index 78% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/zadler32.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/zadler32.c index c4465e1d6ed..a3108315221 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zadler32.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zadler32.c @@ -23,7 +23,7 @@ */ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2007 Mark Adler + * Copyright (C) 1995-2011 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -33,9 +33,9 @@ #define local static -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); -#define BASE 65521UL /* largest prime smaller than 65536 */ +#define BASE 65521 /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -45,39 +45,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); -/* use NO_DIVIDE if your processor does not do division in hardware */ +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ #ifdef NO_DIVIDE -# define MOD(a) \ +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ if (a >= BASE) a -= BASE; \ } while (0) -# define MOD4(a) \ +# define MOD(a) \ do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE -# define MOD4(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE #endif /* ========================================================================= */ @@ -116,7 +121,7 @@ uLong ZEXPORT adler32(adler, buf, len) } if (adler >= BASE) adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ + MOD28(sum2); /* only added so many BASE's */ return adler | (sum2 << 16); } @@ -161,8 +166,13 @@ local uLong adler32_combine_(adler1, adler2, len2) unsigned long sum2; unsigned rem; + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; sum1 = adler1 & 0xffff; sum2 = rem * sum1; MOD(sum2); diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zconf.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zconf.h similarity index 74% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/zconf.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/zconf.h index 78f162cfd6a..c7edbed7d12 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zconf.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zconf.h @@ -23,7 +23,7 @@ */ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -42,11 +42,13 @@ * this permanently in zconf.h using "./configure --zprefix". */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET /* all linked symbols */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block @@ -54,9 +56,11 @@ # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 @@ -67,44 +71,53 @@ # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams +# define deflatePending z_deflatePending # define deflatePrime z_deflatePrime # define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd @@ -119,16 +132,22 @@ # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table -# define uncompress z_uncompress +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif # define zError z_zError -# define zcalloc z_zcalloc -# define zcfree z_zcfree +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif # define zlibCompileFlags z_zlibCompileFlags # define zlibVersion z_zlibVersion @@ -138,7 +157,9 @@ # define alloc_func z_alloc_func # define charf z_charf # define free_func z_free_func -# define gzFile z_gzFile +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif # define gz_header z_gz_header # define gz_headerp z_gz_headerp # define in_func z_in_func @@ -224,6 +245,12 @@ # endif #endif +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL @@ -270,6 +297,14 @@ # endif #endif +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -360,6 +395,7 @@ typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ + #ifdef _LP64 typedef unsigned int uLong; /* 32 bits or more */ #else @@ -387,12 +423,47 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_UNISTD_H #endif +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + #ifdef STDC -# include /* for off_t */ +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and @@ -401,21 +472,38 @@ typedef uLong FAR uLongf; * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ -#if -_LARGEFILE64_SOURCE - -1 == 1 +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif # endif #endif -#ifndef SEEK_SET +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ @@ -425,18 +513,14 @@ typedef uLong FAR uLongf; # define z_off_t long #endif -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +#if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# define z_off64_t z_off_t -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif #endif /* MVS linker does not support external names larger than 8 bytes */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zcrc32.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zcrc32.c similarity index 87% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/zcrc32.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/zcrc32.c index 0eb5b64f110..0fe90df9799 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zcrc32.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zcrc32.c @@ -23,7 +23,7 @@ */ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010 Mark Adler + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster @@ -41,6 +41,8 @@ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. */ #ifdef MAKECRCH @@ -54,31 +56,11 @@ #define local static -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - /* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif #ifdef BYFOUR -# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, @@ -92,16 +74,16 @@ local unsigned long gf2_matrix_times OF((unsigned long *mat, unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); #ifdef DYNAMIC_CRC_TABLE local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; +local z_crc_t FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); + local void write_table OF((FILE *, const z_crc_t FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: @@ -131,9 +113,9 @@ local void make_crc_table OF((void)); */ local void make_crc_table() { - unsigned long c; + z_crc_t c; int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ + z_crc_t poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static volatile int first = 1; /* flag to limit concurrent making */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; @@ -145,13 +127,13 @@ local void make_crc_table() first = 0; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { - c = (unsigned long)n; + c = (z_crc_t)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; @@ -162,11 +144,11 @@ local void make_crc_table() and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; - crc_table[4][n] = REV(c); + crc_table[4][n] = ZSWAP32(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); + crc_table[k + 4][n] = ZSWAP32(c); } } #endif /* BYFOUR */ @@ -188,7 +170,7 @@ local void make_crc_table() if (out == NULL) return; fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); + fprintf(out, "local const z_crc_t FAR "); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); write_table(out, crc_table[0]); # ifdef BYFOUR @@ -208,12 +190,13 @@ local void make_crc_table() #ifdef MAKECRCH local void write_table(out, table) FILE *out; - const unsigned long FAR *table; + const z_crc_t FAR *table; { int n; for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ @@ -228,13 +211,13 @@ local void write_table(out, table) /* ========================================================================= * This function can be used by asm versions of crc32() */ -const unsigned long FAR * ZEXPORT get_crc_table() +const z_crc_t FAR * ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; + return (const z_crc_t FAR *)crc_table; } /* ========================================================================= */ @@ -256,7 +239,7 @@ uLong ZEXPORT crc32(crc, buf, len) #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; + z_crc_t endian; endian = 1; if (*((unsigned char *)(&endian))) @@ -290,17 +273,17 @@ local unsigned long crc32_little(crc, buf, len) const unsigned char FAR *buf; unsigned len; { - register u4 c; - register const u4 FAR *buf4; + register z_crc_t c; + register const z_crc_t FAR *buf4; - c = (u4)crc; + c = (z_crc_t)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); len--; } - buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; while (len >= 32) { DOLIT32; len -= 32; @@ -330,17 +313,17 @@ local unsigned long crc32_big(crc, buf, len) const unsigned char FAR *buf; unsigned len; { - register u4 c; - register const u4 FAR *buf4; + register z_crc_t c; + register const z_crc_t FAR *buf4; - c = REV((u4)crc); + c = ZSWAP32((z_crc_t)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } - buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; buf4--; while (len >= 32) { DOBIG32; @@ -357,7 +340,7 @@ local unsigned long crc32_big(crc, buf, len) c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; - return (unsigned long)(REV(c)); + return (unsigned long)(ZSWAP32(c)); } #endif /* BYFOUR */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zlib.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zlib.h similarity index 84% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/zlib.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/zlib.h index b3617e58bc7..8779cadf207 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zlib.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zlib.h @@ -23,9 +23,9 @@ */ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.5, April 19th, 2010 + version 1.2.8, April 28th, 2013 - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,8 +48,8 @@ The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). */ #ifndef ZLIB_H @@ -61,11 +61,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.5" -#define ZLIB_VERNUM 0x1250 +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_REVISION 8 #define ZLIB_VER_SUBREVISION 0 /* @@ -107,15 +107,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ + z_const Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ + uLong total_in; /* total number of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ + uLong total_out; /* total number of bytes output so far */ - char *msg; /* last error message, NULL if no error */ + z_const char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ @@ -351,8 +351,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). @@ -475,23 +476,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is never required, but can be - used to inform inflate that a faster approach may be used for the single - inflate() call. + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK or Z_TREES is used. + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, + strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END @@ -502,7 +509,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); initializing with inflateInit2(). Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has @@ -604,10 +613,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly @@ -634,8 +648,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, @@ -712,9 +726,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. */ +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); @@ -727,8 +761,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, than or equal to 16, and that many of the least significant bits of value will be inserted in the output. - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, @@ -814,10 +849,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is @@ -827,19 +863,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been - found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the - success case, the application may save the current current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, @@ -986,12 +1041,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + the parameters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, @@ -999,11 +1055,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. @@ -1112,6 +1169,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); 27-31: 0 (reserved) */ +#ifndef Z_SOLO /* utility functions */ @@ -1173,10 +1231,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. */ - /* gzip file access functions */ /* @@ -1186,7 +1245,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, wrapper, documented in RFC 1952, wrapped around a deflate stream. */ -typedef voidp gzFile; /* opaque gzip file descriptor */ +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); @@ -1196,13 +1255,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) Also "a" - can be used instead of "w" to request that the gzip stream that will be - written be appended to the file. "+" will result in an error, since reading - and writing to the same gzip file is not supported. + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. gzopen returns NULL if the file could not be opened, if there was insufficient memory to allocate the gzFile state, or if an invalid mode was @@ -1221,7 +1295,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. gzdopen returns NULL if there was insufficient memory to allocate the gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not @@ -1259,14 +1337,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If - the input file was not in gzip format, gzread copies the given number of - bytes into the buffer. + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream, or failing that, reading the rest - of the input file directly without decompression. The entire input file - will be read if gzread is called until it returns less than the requested - len. + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. gzread returns the number of uncompressed bytes actually read, less than len for end of file, or -1 for error. @@ -1280,7 +1370,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, error. */ -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of @@ -1325,7 +1415,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); @@ -1421,9 +1514,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. This state can change from - false to true while reading the input file if the end of a gzip stream is - reached, but is followed by data that is not another gzip stream. + (0) if file is a gzip stream being decompressed. If the input file is empty, gzdirect() will return true, since the input does not contain a gzip stream. @@ -1432,6 +1523,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); cause buffers to be allocated to allow reading the file to determine if it is a gzip file. Therefore if gzbuffer() is used, it should be called before gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); @@ -1443,7 +1541,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); must not be called more than once on the same allocation. gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, or Z_OK on success. + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. */ ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); @@ -1481,6 +1580,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); file that is being written concurrently. */ +#endif /* !Z_SOLO */ /* checksum functions */ @@ -1516,16 +1616,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. Usage example: @@ -1568,17 +1669,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); #define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if @@ -1586,7 +1712,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, * functions are changed to 64 bits) -- in case these are set on systems * without large file support, _LFS64_LARGEFILE must also be true */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +#ifdef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); @@ -1595,14 +1721,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifdef _LARGEFILE64_SOURCE +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); @@ -1619,6 +1754,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + /* hack for buggy compilers */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; @@ -1627,8 +1769,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, /* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const unsigned long FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif #ifdef __cplusplus } diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zutil.c b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zutil.c similarity index 95% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/zutil.c rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/zutil.c index 041aa973179..e54347610c8 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zutil.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zutil.c @@ -23,19 +23,22 @@ */ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. + * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif -const char * const z_errmsg[10] = { +z_const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ @@ -109,27 +112,27 @@ uLong ZEXPORT zlibCompileFlags() #ifdef FASTEST flags += 1L << 21; #endif -#ifdef STDC +#if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifdef NO_vsnprintf - flags += 1L << 25; + flags += 1L << 25; # ifdef HAS_vsprintf_void - flags += 1L << 26; + flags += 1L << 26; # endif # else # ifdef HAS_vsnprintf_void - flags += 1L << 26; + flags += 1L << 26; # endif # endif #else - flags += 1L << 24; + flags += 1L << 24; # ifdef NO_snprintf - flags += 1L << 25; + flags += 1L << 25; # ifdef HAS_sprintf_void - flags += 1L << 26; + flags += 1L << 26; # endif # else # ifdef HAS_snprintf_void - flags += 1L << 26; + flags += 1L << 26; # endif # endif #endif @@ -205,6 +208,7 @@ void ZLIB_INTERNAL zmemzero(dest, len) } #endif +#ifndef Z_SOLO #ifdef SYS16BIT @@ -340,3 +344,5 @@ void ZLIB_INTERNAL zcfree (opaque, ptr) } #endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zutil.h b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zutil.h similarity index 76% rename from jdk/src/share/native/java/util/zip/zlib-1.2.5/zutil.h rename to jdk/src/share/native/java/util/zip/zlib-1.2.8/zutil.h index 1c4e8d38fe5..b82b14d4a5e 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.5/zutil.h +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.8/zutil.h @@ -23,7 +23,7 @@ */ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -37,7 +37,7 @@ #ifndef ZUTIL_H #define ZUTIL_H -#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +#ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL @@ -45,7 +45,7 @@ #include "zlib.h" -#ifdef STDC +#if defined(STDC) && !defined(Z_SOLO) # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # include # endif @@ -53,6 +53,10 @@ # include #endif +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + #ifndef local # define local static #endif @@ -64,13 +68,13 @@ typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) + return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ @@ -102,16 +106,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include # endif -# else /* MSC or DJGPP */ -# include # endif #endif @@ -131,18 +137,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #ifdef OS2 # define OS_CODE 0x06 -# ifdef M_I86 +# if defined(M_I86) && !defined(Z_SOLO) # include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif # endif # endif #endif @@ -177,14 +185,15 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(__BORLANDC__) +#if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 #pragma warn -8066 #endif /* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif @@ -201,42 +210,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* functions */ -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) +#if defined(pyr) || defined(Z_SOLO) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) @@ -285,14 +259,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define Tracecv(c,x) #endif - -voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); -void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + #endif /* ZUTIL_H */ diff --git a/jdk/src/share/native/sun/security/smartcardio/pcsc.c b/jdk/src/share/native/sun/security/smartcardio/pcsc.c index ab30e138120..b837234761d 100644 --- a/jdk/src/share/native/sun/security/smartcardio/pcsc.c +++ b/jdk/src/share/native/sun/security/smartcardio/pcsc.c @@ -125,7 +125,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardEstablishContext jobjectArray pcsc_multi2jstring(JNIEnv *env, char *spec) { jobjectArray result; jclass stringClass; - char *cp, **tab; + char *cp, **tab = NULL; jstring js; int cnt = 0; @@ -179,7 +179,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade { SCARDCONTEXT context = (SCARDCONTEXT)jContext; LONG rv; - LPTSTR mszReaders; + LPTSTR mszReaders = NULL; DWORD size = 0; jobjectArray result; @@ -190,18 +190,20 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade } dprintf1("-size: %d\n", size); - mszReaders = malloc(size); - if (mszReaders == NULL) { - throwOutOfMemoryError(env, NULL); - return NULL; - } + if (size) { + mszReaders = malloc(size); + if (mszReaders == NULL) { + throwOutOfMemoryError(env, NULL); + return NULL; + } - rv = CALL_SCardListReaders(context, NULL, mszReaders, &size); - if (handleRV(env, rv)) { - free(mszReaders); - return NULL; + rv = CALL_SCardListReaders(context, NULL, mszReaders, &size); + if (handleRV(env, rv)) { + free(mszReaders); + return NULL; + } + dprintf1("-String: %s\n", mszReaders); } - dprintf1("-String: %s\n", mszReaders); result = pcsc_multi2jstring(env, mszReaders); free(mszReaders); @@ -336,7 +338,7 @@ JNIEXPORT jintArray JNICALL Java_sun_security_smartcardio_PCSC_SCardGetStatusCha const char *readerName; readerState = calloc(readers, sizeof(SCARD_READERSTATE)); - if (readerState == NULL) { + if (readerState == NULL && readers > 0) { throwOutOfMemoryError(env, NULL); return NULL; } @@ -347,6 +349,10 @@ JNIEXPORT jintArray JNICALL Java_sun_security_smartcardio_PCSC_SCardGetStatusCha return NULL; } + for (i = 0; i < readers; i++) { + readerState[i].szReader = NULL; + } + for (i = 0; i < readers; i++) { jobject jReaderName = (*env)->GetObjectArrayElement(env, jReaderNames, i); if ((*env)->ExceptionCheck(env)) { @@ -369,9 +375,11 @@ JNIEXPORT jintArray JNICALL Java_sun_security_smartcardio_PCSC_SCardGetStatusCha (*env)->DeleteLocalRef(env, jReaderName); } - rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers); - if (handleRV(env, rv)) { - goto cleanup; + if (readers > 0) { + rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers); + if (handleRV(env, rv)) { + goto cleanup; + } } jEventState = (*env)->NewIntArray(env, readers); diff --git a/jdk/src/solaris/classes/java/lang/UNIXProcess.java b/jdk/src/solaris/classes/java/lang/UNIXProcess.java index 56ba83f036f..85f15407c8f 100644 --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java @@ -97,6 +97,7 @@ final class UNIXProcess extends Process { EnumSet.copyOf(Arrays.asList(launchMechanisms)); } + @SuppressWarnings("fallthrough") private String helperPath(String javahome, String osArch) { switch (this) { case SOLARIS: diff --git a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c index dfe9c421c19..f344f4a00d9 100644 --- a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c +++ b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c @@ -136,5 +136,9 @@ JNIEXPORT void JNICALL Java_sun_security_smartcardio_PlatformPCSC_initialize if ((*env)->ExceptionCheck(env)) { return; } +#ifndef __APPLE__ scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl"); +#else + scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl132"); +#endif // __APPLE__ } diff --git a/jdk/src/windows/transport/shmem/shmem_md.c b/jdk/src/windows/transport/shmem/shmem_md.c index 056dce648f7..2574bc3933b 100644 --- a/jdk/src/windows/transport/shmem/shmem_md.c +++ b/jdk/src/windows/transport/shmem/shmem_md.c @@ -200,6 +200,17 @@ sysIPMutexEnter(sys_ipmutex_t mutex, sys_event_t event) rc = WaitForMultipleObjects(count, handles, FALSE, /* wait for either, not both */ INFINITE); /* infinite timeout */ + + /* If the mutex is abandoned we will consider this a fatal error + * and abort with appropriate message. + * + * Note that only mutexes can be abandoned and that our mutex is + * always at position 0 in the handles array. Thus we only need + * to check WAIT_ABANDONED_0 (not WAIT_ABANDONED_0 + x). + */ + if (rc == WAIT_ABANDONED_0) { + exitTransportWithError("Observed abandoned IP mutex. Aborting.",THIS_FILE, __DATE__, __LINE__); + } return (rc == WAIT_OBJECT_0) ? SYS_OK : SYS_ERR; } diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index dd045badca7..64c5ba9036a 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -261,6 +261,10 @@ com/sun/jdi/JdbMethodExitTest.sh generic-all # 8041934 com/sun/jdi/RepStep.java generic-all +# 8044419 +com/sun/jdi/JdbReadTwiceTest.sh generic-all + + ############################################################################ # jdk_util diff --git a/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java b/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java deleted file mode 100644 index b08206ef3e9..00000000000 --- a/jdk/test/demo/jvmti/mtrace/JFrameCreateTime.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -/* JFrameCreateTime: - * - * Example swing application that just creates a JFrame object. - * - */ - -/* Early in 1.5 it was reported that doing a step into the first JFrame - * was very slow (VisualMust debugger people reported this). - */ - -import java.awt.GraphicsEnvironment; -import javax.swing.*; - -public class JFrameCreateTime { - public static void main(String[] args) { - JFrame f; - long start, end; - if (GraphicsEnvironment.isHeadless()) { - System.out.println("JFrameCreateTime test was skipped due to headless mode"); - } else { - start = System.currentTimeMillis(); - f = new JFrame("JFrame"); - end = System.currentTimeMillis(); - - System.out.println("JFrame first creation took " + (end - start) + " ms"); - - start = System.currentTimeMillis(); - f = new JFrame("JFrame"); - end = System.currentTimeMillis(); - - System.out.println("JFrame second creation took " + (end - start) + " ms"); - System.exit(0); - } - } -} diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index 039feb16404..d59688e9d7d 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -937,18 +937,13 @@ public class Basic { equal(pb.redirectError(), Redirect.to(efile)); THROWS(IllegalArgumentException.class, - new Fun(){void f() { - pb.redirectInput(Redirect.to(ofile)); }}, - new Fun(){void f() { - pb.redirectInput(Redirect.appendTo(ofile)); }}, - new Fun(){void f() { - pb.redirectOutput(Redirect.from(ifile)); }}, - new Fun(){void f() { - pb.redirectError(Redirect.from(ifile)); }}); + () -> pb.redirectInput(Redirect.to(ofile)), + () -> pb.redirectOutput(Redirect.from(ifile)), + () -> pb.redirectError(Redirect.from(ifile))); THROWS(IOException.class, // Input file does not exist - new Fun(){void f() throws Throwable { pb.start(); }}); + () -> pb.start()); setFileContents(ifile, "standard input"); //---------------------------------------------------------------- @@ -1084,18 +1079,15 @@ public class Basic { = new FilePermission("<>", "read,write,execute"); THROWS(SecurityException.class, - new Fun() { void f() throws IOException { - policy.setPermissions(xPermission); - redirectIO(pb, from(tmpFile), PIPE, PIPE); - pb.start();}}, - new Fun() { void f() throws IOException { - policy.setPermissions(rxPermission); - redirectIO(pb, PIPE, to(ofile), PIPE); - pb.start();}}, - new Fun() { void f() throws IOException { - policy.setPermissions(rxPermission); - redirectIO(pb, PIPE, PIPE, to(efile)); - pb.start();}}); + () -> { policy.setPermissions(xPermission); + redirectIO(pb, from(tmpFile), PIPE, PIPE); + pb.start();}, + () -> { policy.setPermissions(rxPermission); + redirectIO(pb, PIPE, to(ofile), PIPE); + pb.start();}, + () -> { policy.setPermissions(rxPermission); + redirectIO(pb, PIPE, PIPE, to(efile)); + pb.start();}); { policy.setPermissions(rxPermission); @@ -1258,10 +1250,10 @@ public class Basic { // System.getenv() is read-only. //---------------------------------------------------------------- THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ getenv().put("FOO","BAR");}}, - new Fun(){void f(){ getenv().remove("PATH");}}, - new Fun(){void f(){ getenv().keySet().remove("PATH");}}, - new Fun(){void f(){ getenv().values().remove("someValue");}}); + () -> getenv().put("FOO","BAR"), + () -> getenv().remove("PATH"), + () -> getenv().keySet().remove("PATH"), + () -> getenv().values().remove("someValue")); try { Collection> c = getenv().entrySet(); @@ -1286,19 +1278,17 @@ public class Basic { { final Map m = new ProcessBuilder().environment(); THROWS(IllegalArgumentException.class, - new Fun(){void f(){ m.put("FOO=","BAR");}}, - new Fun(){void f(){ m.put("FOO\u0000","BAR");}}, - new Fun(){void f(){ m.put("FOO","BAR\u0000");}}); + () -> m.put("FOO=","BAR"), + () -> m.put("FOO\u0000","BAR"), + () -> m.put("FOO","BAR\u0000")); } //---------------------------------------------------------------- // Commands must never be null. //---------------------------------------------------------------- THROWS(NullPointerException.class, - new Fun(){void f(){ - new ProcessBuilder((List)null);}}, - new Fun(){void f(){ - new ProcessBuilder().command((List)null);}}); + () -> new ProcessBuilder((List)null), + () -> new ProcessBuilder().command((List)null)); //---------------------------------------------------------------- // Put in a command; get the same one back out. @@ -1323,25 +1313,18 @@ public class Basic { // Commands must contain at least one element. //---------------------------------------------------------------- THROWS(IndexOutOfBoundsException.class, - new Fun() { void f() throws IOException { - new ProcessBuilder().start();}}, - new Fun() { void f() throws IOException { - new ProcessBuilder(new ArrayList()).start();}}, - new Fun() { void f() throws IOException { - Runtime.getRuntime().exec(new String[]{});}}); + () -> new ProcessBuilder().start(), + () -> new ProcessBuilder(new ArrayList()).start(), + () -> Runtime.getRuntime().exec(new String[]{})); //---------------------------------------------------------------- // Commands must not contain null elements at start() time. //---------------------------------------------------------------- THROWS(NullPointerException.class, - new Fun() { void f() throws IOException { - new ProcessBuilder("foo",null,"bar").start();}}, - new Fun() { void f() throws IOException { - new ProcessBuilder((String)null).start();}}, - new Fun() { void f() throws IOException { - new ProcessBuilder(new String[]{null}).start();}}, - new Fun() { void f() throws IOException { - new ProcessBuilder(new String[]{"foo",null,"bar"}).start();}}); + () -> new ProcessBuilder("foo",null,"bar").start(), + () -> new ProcessBuilder((String)null).start(), + () -> new ProcessBuilder(new String[]{null}).start(), + () -> new ProcessBuilder(new String[]{"foo",null,"bar"}).start()); //---------------------------------------------------------------- // Command lists are growable. @@ -1358,15 +1341,13 @@ public class Basic { try { final Map env = new ProcessBuilder().environment(); THROWS(NullPointerException.class, - new Fun(){void f(){ env.put("foo",null);}}, - new Fun(){void f(){ env.put(null,"foo");}}, - new Fun(){void f(){ env.remove(null);}}, - new Fun(){void f(){ - for (Map.Entry e : env.entrySet()) - e.setValue(null);}}, - new Fun() { void f() throws IOException { - Runtime.getRuntime().exec(new String[]{"foo"}, - new String[]{null});}}); + () -> env.put("foo",null), + () -> env.put(null,"foo"), + () -> env.remove(null), + () -> { for (Map.Entry e : env.entrySet()) + e.setValue(null);}, + () -> Runtime.getRuntime().exec(new String[]{"foo"}, + new String[]{null})); } catch (Throwable t) { unexpected(t); } //---------------------------------------------------------------- @@ -1375,10 +1356,10 @@ public class Basic { try { final Map env = new ProcessBuilder().environment(); THROWS(ClassCastException.class, - new Fun(){void f(){ env.remove(TRUE);}}, - new Fun(){void f(){ env.keySet().remove(TRUE);}}, - new Fun(){void f(){ env.values().remove(TRUE);}}, - new Fun(){void f(){ env.entrySet().remove(TRUE);}}); + () -> env.remove(TRUE), + () -> env.keySet().remove(TRUE), + () -> env.values().remove(TRUE), + () -> env.entrySet().remove(TRUE)); } catch (Throwable t) { unexpected(t); } //---------------------------------------------------------------- @@ -1394,22 +1375,22 @@ public class Basic { // Nulls in environment queries are forbidden. //---------------------------------------------------------------- THROWS(NullPointerException.class, - new Fun(){void f(){ getenv(null);}}, - new Fun(){void f(){ env.get(null);}}, - new Fun(){void f(){ env.containsKey(null);}}, - new Fun(){void f(){ env.containsValue(null);}}, - new Fun(){void f(){ env.keySet().contains(null);}}, - new Fun(){void f(){ env.values().contains(null);}}); + () -> getenv(null), + () -> env.get(null), + () -> env.containsKey(null), + () -> env.containsValue(null), + () -> env.keySet().contains(null), + () -> env.values().contains(null)); //---------------------------------------------------------------- // Non-String types in environment queries are forbidden. //---------------------------------------------------------------- THROWS(ClassCastException.class, - new Fun(){void f(){ env.get(TRUE);}}, - new Fun(){void f(){ env.containsKey(TRUE);}}, - new Fun(){void f(){ env.containsValue(TRUE);}}, - new Fun(){void f(){ env.keySet().contains(TRUE);}}, - new Fun(){void f(){ env.values().contains(TRUE);}}); + () -> env.get(TRUE), + () -> env.containsKey(TRUE), + () -> env.containsValue(TRUE), + () -> env.keySet().contains(TRUE), + () -> env.values().contains(TRUE)); //---------------------------------------------------------------- // Illegal String values in environment queries are (grumble) OK @@ -1427,12 +1408,11 @@ public class Basic { final Set> entrySet = new ProcessBuilder().environment().entrySet(); THROWS(NullPointerException.class, - new Fun(){void f(){ entrySet.contains(null);}}); + () -> entrySet.contains(null)); THROWS(ClassCastException.class, - new Fun(){void f(){ entrySet.contains(TRUE);}}, - new Fun(){void f(){ - entrySet.contains( - new SimpleImmutableEntry(TRUE,""));}}); + () -> entrySet.contains(TRUE), + () -> entrySet.contains( + new SimpleImmutableEntry(TRUE,""))); check(! entrySet.contains (new SimpleImmutableEntry("", ""))); @@ -1902,8 +1882,7 @@ public class Basic { final ProcessBuilder pb = new ProcessBuilder(new String[]{"unliKely"}); pb.environment().put("PATH", "suBdiR"); - THROWS(IOException.class, - new Fun() {void f() throws Throwable {pb.start();}}); + THROWS(IOException.class, () -> pb.start()); } catch (Throwable t) { unexpected(t); } finally { new File("suBdiR/unliKely").delete(); @@ -1976,10 +1955,8 @@ public class Basic { equal(SIZE, p.getInputStream().available()); equal(SIZE, p.getErrorStream().available()); THROWS(IOException.class, - new Fun(){void f() throws IOException { - p.getOutputStream().write((byte) '!'); - p.getOutputStream().flush(); - }}); + () -> { p.getOutputStream().write((byte) '!'); + p.getOutputStream().flush();}); final byte[] bytes = new byte[SIZE + 1]; equal(SIZE, p.getInputStream().read(bytes)); @@ -2006,12 +1983,9 @@ public class Basic { InputStream[] streams = { p.getInputStream(), p.getErrorStream() }; for (final InputStream in : streams) { Fun[] ops = { - new Fun(){void f() throws IOException { - in.read(); }}, - new Fun(){void f() throws IOException { - in.read(bytes); }}, - new Fun(){void f() throws IOException { - in.available(); }} + () -> in.read(), + () -> in.read(bytes), + () -> in.available() }; for (Fun op : ops) { try { @@ -2215,21 +2189,17 @@ public class Basic { } catch (Throwable t) { unexpected(t); } THROWS(SecurityException.class, - new Fun() { void f() throws IOException { - policy.setPermissions(/* Nothing */); - System.getenv("foo");}}, - new Fun() { void f() throws IOException { - policy.setPermissions(/* Nothing */); - System.getenv();}}, - new Fun() { void f() throws IOException { - policy.setPermissions(/* Nothing */); - new ProcessBuilder("echo").start();}}, - new Fun() { void f() throws IOException { - policy.setPermissions(/* Nothing */); - Runtime.getRuntime().exec("echo");}}, - new Fun() { void f() throws IOException { - policy.setPermissions(new RuntimePermission("getenv.bar")); - System.getenv("foo");}}); + () -> { policy.setPermissions(/* Nothing */); + System.getenv("foo");}, + () -> { policy.setPermissions(/* Nothing */); + System.getenv();}, + () -> { policy.setPermissions(/* Nothing */); + new ProcessBuilder("echo").start();}, + () -> { policy.setPermissions(/* Nothing */); + Runtime.getRuntime().exec("echo");}, + () -> { policy.setPermissions( + new RuntimePermission("getenv.bar")); + System.getenv("foo");}); try { policy.setPermissions(new RuntimePermission("getenv.foo")); @@ -2246,18 +2216,16 @@ public class Basic { = new FilePermission("<>", "execute"); THROWS(SecurityException.class, - new Fun() { void f() throws IOException { - // environment permission by itself insufficient - policy.setPermissions(new RuntimePermission("getenv.*")); - ProcessBuilder pb = new ProcessBuilder("env"); - pb.environment().put("foo","bar"); - pb.start();}}, - new Fun() { void f() throws IOException { - // exec permission by itself insufficient - policy.setPermissions(execPermission); - ProcessBuilder pb = new ProcessBuilder("env"); - pb.environment().put("foo","bar"); - pb.start();}}); + () -> { // environment permission by itself insufficient + policy.setPermissions(new RuntimePermission("getenv.*")); + ProcessBuilder pb = new ProcessBuilder("env"); + pb.environment().put("foo","bar"); + pb.start();}, + () -> { // exec permission by itself insufficient + policy.setPermissions(execPermission); + ProcessBuilder pb = new ProcessBuilder("env"); + pb.environment().put("foo","bar"); + pb.start();}); try { // Both permissions? OK. @@ -2585,7 +2553,7 @@ public class Basic { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private static abstract class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java b/jdk/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java new file mode 100644 index 00000000000..ad8a87a13d3 --- /dev/null +++ b/jdk/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8039916 + * @summary Test that a call to getType() on an AnnotatedType returned from an + * Executable.getAnnotated* returns the same type as the corresponding + * Executable.getGeneric* call. + * @run testng TestExecutableGetAnnotatedType + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.testng.Assert.*; + +public class TestExecutableGetAnnotatedType { + @Test(dataProvider = "genericExecutableData") + public void testGenericMethodExceptions(Executable e) throws Exception { + testExceptions(e); + } + + @Test(dataProvider = "executableData") + public void testMethodExceptions(Executable e) throws Exception { + testExceptions(e); + } + + @Test(dataProvider = "genericExecutableData") + public void testGenericMethodParameterTypes(Executable e) throws Exception { + testMethodParameters(e); + } + + @Test(dataProvider = "executableData") + public void testMethodParameterTypes(Executable e) throws Exception { + testMethodParameters(e); + } + + @Test(dataProvider = "genericExecutableData") + public void testGenericParameterTypes(Executable e) throws Exception { + testParameters(e.getParameters()); + } + + @Test(dataProvider = "executableData") + public void testParameterTypes(Executable e) throws Exception { + testParameters(e.getParameters()); + } + + // should test constructors as well, see JDK-8044629 + @Test(dataProvider = "genericMethodData") + public void testGenericReceiverType(Executable e) throws Exception { + testReceiverType0(e); + } + + // should test constructors as well, see JDK-8044629 + @Test(dataProvider = "methodData") + public void testReceiverType(Executable e) throws Exception { + testReceiverType0(e); + } + + @Test(dataProvider = "genericMethodData") + public void testGenericMethodReturnType(Object o) throws Exception { + // testng gets confused if the param to this method has type Method + Method m = (Method)o; + testReturnType(m); + } + + @Test(dataProvider = "methodData") + public void testMethodReturnType(Object o) throws Exception { + // testng gets confused if the param to this method has type Method + Method m = (Method)o; + testReturnType(m); + } + + private void testExceptions(Executable e) { + Type[] ts = e.getGenericExceptionTypes(); + AnnotatedType[] ats = e.getAnnotatedExceptionTypes(); + assertEquals(ts.length, ats.length); + + for (int i = 0; i < ts.length; i++) { + Type t = ts[i]; + AnnotatedType at = ats[i]; + assertSame(at.getType(), t, e.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); + } + } + + private void testMethodParameters(Executable e) { + Type[] ts = e.getGenericParameterTypes(); + AnnotatedType[] ats = e.getAnnotatedParameterTypes(); + assertEquals(ts.length, ats.length); + + for (int i = 0; i < ts.length; i++) { + Type t = ts[i]; + AnnotatedType at = ats[i]; + assertSame(at.getType(), t, e.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); + } + } + + private void testParameters(Parameter[] params) { + for (Parameter p : params) { + Type t = p.getParameterizedType(); + AnnotatedType at = p.getAnnotatedType(); + assertSame(at.getType(), t, p.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); + } + } + + private void testReceiverType0(Executable e) { + if (Modifier.isStatic(e.getModifiers())) + assertNull(e.getAnnotatedReceiverType()); + else + assertSame(e.getAnnotatedReceiverType().getType(), e.getDeclaringClass()); + } + + private void testReturnType(Method m) { + Type t = m.getGenericReturnType(); + AnnotatedType at = m.getAnnotatedReturnType(); + assertSame(at.getType(), t, m.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); + } + + @DataProvider + public Object[][] methodData() throws Exception { + return filterData(Arrays.stream(Methods1.class.getMethods()), Methods1.class) + .toArray(new Object[0][0]); + } + + @DataProvider + public Object[][] genericMethodData() throws Exception { + return filterData(Arrays.stream(GenericMethods1.class.getMethods()), GenericMethods1.class) + .toArray(new Object[0][0]); + } + + @DataProvider + public Object[][] executableData() throws Exception { + @SuppressWarnings("raw") + List l = filterData(Arrays.stream(Methods1.class.getMethods()), Methods1.class); + l.addAll(filterData(Arrays.stream(Methods1.class.getConstructors()), Methods1.class)); + l.addAll(filterData(Arrays.stream(Ctors1.class.getConstructors()), Ctors1.class)); + return ((List)l).toArray(new Object[0][0]); + } + + @DataProvider + public Object[][] genericExecutableData() throws Exception { + @SuppressWarnings("raw") + List l = filterData(Arrays.stream(GenericMethods1.class.getMethods()), GenericMethods1.class); + l.addAll(filterData(Arrays.stream(GenericMethods1.class.getConstructors()), GenericMethods1.class)); + l.addAll(filterData(Arrays.stream(GenericCtors1.class.getConstructors()), GenericCtors1.class)); + return ((List)l).toArray(new Object[0][0]); + } + + private List filterData(Stream l, Class c) { + return l.filter(m -> (m.getDeclaringClass() == c)) // remove object methods + .map(m -> { Object[] o = new Object[1]; o[0] = m; return o; }) + .collect(Collectors.toList()); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @interface TA {} + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @interface TB {} + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @interface TC {} + + public static class Methods1 { + public static void m1() throws Error, RuntimeException {;} + public static long m2(int a, double b) throws Error, RuntimeException { return 0L; } + public static Object m3(String s, List l) throws Error, RuntimeException { return null; } + public static Object m4(String s, List l) { return null; } + public static Object m4(String s, List l, boolean ... b){ return null; } + + public static void m10() throws @TA Error, @TB @TC RuntimeException {;} + public static @TB long m20(@TC int a, @TA double b) throws @TA Error, @TB @TC RuntimeException { return 0L; } + public static @TC Object m30(@TA String s, @TB List l) throws @TA Error, @TB @TC RuntimeException { return null; } + public static @TA Object m40(@TB String s, @TC List<@TA String> l) { return null; } + public static @TA Object m40(@TB String s, @TC List<@TA String> l, @TB boolean ... b) { return null; } + + public Methods1(int a, double b) {} + public Methods1(String s, List l, boolean ... b) {} + public Methods1(@TC long a, @TA float b) {} + public Methods1(@TA int i, @TB String s, @TC List<@TA String> l, @TB boolean ... b) {} + } + + // test default ctor + public static class Ctors1 { + } + + public static class GenericMethods1 { + public E m1(E e, Object o) throws Error, RuntimeException { return null; } + public E m2(List e, int i) throws Error, RuntimeException { return null; } + public E m3(double d, List e) throws Error, RuntimeException { return null; } + public E m4(byte[] b, GenericMethods1 e) { return null; } + public E m5(GenericMethods1 e) { return null; } + public E m6(char c, E e) { return null; } + public E m7(char c, E e, byte ... b) { return null; } + + public static M n1(M e) { return null; } + public static M n2(List e) { return null; } + public static M n3(List e) throws Error, M { return null; } + public static M n4(GenericMethods1 e) throws Error, RuntimeException { return null; } + public static M n5(GenericMethods1 e) { return null; } + public static M n6(M e) { return null; } + + public E o1(E e) { return null; } + public E o2(List e) { return null; } + public E o3(GenericMethods1 this, List e) throws M, N { return null; } + public E o4(GenericMethods1 e) throws Error, RuntimeException { return null; } + public E o5(GenericMethods1 e) { return null; } + public E o6(E e) { return null; } + + + // with annotations + public @TA E m10(E e, @TC Object o) throws @TA Error, @TB @TC RuntimeException { return null; } + public @TB E m20(@TA List<@TA ? extends @TA List> e, @TC int i) throws @TA Error, @TB @TC RuntimeException { return null; } + public @TB E m30(@TC double d, List e) throws @TA Error, @TB @TC RuntimeException { return null; } + public <@TA E extends @TA List> @TA E m40(@TA byte @TB [] b, GenericMethods1<@TA ? extends E> e) { return null; } + public <@TB E extends @TB List> E m50(@TA GenericMethods1 e) { return null; } + public <@TB E extends @TA List & Cloneable> E m60(@TC char c, E e) { return null; } + public <@TB E extends @TA List & Cloneable> E m70(@TC char c, E e, @TA @TB byte ... b) { return null; } + + public static <@TA M> @TA M n10(M e) { return null; } + public static <@TA @TB @TC M> M n20(List<@TA ? extends List> e) { return null; } + @TA @TB @TC public static M n30(List<@TB M> e) throws @TA Error, @TB @TC M { return null; } + public static <@TC M extends Number> M n40(GenericMethods1 e) throws @TA Error, @TB @TC RuntimeException { return null; } + @TA public static M n50(GenericMethods1 e) { return null; } + public static <@TA M extends @TB List & @TC @TB Cloneable> M n60(M e) { return null; } + + public <@TC M> E o10(@TA E e) { return null; } + public @TA E o20(@TB List<@TB ? extends @TB List> e) { return null; } + @TC public @TB E o30(@TA @TB @TC GenericMethods1 this, List e) throws @TA M, @TB @TC N { return null; } + public <@TA M extends Number> E o40(GenericMethods1 e) throws @TA Error, @TB @TC RuntimeException { return null; } + public E o50(GenericMethods1<@TA ? super Number> e) { return null; } + public <@TA M extends @TB List & @TC Cloneable> E o60(@TA E e) { return null; } + + + // ctors + public GenericMethods1(List e, int i) throws Error, RuntimeException { } + public GenericMethods1(char c, E e, byte ... b) { } + @TC public GenericMethods1(List<@TC E> e) throws @TA M, @TB @TC N { } + public <@TA M extends @TB List & @TC Cloneable> GenericMethods1(@TA E e, @TB M m) throws @TA Exception { } + public <@TA M extends @TB List & @TC Cloneable> GenericMethods1(@TA E e, @TB M m, @TC byte ... b) throws Exception { } + } + + // test default ctor + public static class GenericCtors1 { + } +} diff --git a/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java b/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java index dc34bba24b9..33acc50d667 100644 --- a/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java +++ b/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java @@ -33,11 +33,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.nio.file.Files; -import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFileAttributeView; -import java.util.stream.Stream; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -163,34 +161,66 @@ public class LogGeneratedClassesTest extends LUtils { tr.assertZero("Should still return 0"); } + private static boolean isWriteableDirectory(Path p) { + if (!Files.isDirectory(p)) { + return false; + } + Path test = p.resolve(Paths.get("test")); + try { + Files.createFile(test); + assertTrue(Files.exists(test)); + return true; + } catch (IOException e) { + assertFalse(Files.exists(test)); + return false; + } finally { + if (Files.exists(test)) { + try { + Files.delete(test); + } catch (IOException e) { + throw new Error(e); + } + } + } + } + @Test public void testDumpDirNotWritable() throws IOException { - if (! Files.getFileStore(Paths.get(".")) - .supportsFileAttributeView(PosixFileAttributeView.class)) { + if (!Files.getFileStore(Paths.get(".")) + .supportsFileAttributeView(PosixFileAttributeView.class)) { // No easy way to setup readonly directory without POSIX // We would like to skip the test with a cause with // throw new SkipException("Posix not supported"); // but jtreg will report failure so we just pass the test // which we can look at if jtreg changed its behavior + System.out.println("WARNING: POSIX is not supported. Skipping testDumpDirNotWritable test."); return; } Files.createDirectory(Paths.get("readOnly"), asFileAttribute(fromString("r-xr-xr-x"))); + try { + if (isWriteableDirectory(Paths.get("readOnly"))) { + // Skipping the test: it's allowed to write into read-only directory + // (e.g. current user is super user). + System.out.println("WARNING: readOnly directory is writeable. Skipping testDumpDirNotWritable test."); + return; + } - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", ".", - "-Djdk.internal.lambda.dumpProxyClasses=readOnly", - "-Djava.security.manager", - "com.example.TestLambda"); - assertEquals(tr.testOutput.stream() - .filter(s -> s.startsWith("WARNING")) - .peek(s -> assertTrue(s.contains("not writable"))) - .count(), - 1, "only show error once"); - tr.assertZero("Should still return 0"); - - TestUtil.removeAll(Paths.get("readOnly")); + TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), + "-cp", ".", + "-Djdk.internal.lambda.dumpProxyClasses=readOnly", + "-Djava.security.manager", + "com.example.TestLambda"); + assertEquals(tr.testOutput.stream() + .filter(s -> s.startsWith("WARNING")) + .peek(s -> assertTrue(s.contains("not writable"))) + .count(), + 1, "only show error once"); + tr.assertZero("Should still return 0"); + } finally { + TestUtil.removeAll(Paths.get("readOnly")); + } } @Test diff --git a/jdk/test/java/lang/invoke/lookup/SpecialStatic.java b/jdk/test/java/lang/invoke/lookup/SpecialStatic.java new file mode 100644 index 00000000000..57f55570752 --- /dev/null +++ b/jdk/test/java/lang/invoke/lookup/SpecialStatic.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8032400 + * @summary JSR292: invokeSpecial: InternalError attempting to lookup a method + * @compile -XDignore.symbol.file SpecialStatic.java + * @run junit test.java.lang.invoke.lookup.SpecialStatic + */ +package test.java.lang.invoke.lookup; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import jdk.internal.org.objectweb.asm.*; +import org.junit.Test; +import static jdk.internal.org.objectweb.asm.Opcodes.*; +import static org.junit.Assert.*; + +/** + * Test case: + * class T1 { int m() { return 1; }} + * class T2 extends T1 { static int m() { return 2; }} + * class T3 extends T2 { int m() { return 3; }} + * + * T3::test { invokespecial T1.m() T3 } ==> T1::m + */ +public class SpecialStatic { + static class CustomClassLoader extends ClassLoader { + public Class loadClass(String name) throws ClassNotFoundException { + if (findLoadedClass(name) != null) { + return findLoadedClass(name); + } + + if ("T1".equals(name)) { + byte[] classFile = dumpT1(); + return defineClass("T1", classFile, 0, classFile.length); + } + if ("T2".equals(name)) { + byte[] classFile = dumpT2(); + return defineClass("T2", classFile, 0, classFile.length); + } + if ("T3".equals(name)) { + byte[] classFile = dumpT3(); + return defineClass("T3", classFile, 0, classFile.length); + } + + return super.loadClass(name); + } + } + + private static ClassLoader cl = new CustomClassLoader(); + private static Class t1, t3; + static { + try { + t1 = cl.loadClass("T1"); + t3 = cl.loadClass("T3"); + } catch (ClassNotFoundException e) { + throw new Error(e); + } + } + + public static void main(String[] args) throws Throwable { + SpecialStatic test = new SpecialStatic(); + test.testConstant(); + test.testFindSpecial(); + } + + @Test + public void testConstant() throws Throwable { + MethodHandle mh = (MethodHandle)t3.getDeclaredMethod("getMethodHandle").invoke(null); + int result = (int)mh.invoke(t3.newInstance()); + assertEquals(result, 1); // T1.m should be invoked. + } + + @Test + public void testFindSpecial() throws Throwable { + MethodHandles.Lookup lookup = (MethodHandles.Lookup)t3.getDeclaredMethod("getLookup").invoke(null); + MethodHandle mh = lookup.findSpecial(t1, "m", MethodType.methodType(int.class), t3); + int result = (int)mh.invoke(t3.newInstance()); + assertEquals(result, 1); // T1.m should be invoked. + } + + public static byte[] dumpT1() { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + cw.visit(52, ACC_PUBLIC + ACC_SUPER, "T1", null, "java/lang/Object", null); + + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + mv = cw.visitMethod(ACC_PUBLIC, "m", "()I", null, null); + mv.visitCode(); + mv.visitIntInsn(BIPUSH, 1); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + cw.visitEnd(); + return cw.toByteArray(); + } + + public static byte[] dumpT2() { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + cw.visit(52, ACC_PUBLIC + ACC_SUPER, "T2", null, "T1", null); + + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "T1", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "m", "()I", null, null); + mv.visitCode(); + mv.visitIntInsn(BIPUSH, 2); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + cw.visitEnd(); + return cw.toByteArray(); + } + + public static byte[] dumpT3() { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + cw.visit(52, ACC_PUBLIC + ACC_SUPER, "T3", null, "T2", null); + + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "T2", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + mv = cw.visitMethod(ACC_PUBLIC, "m", "()I", null, null); + mv.visitCode(); + mv.visitIntInsn(BIPUSH, 3); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + // getMethodHandle + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "getMethodHandle", "()Ljava/lang/invoke/MethodHandle;", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Handle(H_INVOKESPECIAL, "T1", "m", "()I")); + mv.visitInsn(ARETURN); + mv.visitMaxs(1, 0); + mv.visitEnd(); + + // getLookup + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "getLookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", null, null); + mv.visitCode(); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false); + mv.visitInsn(ARETURN); + mv.visitMaxs(1, 0); + mv.visitEnd(); + + cw.visitEnd(); + return cw.toByteArray(); + } +} diff --git a/jdk/test/java/nio/charset/StandardCharsets/Standard.java b/jdk/test/java/nio/charset/StandardCharsets/Standard.java index 66d1b112a1b..c570a955857 100644 --- a/jdk/test/java/nio/charset/StandardCharsets/Standard.java +++ b/jdk/test/java/nio/charset/StandardCharsets/Standard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,13 +99,6 @@ public class Standard { System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new Exception("Some tests failed"); } - private static abstract class Fun {abstract void f() throws Throwable;} - private static void THROWS(Class k, Fun... fs) { - for (Fun f : fs) - try { f.f(); fail("Expected " + k.getName() + " not thrown"); } - catch (Throwable t) { - if (k.isAssignableFrom(t.getClass())) pass(); - else unexpected(t);}} static byte[] serializedForm(Object obj) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/jdk/test/java/util/Collection/BiggernYours.java b/jdk/test/java/util/Collection/BiggernYours.java index 24ce930e713..37bbe072c7a 100644 --- a/jdk/test/java/util/Collection/BiggernYours.java +++ b/jdk/test/java/util/Collection/BiggernYours.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -236,13 +236,6 @@ public class BiggernYours { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private static abstract class Fun {abstract void f() throws Throwable;} - static void THROWS(Class k, Fun... fs) { - for (Fun f : fs) - try { f.f(); fail("Expected " + k.getName() + " not thrown"); } - catch (Throwable t) { - if (k.isAssignableFrom(t.getClass())) pass(); - else unexpected(t);}} private static abstract class CheckedThread extends Thread { abstract void realRun() throws Throwable; public void run() { diff --git a/jdk/test/java/util/Collection/IteratorAtEnd.java b/jdk/test/java/util/Collection/IteratorAtEnd.java index fffc7f70fa1..be3a7e116cc 100644 --- a/jdk/test/java/util/Collection/IteratorAtEnd.java +++ b/jdk/test/java/util/Collection/IteratorAtEnd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,9 +84,9 @@ public class IteratorAtEnd { try { final Iterator it = c.iterator(); THROWS(NoSuchElementException.class, - new Fun() {void f() { while (true) it.next(); }}); + () -> { while (true) it.next(); }); try { it.remove(); } - catch (UnsupportedOperationException _) { return; } + catch (UnsupportedOperationException exc) { return; } pass(); } catch (Throwable t) { unexpected(t); } @@ -96,10 +96,9 @@ public class IteratorAtEnd { final ListIterator it = list.listIterator(0); it.next(); final Object x = it.previous(); - THROWS(NoSuchElementException.class, - new Fun() {void f() { it.previous(); }}); + THROWS(NoSuchElementException.class, () -> it.previous()); try { it.remove(); } - catch (UnsupportedOperationException _) { return; } + catch (UnsupportedOperationException exc) { return; } pass(); check(! list.get(0).equals(x)); } catch (Throwable t) { unexpected(t); } @@ -108,10 +107,9 @@ public class IteratorAtEnd { final ListIterator it = list.listIterator(list.size()); it.previous(); final Object x = it.next(); - THROWS(NoSuchElementException.class, - new Fun() {void f() { it.next(); }}); + THROWS(NoSuchElementException.class, () -> it.next()); try { it.remove(); } - catch (UnsupportedOperationException _) { return; } + catch (UnsupportedOperationException exc) { return; } pass(); check(! list.get(list.size()-1).equals(x)); } catch (Throwable t) { unexpected(t); } @@ -132,7 +130,7 @@ public class IteratorAtEnd { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private static abstract class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/Collection/MOAT.java b/jdk/test/java/util/Collection/MOAT.java index f50682fea24..f55a1e87745 100644 --- a/jdk/test/java/util/Collection/MOAT.java +++ b/jdk/test/java/util/Collection/MOAT.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,10 +117,8 @@ public class MOAT { final List emptyArray = Arrays.asList(new Integer[]{}); testCollection(emptyArray); testEmptyList(emptyArray); - THROWS(IndexOutOfBoundsException.class, - new Fun(){void f(){ emptyArray.set(0,1); }}); - THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ emptyArray.add(0,1); }}); + THROWS(IndexOutOfBoundsException.class, () -> emptyArray.set(0,1)); + THROWS(UnsupportedOperationException.class, () -> emptyArray.add(0,1)); List noOne = nCopies(0,1); testCollection(noOne); @@ -204,8 +202,7 @@ public class MOAT { if (rnd.nextBoolean()) check(! it.hasNext()); - THROWS(NoSuchElementException.class, - new Fun(){void f(){ it.next(); }}); + THROWS(NoSuchElementException.class, () -> it.next()); try { it.remove(); } catch (IllegalStateException ignored) { pass(); } @@ -232,16 +229,15 @@ public class MOAT { private static void testImmutableCollection(final Collection c) { THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ c.add(99); }}, - new Fun(){void f(){ c.addAll(singleton(99)); }}); + () -> c.add(99), + () -> c.addAll(singleton(99))); if (! c.isEmpty()) { final Integer first = c.iterator().next(); THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ c.clear(); }}, - new Fun(){void f(){ c.remove(first); }}, - new Fun(){void f(){ c.removeAll(singleton(first)); }}, - new Fun(){void f(){ c.retainAll(emptyList()); }} - ); + () -> c.clear(), + () -> c.remove(first), + () -> c.removeAll(singleton(first)), + () -> c.retainAll(emptyList())); } } @@ -253,17 +249,17 @@ public class MOAT { testList(c); testImmutableCollection(c); THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ c.set(0,42); }}, - new Fun(){void f(){ c.add(0,42); }}, - new Fun(){void f(){ c.addAll(0,singleton(86)); }}); + () -> c.set(0,42), + () -> c.add(0,42), + () -> c.addAll(0,singleton(86))); if (! c.isEmpty()) THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ - Iterator it = c.iterator(); - it.next(); it.remove();}}, - new Fun(){void f(){ - ListIterator it = c.listIterator(); - it.next(); it.remove();}}); + () -> { Iterator it = c.iterator(); + it.next(); + it.remove(); }, + () -> { ListIterator it = c.listIterator(); + it.next(); + it.remove(); }); } private static void clear(Collection c) { @@ -290,19 +286,19 @@ public class MOAT { private static void testImmutableMap(final Map m) { THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ m.put(1,1); }}, - new Fun(){void f(){ m.putAll(singletonMap(1,1)); }}); + () -> m.put(1,1), + () -> m.putAll(singletonMap(1,1))); if (! m.isEmpty()) { final Integer first = m.keySet().iterator().next(); THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ m.remove(first); }}, - new Fun(){void f(){ m.clear(); }}); + () -> m.remove(first), + () -> m.clear()); final Map.Entry me = m.entrySet().iterator().next(); Integer key = me.getKey(); Integer val = me.getValue(); THROWS(UnsupportedOperationException.class, - new Fun(){void f(){ me.setValue(3); }}); + () -> me.setValue(3)); equal(key, me.getKey()); equal(val, me.getValue()); } @@ -492,9 +488,9 @@ public class MOAT { // insert, query, remove element at head if (isEmpty) { THROWS(NoSuchElementException.class, - new Fun(){void f(){ deq.getFirst(); }}, - new Fun(){void f(){ deq.element(); }}, - new Fun(){void f(){ deq.iterator().next(); }}); + () -> deq.getFirst(), + () -> deq.element(), + () -> deq.iterator().next()); check(deq.peekFirst() == null); check(deq.peek() == null); } else { @@ -546,9 +542,9 @@ public class MOAT { } if (isEmpty) { THROWS(NoSuchElementException.class, - new Fun(){void f(){ deq.getFirst(); }}, - new Fun(){void f(){ deq.element(); }}, - new Fun(){void f(){ deq.iterator().next(); }}); + () -> deq.getFirst(), + () -> deq.element(), + () -> deq.iterator().next()); check(deq.peekFirst() == null); check(deq.peek() == null); } else { @@ -571,8 +567,7 @@ public class MOAT { // insert, query, remove element at tail if (isEmpty) { check(deq.peekLast() == null); - THROWS(NoSuchElementException.class, - new Fun(){void f(){ deq.getLast(); }}); + THROWS(NoSuchElementException.class, () -> deq.getLast()); } else { check(deq.peekLast() != e); check(deq.getLast() != e); @@ -615,8 +610,7 @@ public class MOAT { } if (isEmpty) { check(deq.peekLast() == null); - THROWS(NoSuchElementException.class, - new Fun(){void f(){ deq.getLast(); }}); + THROWS(NoSuchElementException.class, () -> deq.getLast()); } else { check(deq.peekLast() != e); check(deq.getLast() != e); @@ -649,17 +643,17 @@ public class MOAT { if (isList) { check(!asList.listIterator().hasPrevious()); THROWS(NoSuchElementException.class, - new Fun(){void f(){ asList.listIterator().previous(); }}); + () -> asList.listIterator().previous()); } THROWS(NoSuchElementException.class, - new Fun(){void f(){ deq.iterator().next(); }}, - new Fun(){void f(){ deq.element(); }}, - new Fun(){void f(){ deq.getFirst(); }}, - new Fun(){void f(){ deq.getLast(); }}, - new Fun(){void f(){ deq.pop(); }}, - new Fun(){void f(){ deq.remove(); }}, - new Fun(){void f(){ deq.removeFirst(); }}, - new Fun(){void f(){ deq.removeLast(); }}); + () -> deq.iterator().next(), + () -> deq.element(), + () -> deq.getFirst(), + () -> deq.getLast(), + () -> deq.pop(), + () -> deq.remove(), + () -> deq.removeFirst(), + () -> deq.removeLast()); check(deq.poll() == null); check(deq.pollFirst() == null); @@ -728,8 +722,8 @@ public class MOAT { l.listIterator(0); l.listIterator(l.size()); THROWS(IndexOutOfBoundsException.class, - new Fun(){void f(){l.listIterator(-1);}}, - new Fun(){void f(){l.listIterator(l.size() + 1);}}); + () -> l.listIterator(-1), + () -> l.listIterator(l.size() + 1)); if (l instanceof AbstractList) { try { @@ -1004,22 +998,22 @@ public class MOAT { ? (ConcurrentMap) m : null; List fs = new ArrayList(); - fs.add(new Fun(){void f(){ check(! m.containsKey(null));}}); - fs.add(new Fun(){void f(){ equal(m.remove(null), null);}}); - fs.add(new Fun(){void f(){ equal(m.get(null), null);}}); - if (cm != null) { - fs.add(new Fun(){void f(){ check(! cm.remove(null,null));}});} + fs.add(() -> check(! m.containsKey(null))); + fs.add(() -> equal(m.remove(null), null)); + fs.add(() -> equal(m.get(null), null)); + if (cm != null) + fs.add(() -> check(! cm.remove(null,null))); throwsConsistently(NullPointerException.class, fs); fs.clear(); final Map sm = singletonMap(null,1); - fs.add(new Fun(){void f(){ equal(m.put(null,1), null); m.clear();}}); - fs.add(new Fun(){void f(){ m.putAll(sm); m.clear();}}); + fs.add(() -> { equal(m.put(null,1), null); m.clear();}); + fs.add(() -> { m.putAll(sm); m.clear();}); if (cm != null) { - fs.add(new Fun(){void f(){ check(! cm.remove(null,null));}}); - fs.add(new Fun(){void f(){ equal(cm.putIfAbsent(null,1), 1);}}); - fs.add(new Fun(){void f(){ equal(cm.replace(null,1), null);}}); - fs.add(new Fun(){void f(){ equal(cm.replace(null,1, 1), 1);}}); + fs.add(() -> check(! cm.remove(null,null))); + fs.add(() -> equal(cm.putIfAbsent(null,1), 1)); + fs.add(() -> equal(cm.replace(null,1), null)); + fs.add(() -> equal(cm.replace(null,1, 1), 1)); } throwsConsistently(NullPointerException.class, fs); } @@ -1180,8 +1174,7 @@ public class MOAT { equalNext(it, 3); equalNext(it, 1); check(! it.hasNext()); - THROWS(NoSuchElementException.class, - new Fun(){void f(){it.next();}}); + THROWS(NoSuchElementException.class, () -> it.next()); } { @@ -1191,8 +1184,7 @@ public class MOAT { check(it.hasNext()); equal(it.next().getKey(), 3); check(it.hasNext()); equal(it.next().getKey(), 1); check(! it.hasNext()); - THROWS(NoSuchElementException.class, - new Fun(){void f(){it.next();}}); + THROWS(NoSuchElementException.class, () -> it.next()); } prepMapForDescItrTests(m); @@ -1262,8 +1254,7 @@ public class MOAT { equalNext(it, 3); equalNext(it, 1); check(! it.hasNext()); - THROWS(NoSuchElementException.class, - new Fun(){void f(){it.next();}}); + THROWS(NoSuchElementException.class, () -> it.next()); } prepSetForDescItrTests(s); @@ -1365,7 +1356,7 @@ public class MOAT { System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new Exception("Some tests failed"); } - private static abstract class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} private static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/Collections/AsLifoQueue.java b/jdk/test/java/util/Collections/AsLifoQueue.java index ddb98a74517..59c08e85c75 100644 --- a/jdk/test/java/util/Collections/AsLifoQueue.java +++ b/jdk/test/java/util/Collections/AsLifoQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,8 +56,7 @@ public class AsLifoQueue { equal(q.size(), 3); check(! q.offer("d")); equal(q.size(), 3); - THROWS(IllegalStateException.class, - new Fun(){void f(){ q.add("d"); }}); + THROWS(IllegalStateException.class, () -> q.add("d")); equal(q.size(), 3); equal(q.toString(), "[c, b, a]"); equal(q.peek(), "c"); @@ -66,8 +65,7 @@ public class AsLifoQueue { equal(q.poll(), "b"); equal(q.peek(), "a"); equal(q.remove(), "a"); - THROWS(NoSuchElementException.class, - new Fun(){void f(){ q.remove(); }}); + THROWS(NoSuchElementException.class, () -> q.remove()); equal(q.poll(), null); check(q.isEmpty()); equal(q.size(), 0); @@ -88,7 +86,7 @@ public class AsLifoQueue { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - static abstract class Fun { abstract void f() throws Throwable; } + interface Fun {void f() throws Throwable;} private static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/HashMap/PutNullKey.java b/jdk/test/java/util/HashMap/PutNullKey.java new file mode 100644 index 00000000000..72aade00186 --- /dev/null +++ b/jdk/test/java/util/HashMap/PutNullKey.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8046085 + * @summary Ensure that when trees are being used for collisions that null key + * insertion still works. + */ + +import java.util.*; +import java.util.stream.IntStream; + +public class PutNullKey { + + // Initial capacity of map + // Should be >= the map capacity for treeifying, see HashMap/ConcurrentMap.MIN_TREEIFY_CAPACITY + static final int INITIAL_CAPACITY = 64; + + // Maximum size of map + // Should be > the treeify threshold, see HashMap/ConcurrentMap.TREEIFY_THRESHOLD + static final int SIZE = 256; + + // Load factor of map + // A value 1.0 will ensure that a new threshold == capacity + static final float LOAD_FACTOR = 1.0f; + + public static class CollidingHash implements Comparable { + + private final int value; + + public CollidingHash(int value) { + this.value = value; + } + + @Override + public int hashCode() { + // intentionally bad hashcode. Force into first bin. + return 0; + } + + @Override + public boolean equals(Object o) { + if (null == o) { + return false; + } + + if (o.getClass() != CollidingHash.class) { + return false; + } + + return value == ((CollidingHash) o).value; + } + + @Override + public int compareTo(CollidingHash o) { + return value - o.value; + } + } + + public static void main(String[] args) throws Exception { + Map m = new HashMap<>(INITIAL_CAPACITY, LOAD_FACTOR); + IntStream.range(0, SIZE) + .mapToObj(CollidingHash::new) + .forEach(e -> { m.put(e, e); }); + + // kaboom? + m.put(null, null); + } +} diff --git a/jdk/test/java/util/NavigableMap/LockStep.java b/jdk/test/java/util/NavigableMap/LockStep.java index adb8b1978c9..62ffc72877d 100644 --- a/jdk/test/java/util/NavigableMap/LockStep.java +++ b/jdk/test/java/util/NavigableMap/LockStep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -236,8 +236,8 @@ public class LockStep { Comparator cmp = comparator(s); if (s.isEmpty()) { THROWS(NoSuchElementException.class, - new Fun(){void f(){ s.first(); }}, - new Fun(){void f(){ s.last(); }}); + () -> s.first(), + () -> s.last()); equal(null, s.lower(1)); equal(null, s.floor(1)); equal(null, s.ceiling(1)); @@ -265,8 +265,7 @@ public class LockStep { }; for (final Iterator it : its) if (maybe(4)) - THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + THROWS(IllegalStateException.class, () -> it.remove()); Object prev = null; for (Object e : s) { check(s.contains(e)); @@ -284,7 +283,7 @@ public class LockStep { for (final Iterator it : its) { if (maybe(2)) check(! it.hasNext()); - Fun fun = new Fun(){void f(){ it.next(); }}; + Fun fun = () -> it.next(); THROWS(NoSuchElementException.class, fun, fun, fun); } } @@ -380,8 +379,8 @@ public class LockStep { Comparator cmp = comparator(m); if (m.isEmpty()) { THROWS(NoSuchElementException.class, - new Fun(){void f(){ m.firstKey(); }}, - new Fun(){void f(){ m.lastKey(); }}); + () -> m.firstKey(), + () -> m.lastKey()); equal(null, m.firstEntry()); equal(null, m.lastEntry()); equal(null, m.pollFirstEntry()); @@ -430,8 +429,7 @@ public class LockStep { Iterator[] its = concat(kits, vits, eits); for (final Iterator it : its) if (maybe(4)) - THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + THROWS(IllegalStateException.class, () -> it.remove()); Map.Entry prev = null; for (Map.Entry e : (Set) m.entrySet()) { Object k = e.getKey(); @@ -459,7 +457,7 @@ public class LockStep { for (final Iterator it : its) { if (maybe(2)) check(! it.hasNext()); - Fun fun = new Fun(){void f(){ it.next(); }}; + Fun fun = () -> it.next(); THROWS(NoSuchElementException.class, fun, fun, fun); } } @@ -633,7 +631,7 @@ public class LockStep { } static Fun remover(final Iterator it) { - return new Fun(){void f(){ it.remove(); }}; + return () -> it.remove(); } static MapFrobber randomRemover(NavigableMap m) { @@ -663,7 +661,7 @@ public class LockStep { it.remove(); if (maybe(2)) THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + () -> it.remove()); } checkUnusedKey(m, k);}}, new MapFrobber() {void frob(NavigableMap m) { @@ -673,7 +671,7 @@ public class LockStep { it.remove(); if (maybe(2)) THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + () -> it.remove()); } checkUnusedKey(m, k);}}, new MapFrobber() {void frob(NavigableMap m) { @@ -718,7 +716,7 @@ public class LockStep { it.remove(); if (maybe(2)) THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + () -> it.remove()); } checkUnusedElt(s, e);}}, new SetFrobber() {void frob(NavigableSet s) { @@ -728,7 +726,7 @@ public class LockStep { it.remove(); if (maybe(2)) THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + () -> it.remove()); } checkUnusedElt(s, e);}}, new SetFrobber() {void frob(NavigableSet s) { @@ -738,7 +736,7 @@ public class LockStep { it.remove(); if (maybe(2)) THROWS(IllegalStateException.class, - new Fun(){void f(){ it.remove(); }}); + () -> it.remove()); } checkUnusedElt(s, e);}} }; @@ -769,12 +767,12 @@ public class LockStep { for (final NavigableMap m : maps) { final Object e = usedKey(m); THROWS(IllegalArgumentException.class, - new Fun(){void f(){m.subMap(e,true,e,false) - .subMap(e,true,e,true);}}, - new Fun(){void f(){m.subMap(e,false,e,true) - .subMap(e,true,e,true);}}, - new Fun(){void f(){m.tailMap(e,false).tailMap(e,true);}}, - new Fun(){void f(){m.headMap(e,false).headMap(e,true);}}); + () -> {m.subMap(e,true,e,false) + .subMap(e,true,e,true);}, + () -> {m.subMap(e,false,e,true) + .subMap(e,true,e,true);}, + () -> m.tailMap(e,false).tailMap(e,true), + () -> m.headMap(e,false).headMap(e,true)); } //System.out.printf("%s%n", m1); for (int i = size; i > 0; i--) { @@ -811,12 +809,12 @@ public class LockStep { for (final NavigableSet s : sets) { final Object e = usedElt(s); THROWS(IllegalArgumentException.class, - new Fun(){void f(){s.subSet(e,true,e,false) - .subSet(e,true,e,true);}}, - new Fun(){void f(){s.subSet(e,false,e,true) - .subSet(e,true,e,true);}}, - new Fun(){void f(){s.tailSet(e,false).tailSet(e,true);}}, - new Fun(){void f(){s.headSet(e,false).headSet(e,true);}}); + () -> {s.subSet(e,true,e,false) + .subSet(e,true,e,true);}, + () -> {s.subSet(e,false,e,true) + .subSet(e,true,e,true);}, + () -> s.tailSet(e,false).tailSet(e,true), + () -> s.headSet(e,false).headSet(e,true)); } //System.out.printf("%s%n", s1); for (int i = size; i > 0; i--) { @@ -847,7 +845,7 @@ public class LockStep { System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new Exception("Some tests failed"); } - static abstract class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/PriorityQueue/ForgetMeNot.java b/jdk/test/java/util/PriorityQueue/ForgetMeNot.java index f6970fa73f7..7778d1d793d 100644 --- a/jdk/test/java/util/PriorityQueue/ForgetMeNot.java +++ b/jdk/test/java/util/PriorityQueue/ForgetMeNot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,16 +37,14 @@ public class ForgetMeNot { private static void noMoreElements(final Iterator it) { for (int j = 0; j < 2; j++) { - THROWS(NoSuchElementException.class, - new Fun() { void f() { it.next(); }}); + THROWS(NoSuchElementException.class, () -> it.next()); check(! it.hasNext()); } } private static void removeIsCurrentlyIllegal(final Iterator it) { for (int j = 0; j < 2; j++) { - THROWS(IllegalStateException.class, - new Fun() { void f() { it.remove(); }}); + THROWS(IllegalStateException.class, () -> it.remove()); } } @@ -146,7 +144,7 @@ public class ForgetMeNot { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private static abstract class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/Properties/LoadAndStoreXML.java b/jdk/test/java/util/Properties/LoadAndStoreXML.java index 5353c645b81..241a783053f 100644 --- a/jdk/test/java/util/Properties/LoadAndStoreXML.java +++ b/jdk/test/java/util/Properties/LoadAndStoreXML.java @@ -32,6 +32,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; @@ -47,6 +48,7 @@ import java.util.Properties; import java.util.PropertyPermission; public class LoadAndStoreXML { + static final String bomChar = "\uFEFF"; /** * Simple policy implementation that grants a set of permissions to @@ -125,13 +127,14 @@ public class LoadAndStoreXML { * Sanity test that properties saved with Properties#storeToXML can be * read with Properties#loadFromXML. */ - static void testLoadAndStore(String encoding) throws IOException { + static void testLoadAndStore(String encoding, boolean appendBOM) throws IOException { System.out.println("testLoadAndStore, encoding=" + encoding); Properties props = new Properties(); + props.put("k0", "\u6C34"); props.put("k1", "foo"); props.put("k2", "bar"); - props.put("k3", "\\u0020\\u0391\\u0392\\u0393\\u0394\\u0395\\u0396\\u0397"); + props.put("k3", "\u0020\u0391\u0392\u0393\u0394\u0395\u0396\u0397"); props.put("k4", "\u7532\u9aa8\u6587"); props.put("k5", "/lib/jaxp.properties"); @@ -141,7 +144,17 @@ public class LoadAndStoreXML { throw new RuntimeException("OutputStream closed by storeToXML"); Properties p = new Properties(); - TestInputStream in = new TestInputStream(out.toByteArray()); + TestInputStream in; + if (appendBOM) { + byte[] byteOrderMark = bomChar.getBytes(Charset.forName(encoding)); + byte[] outArray = out.toByteArray(); + byte[] inputArray = new byte[byteOrderMark.length + outArray.length]; + System.arraycopy(byteOrderMark, 0, inputArray, 0, byteOrderMark.length); + System.arraycopy(outArray, 0, inputArray, byteOrderMark.length, outArray.length); + in = new TestInputStream(inputArray); + } else { + in = new TestInputStream(out.toByteArray()); + } p.loadFromXML(in); if (in.isOpen()) throw new RuntimeException("InputStream not closed by loadFromXML"); @@ -231,8 +244,12 @@ public class LoadAndStoreXML { public static void main(String[] args) throws IOException { - testLoadAndStore("UTF-8"); - testLoadAndStore("UTF-16"); + testLoadAndStore("UTF-8", false); + testLoadAndStore("UTF-16", false); + testLoadAndStore("UTF-16BE", false); + testLoadAndStore("UTF-16LE", false); + testLoadAndStore("UTF-16BE", true); + testLoadAndStore("UTF-16LE", true); testLoadWithoutEncoding(); testLoadWithBadEncoding(); testStoreWithBadEncoding(); @@ -250,7 +267,7 @@ public class LoadAndStoreXML { Policy.setPolicy(p); System.setSecurityManager(new SecurityManager()); try { - testLoadAndStore("UTF-8"); + testLoadAndStore("UTF-8", false); } finally { // turn off security manager and restore policy System.setSecurityManager(null); diff --git a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java index cdfd9e88bdb..94ad2a172bb 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,19 +69,13 @@ public class Interrupt { (BlockingDeque) q : null; q.clear(); List fs = new ArrayList(); - fs.add(new Fun() { void f() throws Throwable - { q.take(); }}); - fs.add(new Fun() { void f() throws Throwable - { q.poll(60, SECONDS); }}); + fs.add(() -> q.take()); + fs.add(() -> q.poll(60, SECONDS)); if (deq != null) { - fs.add(new Fun() { void f() throws Throwable - { deq.takeFirst(); }}); - fs.add(new Fun() { void f() throws Throwable - { deq.takeLast(); }}); - fs.add(new Fun() { void f() throws Throwable - { deq.pollFirst(7, SECONDS); }}); - fs.add(new Fun() { void f() throws Throwable - { deq.pollLast(7, SECONDS); }}); + fs.add(() -> deq.takeFirst()); + fs.add(() -> deq.takeLast()); + fs.add(() -> deq.pollFirst(7, SECONDS)); + fs.add(() -> deq.pollLast(7, SECONDS)); } checkInterrupted(fs); @@ -92,19 +86,13 @@ public class Interrupt { catch (Throwable t) { unexpected(t); } fs.clear(); - fs.add(new Fun() { void f() throws Throwable - { q.put(1); }}); - fs.add(new Fun() { void f() throws Throwable - { q.offer(1, 7, SECONDS); }}); + fs.add(() -> q.put(1)); + fs.add(() -> q.offer(1, 7, SECONDS)); if (deq != null) { - fs.add(new Fun() { void f() throws Throwable - { deq.putFirst(1); }}); - fs.add(new Fun() { void f() throws Throwable - { deq.putLast(1); }}); - fs.add(new Fun() { void f() throws Throwable - { deq.offerFirst(1, 7, SECONDS); }}); - fs.add(new Fun() { void f() throws Throwable - { deq.offerLast(1, 7, SECONDS); }}); + fs.add(() -> deq.putFirst(1)); + fs.add(() -> deq.putLast(1)); + fs.add(() -> deq.offerFirst(1, 7, SECONDS)); + fs.add(() -> deq.offerLast(1, 7, SECONDS)); } checkInterrupted(fs); } catch (Throwable t) { @@ -135,5 +123,5 @@ public class Interrupt { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private abstract static class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} } diff --git a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java index 123481985b2..b6b8d637b2f 100644 --- a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java +++ b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,10 +40,8 @@ public class Basic { equal(barrier.getNumberWaiting(), 0); THROWS(BrokenBarrierException.class, - new Fun() { public void f() throws Throwable { - barrier.await(); }}, - new Fun() { public void f() throws Throwable { - barrier.await(100, MILLISECONDS); }}); + () -> barrier.await(), + () -> barrier.await(100, MILLISECONDS)); } private static void reset(CyclicBarrier barrier) { @@ -417,7 +415,7 @@ public class Basic { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - abstract static class Fun { abstract void f() throws Throwable; } + interface Fun {void f() throws Throwable;} private static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/concurrent/Executors/Throws.java b/jdk/test/java/util/concurrent/Executors/Throws.java index 424b60d6d72..402472df366 100644 --- a/jdk/test/java/util/concurrent/Executors/Throws.java +++ b/jdk/test/java/util/concurrent/Executors/Throws.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,33 +45,31 @@ public class Throws { ThreadPoolExecutor executor) {}}; final RejectedExecutionHandler nullHandler = null; - THROWS( - NullPointerException.class, - new Fun(){void f(){ newFixedThreadPool(3, null); }}, - new Fun(){void f(){ newCachedThreadPool(null); }}, - new Fun(){void f(){ newSingleThreadScheduledExecutor(null); }}, - new Fun(){void f(){ newScheduledThreadPool(0, null); }}, - new Fun(){void f(){ unconfigurableExecutorService(null); }}, - new Fun(){void f(){ unconfigurableScheduledExecutorService(null); }}, - new Fun(){void f(){ callable(null, "foo"); }}, - new Fun(){void f(){ callable((Runnable) null); }}, - new Fun(){void f(){ callable((PrivilegedAction) null); }}, - new Fun(){void f(){ callable((PrivilegedExceptionAction) null); }}, - new Fun(){void f(){ privilegedCallable((Callable) null); }}, - new Fun(){void f(){ new ScheduledThreadPoolExecutor(0, nullFactory); }}, - new Fun(){void f(){ new ScheduledThreadPoolExecutor(0, nullFactory, reh); }}, - new Fun(){void f(){ new ScheduledThreadPoolExecutor(0, fac, nullHandler); }}); + THROWS(NullPointerException.class, + () -> newFixedThreadPool(3, null), + () -> newCachedThreadPool(null), + () -> newSingleThreadScheduledExecutor(null), + () -> newScheduledThreadPool(0, null), + () -> unconfigurableExecutorService(null), + () -> unconfigurableScheduledExecutorService(null), + () -> callable(null, "foo"), + () -> callable((Runnable) null), + () -> callable((PrivilegedAction) null), + () -> callable((PrivilegedExceptionAction) null), + () -> privilegedCallable((Callable) null), + () -> new ScheduledThreadPoolExecutor(0, nullFactory), + () -> new ScheduledThreadPoolExecutor(0, nullFactory, reh), + () -> new ScheduledThreadPoolExecutor(0, fac, nullHandler)); - THROWS( - IllegalArgumentException.class, - new Fun(){void f(){ newFixedThreadPool(-42); }}, - new Fun(){void f(){ newFixedThreadPool(0) ; }}, - new Fun(){void f(){ newFixedThreadPool(-42, fac); }}, - new Fun(){void f(){ newFixedThreadPool(0, fac); }}, - new Fun(){void f(){ newScheduledThreadPool(-42); }}, - new Fun(){void f(){ new ScheduledThreadPoolExecutor(-42); }}, - new Fun(){void f(){ new ScheduledThreadPoolExecutor(-42, reh); }}, - new Fun(){void f(){ new ScheduledThreadPoolExecutor(-42, fac, reh); }}); + THROWS(IllegalArgumentException.class, + () -> newFixedThreadPool(-42), + () -> newFixedThreadPool(0), + () -> newFixedThreadPool(-42, fac), + () -> newFixedThreadPool(0, fac), + () -> newScheduledThreadPool(-42), + () -> new ScheduledThreadPoolExecutor(-42), + () -> new ScheduledThreadPoolExecutor(-42, reh), + () -> new ScheduledThreadPoolExecutor(-42, fac, reh)); try { newFixedThreadPool(1).shutdownNow(); pass(); } catch (Throwable t) { unexpected(t); } @@ -122,7 +120,7 @@ public class Throws { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private abstract static class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/concurrent/FutureTask/Customized.java b/jdk/test/java/util/concurrent/FutureTask/Customized.java index 15159ca0aab..a1afd9015a1 100644 --- a/jdk/test/java/util/concurrent/FutureTask/Customized.java +++ b/jdk/test/java/util/concurrent/FutureTask/Customized.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,8 +70,7 @@ public class Customized { check(! task.isDone()); check(! task.isCancelled()); THROWS(TimeoutException.class, - new Fun(){void f() throws Throwable { - task.get(0L, TimeUnit.SECONDS); }}); + () -> task.get(0L, TimeUnit.SECONDS)); } static void checkDone(final FutureTask task) { @@ -86,20 +85,16 @@ public class Customized { check(task.isDone()); check(task.isCancelled()); THROWS(CancellationException.class, - new Fun(){void f() throws Throwable { - task.get(0L, TimeUnit.SECONDS); }}, - new Fun(){void f() throws Throwable { - task.get(); }}); + () -> task.get(0L, TimeUnit.SECONDS), + () -> task.get()); } static void checkThrew(final FutureTask task) { check(task.isDone()); check(! task.isCancelled()); THROWS(ExecutionException.class, - new Fun(){void f() throws Throwable { - task.get(0L, TimeUnit.SECONDS); }}, - new Fun(){void f() throws Throwable { - task.get(); }}); + () -> task.get(0L, TimeUnit.SECONDS), + () -> task.get()); } static void cancel(FutureTask task, boolean mayInterruptIfRunning) { @@ -203,7 +198,7 @@ public class Customized { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private abstract static class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java index aed43ac68a8..d89ee28333e 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,7 @@ public class ConfigChanges { check(((ThreadPoolExecutor) es).isTerminating() || es.isTerminated()); THROWS(RejectedExecutionException.class, - new Fun() {void f() {es.execute(nop);}}); + () -> es.execute(nop)); } } catch (Throwable t) { unexpected(t); } } @@ -241,7 +241,7 @@ public class ConfigChanges { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private abstract static class Fun {abstract void f() throws Throwable;} + interface Fun {void f() throws Throwable;} static void THROWS(Class k, Fun... fs) { for (Fun f : fs) try { f.f(); fail("Expected " + k.getName() + " not thrown"); } diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java index dbf82f22ece..780aa4eeb06 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,13 +81,6 @@ public class ShutdownNowExecuteRace { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private abstract static class Fun {abstract void f() throws Throwable;} - static void THROWS(Class k, Fun... fs) { - for (Fun f : fs) - try { f.f(); fail("Expected " + k.getName() + " not thrown"); } - catch (Throwable t) { - if (k.isAssignableFrom(t.getClass())) pass(); - else unexpected(t);}} private abstract static class CheckedThread extends Thread { abstract void realRun() throws Throwable; public void run() { diff --git a/jdk/test/sun/nio/ch/ServerSocketAdaptorTest.java b/jdk/test/sun/nio/ch/ServerSocketAdaptorTest.java new file mode 100644 index 00000000000..062fc784520 --- /dev/null +++ b/jdk/test/sun/nio/ch/ServerSocketAdaptorTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024832 + */ + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.SocketException; +import java.nio.channels.ServerSocketChannel; + +public class ServerSocketAdaptorTest { + + public static void main(String[] args) throws IOException { + + String message = null; + + try (ServerSocket s = new ServerSocket()) { + s.accept(); + throw new AssertionError(); + } catch (IOException e) { + message = e.getMessage(); + } + + try (ServerSocket ss = ServerSocketChannel.open().socket()) { + + assert !ss.isBound() : "the assumption !ss.isBound() doesn't hold"; + + try { + ss.accept(); + throw new AssertionError(); + } catch (Exception e) { + if (e instanceof SocketException && message.equals(e.getMessage())) { + return; + } else { + throw new AssertionError( + "Expected to throw SocketException with a particular message", e); + } + } + } + } +} diff --git a/jdk/test/sun/nio/cs/FindOneCharEncoderBugs.java b/jdk/test/sun/nio/cs/FindOneCharEncoderBugs.java index 0b244e8c0e6..95ce0fca6fa 100644 --- a/jdk/test/sun/nio/cs/FindOneCharEncoderBugs.java +++ b/jdk/test/sun/nio/cs/FindOneCharEncoderBugs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,13 +155,6 @@ public class FindOneCharEncoderBugs { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - private static abstract class Fun {abstract void f() throws Throwable;} - static void THROWS(Class k, Fun... fs) { - for (Fun f : fs) - try { f.f(); fail("Expected " + k.getName() + " not thrown"); } - catch (Throwable t) { - if (k.isAssignableFrom(t.getClass())) pass(); - else unexpected(t);}} private static abstract class CheckedThread extends Thread { abstract void realRun() throws Throwable; public void run() { diff --git a/jdk/test/sun/security/krb5/auto/KDC.java b/jdk/test/sun/security/krb5/auto/KDC.java index 356f84e9856..686e238579e 100644 --- a/jdk/test/sun/security/krb5/auto/KDC.java +++ b/jdk/test/sun/security/krb5/auto/KDC.java @@ -141,6 +141,8 @@ public class KDC { private BlockingQueue q = new ArrayBlockingQueue<>(100); // Options private Map options = new HashMap<>(); + // Realm-specific krb5.conf settings + private List conf = new ArrayList<>(); private Thread thread1, thread2, thread3; DatagramSocket u1 = null; @@ -243,7 +245,7 @@ public class KDC { /** * Sets an option * @param key the option name - * @param obj the value + * @param value the value */ public void setOption(Option key, Object value) { if (value == null) { @@ -372,6 +374,13 @@ public class KDC { return kdc; } + /** + * Add realm-specific krb5.conf setting + */ + public void addConf(String s) { + conf.add(s); + } + /** * Writes a krb5.conf for one or more KDC that includes KDC locations for * each realm and the default realm name. You can also add extra strings @@ -397,6 +406,7 @@ public class KDC { * [realms] * REALM.NAME = { * kdc = host:port_number + * # realm-specific settings * } * * @@ -444,10 +454,10 @@ public class KDC { } } sb.append("\n[realms]\n"); - sb.append(realmLineForKDC(kdc)); + sb.append(kdc.realmLine()); for (Object o: more) { if (o instanceof KDC) { - sb.append(realmLineForKDC((KDC)o)); + sb.append(((KDC)o).realmLine()); } } FileOutputStream fos = new FileOutputStream(f); @@ -1133,14 +1143,16 @@ public class KDC { /** * Generates a line for a KDC to put inside [realms] of krb5.conf - * @param kdc the KDC - * @return REALM.NAME = { kdc = host:port } + * @return REALM.NAME = { kdc = host:port etc } */ - private static String realmLineForKDC(KDC kdc) { - return String.format("%s = {\n kdc = %s:%d\n}\n", - kdc.realm, - kdc.kdc, - kdc.port); + private String realmLine() { + StringBuilder sb = new StringBuilder(); + sb.append(realm).append(" = {\n kdc = ") + .append(kdc).append(':').append(port).append('\n'); + for (String s: conf) { + sb.append(" ").append(s).append('\n'); + } + return sb.append("}\n").toString(); } /** diff --git a/jdk/test/sun/security/krb5/auto/UdpTcp.java b/jdk/test/sun/security/krb5/auto/UdpTcp.java index e66f5d459fb..ae54b793527 100644 --- a/jdk/test/sun/security/krb5/auto/UdpTcp.java +++ b/jdk/test/sun/security/krb5/auto/UdpTcp.java @@ -43,9 +43,15 @@ public class UdpTcp { OneKDC kdc = new OneKDC(null); kdc.writeJAASConf(); - KDC.saveConfig(OneKDC.KRB5_CONF, kdc, - "udp_preference_limit = " - + (args[0].equals("UDP") ? "1000" : "100")); + // Two styles of kdc_timeout setting. One global, one realm-specific. + if (args[0].equals("UDP")) { + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "kdc_timeout = 10s"); + } else { + kdc.addConf("kdc_timeout = 10s"); + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "udp_preference_limit = 1"); + } Config.refresh(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); @@ -56,7 +62,7 @@ public class UdpTcp { for (String line: new String(bo.toByteArray()).split("\n")) { if (line.contains(">>> KDCCommunication")) { - if (!line.contains(args[0])) { + if (!line.contains(args[0]) || !line.contains("timeout=10000")) { throw new Exception("No " + args[0] + " in: " + line); } } diff --git a/jdk/test/sun/security/pkcs11/PKCS11Test.java b/jdk/test/sun/security/pkcs11/PKCS11Test.java index 3699f880456..f1b179b00f5 100644 --- a/jdk/test/sun/security/pkcs11/PKCS11Test.java +++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -457,7 +457,7 @@ public abstract class PKCS11Test { osMap.put("SunOS-x86-32", new String[]{"/usr/lib/mps/"}); osMap.put("SunOS-amd64-64", new String[]{"/usr/lib/mps/64/"}); osMap.put("Linux-i386-32", new String[]{ - "/usr/lib/i386-linux-gnu/", "/usr/lib/"}); + "/usr/lib/i386-linux-gnu/", "/usr/lib32/", "/usr/lib/"}); osMap.put("Linux-amd64-64", new String[]{ "/usr/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/nss/", "/usr/lib64/"}); diff --git a/jdk/test/sun/security/tools/jarsigner/certpolicy.sh b/jdk/test/sun/security/tools/jarsigner/certpolicy.sh new file mode 100644 index 00000000000..20cf92b1618 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/certpolicy.sh @@ -0,0 +1,80 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8036709 +# @summary Java 7 jarsigner displays warning about cert policy tree +# +# @run shell certpolicy.sh +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +KT="$TESTJAVA/bin/keytool $TESTTOOLVMOPTS \ + -keypass changeit -storepass changeit -keystore ks -keyalg rsa" +JS="$TESTJAVA/bin/jarsigner $TESTTOOLVMOPTS -storepass changeit -keystore ks" +JAR="$TESTJAVA/bin/jar $TESTTOOLVMOPTS" + +rm ks 2> /dev/null +$KT -genkeypair -alias ca -dname CN=CA -ext bc +$KT -genkeypair -alias int -dname CN=Int +$KT -genkeypair -alias ee -dname CN=EE + +# CertificatePolicies [[PolicyId: [1.2.3]], [PolicyId: [1.2.4]]] +# PolicyConstraints: [Require: 0; Inhibit: unspecified] +$KT -certreq -alias int | \ + $KT -gencert -rfc -alias ca \ + -ext 2.5.29.32="30 0C 30 04 06 02 2A 03 30 04 06 02 2A 04" \ + -ext "2.5.29.36=30 03 80 01 00" -ext bc | \ + $KT -import -alias int + +# CertificatePolicies [[PolicyId: [1.2.3]]] +$KT -certreq -alias ee | \ + $KT -gencert -rfc -alias int \ + -ext 2.5.29.32="30 06 30 04 06 02 2A 03" | \ + $KT -import -alias ee + +$KT -export -alias ee -rfc > cc +$KT -export -alias int -rfc >> cc +$KT -export -alias ca -rfc >> cc + +$KT -delete -alias int + +ERR='' +$JAR cvf a.jar cc + +# Make sure the certchain in the signed jar contains all 3 certs +$JS -strict -certchain cc a.jar ee -debug || ERR="sign" +$JS -strict -verify a.jar -debug || ERR="$ERR verify" + +if [ "$ERR" = "" ]; then + echo "Success" + exit 0 +else + echo "Failed: $ERR" + exit 1 +fi + diff --git a/jdk/test/sun/security/tools/keytool/autotest.sh b/jdk/test/sun/security/tools/keytool/autotest.sh index 90e0a66a268..8154af5939b 100644 --- a/jdk/test/sun/security/tools/keytool/autotest.sh +++ b/jdk/test/sun/security/tools/keytool/autotest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -72,6 +72,8 @@ case "$OS" in Linux ) if [ $B32 = true ]; then LIBNAME=`find_one \ + "/usr/lib32/libsoftokn3.so" \ + "/usr/lib32/nss/libsoftokn3.so" \ "/usr/lib/libsoftokn3.so" \ "/usr/lib/i386-linux-gnu/nss/libsoftokn3.so" \ "/usr/lib/nss/libsoftokn3.so"` diff --git a/jdk/test/sun/security/tools/keytool/weaksize.sh b/jdk/test/sun/security/tools/keytool/weaksize.sh new file mode 100644 index 00000000000..f095645976f --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/weaksize.sh @@ -0,0 +1,60 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8044755 +# @summary Add a test for algorithm constraints check in jarsigner +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# The sigalg used is MD2withRSA, which is obsolete. + +KT="$TESTJAVA/bin/keytool ${TESTTOOLVMOPTS} -keystore ks + -storepass changeit -keypass changeit + -keyalg rsa -sigalg MD2withRSA -debug" +JS="$TESTJAVA/bin/jarsigner ${TESTTOOLVMOPTS} -keystore ks + -storepass changeit -strict -debug" +JAR="$TESTJAVA/bin/jar ${TESTTOOLVMOPTS}" + +rm ks 2> /dev/null + +$KT -genkeypair -alias ca -dname CN=CA -ext bc +$KT -genkeypair -alias signer -dname CN=Signer + +$KT -certreq -alias signer | \ + $KT -gencert -alias ca -ext ku=dS -rfc | \ + $KT -importcert -alias signer + +$JAR cvf a.jar ks + +# We always trust a TrustedCertificateEntry +$JS a.jar ca || exit 1 + +# An end-entity cert must follow algorithm constraints +$JS a.jar signer && exit 2 + +exit 0 diff --git a/jdk/test/sun/security/tools/policytool/i18n.sh b/jdk/test/sun/security/tools/policytool/i18n.sh index cefa93ea762..536080b6438 100644 --- a/jdk/test/sun/security/tools/policytool/i18n.sh +++ b/jdk/test/sun/security/tools/policytool/i18n.sh @@ -77,7 +77,7 @@ echo "HELLO!" echo "Checking for $HOME/.java.policy" # 8015274 -if [ -e $HOME/.java.policy ]; then +if [ -f $HOME/.java.policy ]; then echo "You have a .java.policy file in your HOME directory" echo "The file must be removed before running this test" exit 1 diff --git a/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh b/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh index 921524be9e0..ab4cb16dc13 100644 --- a/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh +++ b/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh @@ -42,7 +42,7 @@ fi rm -f jrunscriptTest.out 2>/dev/null ${JRUNSCRIPT} -J-Djava.awt.headless=true -l nashorn > jrunscriptTest.out 2>&1 < 0 && htmlstr.startsWith("/..", previndex)) { + int prevEnd = 0; + do { + int match = docrootMatcher.start(); + // append htmlstr up to start of next {@docroot} + buf.append(htmlstr.substring(prevEnd, match)); + prevEnd = docrootMatcher.end(); + if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", prevEnd)) { // Insert the absolute link if {@docRoot} is followed by "/..". buf.append(configuration.docrootparent); - previndex += 3; + prevEnd += 3; } else { // Insert relative path where {@docRoot} was located buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath()); } // Append slash if next character is not a slash - if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') { + if (prevEnd < htmlstr.length() && htmlstr.charAt(prevEnd) != '/') { buf.append('/'); } - } + } while (docrootMatcher.find()); + buf.append(htmlstr.substring(prevEnd)); return buf.toString(); } + //where: + // Note: {@docRoot} is not case sensitive when passed in w/command line option: + private static final Pattern docrootPattern = + Pattern.compile(Pattern.quote("{@docroot}"), Pattern.CASE_INSENSITIVE); /** * Get the script to show or hide the All classes link. @@ -1690,13 +1687,13 @@ public class HtmlDocletWriter extends HtmlDocWriter { } //Redirect all relative links. - int end, begin = StringUtils.toLowerCase(text).indexOf("= 0){ StringBuilder textBuff = new StringBuilder(text); while(begin >=0){ if (textBuff.length() > begin + 2 && ! Character.isWhitespace(textBuff.charAt(begin+2))) { - begin = StringUtils.toLowerCase(textBuff.toString()).indexOf(""); - int end = lc.indexOf(""); - if(begin == -1 || end == -1 || end <= begin){ - return tag; - } else { - return tag.substring(begin + 6, end); - } - } - /** * {@inheritDoc} */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index eb4b43f3622..56296d458c6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -394,7 +394,7 @@ public class JavacTrees extends DocTrees { paramTypes = lb.toList(); } - ClassSymbol sym = (ClassSymbol) types.upperBound(tsym.type).tsym; + ClassSymbol sym = (ClassSymbol) types.cvarUpperBound(tsym.type).tsym; Symbol msym = (memberName == sym.name) ? findConstructor(sym, paramTypes) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java new file mode 100644 index 00000000000..4c19370386d --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java @@ -0,0 +1,537 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.code; + +import java.io.*; +import java.util.EnumSet; +import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileManager.Location; +import javax.tools.StandardJavaFileManager; + +import static javax.tools.StandardLocation.*; + +import com.sun.tools.javac.comp.Annotate; +import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.jvm.ClassReader; +import com.sun.tools.javac.util.*; + +import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Kinds.*; + +import static com.sun.tools.javac.main.Option.*; + +/** + * This class provides operations to locate class definitions + * from the source and class files on the paths provided to javac. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class ClassFinder { + /** The context key for the class finder. */ + protected static final Context.Key classFinderKey = new Context.Key<>(); + + ClassReader reader; + + Annotate annotate; + + /** Switch: verbose output. + */ + boolean verbose; + + /** + * Switch: cache completion failures unless -XDdev is used + */ + private boolean cacheCompletionFailure; + + /** + * Switch: prefer source files instead of newer when both source + * and class are available + **/ + protected boolean preferSource; + + /** + * Switch: Search classpath and sourcepath for classes before the + * bootclasspath + */ + protected boolean userPathsFirst; + + /** The log to use for verbose output + */ + final Log log; + + /** The symbol table. */ + Symtab syms; + + /** The name table. */ + final Names names; + + /** Force a completion failure on this name + */ + final Name completionFailureName; + + /** Access to files + */ + private final JavaFileManager fileManager; + + /** Factory for diagnostics + */ + JCDiagnostic.Factory diagFactory; + + /** Can be reassigned from outside: + * the completer to be used for ".java" files. If this remains unassigned + * ".java" files will not be loaded. + */ + public Completer sourceCompleter = null; + + /** The path name of the class file currently being read. + */ + protected JavaFileObject currentClassFile = null; + + /** The class or method currently being read. + */ + protected Symbol currentOwner = null; + + /** + * Completer that delegates to the complete-method of this class. + */ + private final Completer thisCompleter = new Completer() { + @Override + public void complete(Symbol sym) throws CompletionFailure { + ClassFinder.this.complete(sym); + } + }; + + public Completer getCompleter() { + return thisCompleter; + } + + /** Get the ClassFinder instance for this invocation. */ + public static ClassFinder instance(Context context) { + ClassFinder instance = context.get(classFinderKey); + if (instance == null) + instance = new ClassFinder(context); + return instance; + } + + /** Construct a new class reader. */ + protected ClassFinder(Context context) { + context.put(classFinderKey, this); + reader = ClassReader.instance(context); + names = Names.instance(context); + syms = Symtab.instance(context); + fileManager = context.get(JavaFileManager.class); + if (fileManager == null) + throw new AssertionError("FileManager initialization error"); + diagFactory = JCDiagnostic.Factory.instance(context); + + log = Log.instance(context); + annotate = Annotate.instance(context); + + Options options = Options.instance(context); + verbose = options.isSet(VERBOSE); + cacheCompletionFailure = options.isUnset("dev"); + preferSource = "source".equals(options.get("-Xprefer")); + userPathsFirst = options.isSet(XXUSERPATHSFIRST); + + + completionFailureName = + options.isSet("failcomplete") + ? names.fromString(options.get("failcomplete")) + : null; + } + +/************************************************************************ + * Loading Classes + ***********************************************************************/ + + /** Completion for classes to be loaded. Before a class is loaded + * we make sure its enclosing class (if any) is loaded. + */ + private void complete(Symbol sym) throws CompletionFailure { + if (sym.kind == TYP) { + ClassSymbol c = (ClassSymbol)sym; + c.members_field = new Scope.ErrorScope(c); // make sure it's always defined + annotate.enterStart(); + try { + completeOwners(c.owner); + completeEnclosing(c); + } finally { + // The flush needs to happen only after annotations + // are filled in. + annotate.enterDoneWithoutFlush(); + } + fillIn(c); + } else if (sym.kind == PCK) { + PackageSymbol p = (PackageSymbol)sym; + try { + fillIn(p); + } catch (IOException ex) { + throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); + } + } + if (!reader.filling) + annotate.flush(); // finish attaching annotations + } + + /** complete up through the enclosing package. */ + private void completeOwners(Symbol o) { + if (o.kind != PCK) completeOwners(o.owner); + o.complete(); + } + + /** + * Tries to complete lexically enclosing classes if c looks like a + * nested class. This is similar to completeOwners but handles + * the situation when a nested class is accessed directly as it is + * possible with the Tree API or javax.lang.model.*. + */ + private void completeEnclosing(ClassSymbol c) { + if (c.owner.kind == PCK) { + Symbol owner = c.owner; + for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) { + Symbol encl = owner.members().lookup(name).sym; + if (encl == null) + encl = syms.classes.get(TypeSymbol.formFlatName(name, owner)); + if (encl != null) + encl.complete(); + } + } + } + + /** Fill in definition of class `c' from corresponding class or + * source file. + */ + private void fillIn(ClassSymbol c) { + if (completionFailureName == c.fullname) { + throw new CompletionFailure(c, "user-selected completion failure by class name"); + } + currentOwner = c; + JavaFileObject classfile = c.classfile; + if (classfile != null) { + JavaFileObject previousClassFile = currentClassFile; + try { + if (reader.filling) { + Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile); + } + currentClassFile = classfile; + if (verbose) { + log.printVerbose("loading", currentClassFile.toString()); + } + if (classfile.getKind() == JavaFileObject.Kind.CLASS) { + reader.readClassFile(c); + } else { + if (sourceCompleter != null) { + sourceCompleter.complete(c); + } else { + throw new IllegalStateException("Source completer required to read " + + classfile.toUri()); + } + } + return; + } finally { + currentClassFile = previousClassFile; + } + } else { + JCDiagnostic diag = + diagFactory.fragment("class.file.not.found", c.flatname); + throw + newCompletionFailure(c, diag); + } + } + // where + /** Static factory for CompletionFailure objects. + * In practice, only one can be used at a time, so we share one + * to reduce the expense of allocating new exception objects. + */ + private CompletionFailure newCompletionFailure(TypeSymbol c, + JCDiagnostic diag) { + if (!cacheCompletionFailure) { + // log.warning("proc.messager", + // Log.getLocalizedString("class.file.not.found", c.flatname)); + // c.debug.printStackTrace(); + return new CompletionFailure(c, diag); + } else { + CompletionFailure result = cachedCompletionFailure; + result.sym = c; + result.diag = diag; + return result; + } + } + private CompletionFailure cachedCompletionFailure = + new CompletionFailure(null, (JCDiagnostic) null); + { + cachedCompletionFailure.setStackTrace(new StackTraceElement[0]); + } + + + /** Load a toplevel class with given fully qualified name + * The class is entered into `classes' only if load was successful. + */ + public ClassSymbol loadClass(Name flatname) throws CompletionFailure { + boolean absent = syms.classes.get(flatname) == null; + ClassSymbol c = syms.enterClass(flatname); + if (c.members_field == null && c.completer != null) { + try { + c.complete(); + } catch (CompletionFailure ex) { + if (absent) syms.classes.remove(flatname); + throw ex; + } + } + return c; + } + +/************************************************************************ + * Loading Packages + ***********************************************************************/ + + /** Include class corresponding to given class file in package, + * unless (1) we already have one the same kind (.class or .java), or + * (2) we have one of the other kind, and the given class file + * is older. + */ + protected void includeClassFile(PackageSymbol p, JavaFileObject file) { + if ((p.flags_field & EXISTS) == 0) + for (Symbol q = p; q != null && q.kind == PCK; q = q.owner) + q.flags_field |= EXISTS; + JavaFileObject.Kind kind = file.getKind(); + int seen; + if (kind == JavaFileObject.Kind.CLASS) + seen = CLASS_SEEN; + else + seen = SOURCE_SEEN; + String binaryName = fileManager.inferBinaryName(currentLoc, file); + int lastDot = binaryName.lastIndexOf("."); + Name classname = names.fromString(binaryName.substring(lastDot + 1)); + boolean isPkgInfo = classname == names.package_info; + ClassSymbol c = isPkgInfo + ? p.package_info + : (ClassSymbol) p.members_field.lookup(classname).sym; + if (c == null) { + c = syms.enterClass(classname, p); + if (c.classfile == null) // only update the file if's it's newly created + c.classfile = file; + if (isPkgInfo) { + p.package_info = c; + } else { + if (c.owner == p) // it might be an inner class + p.members_field.enter(c); + } + } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) { + // if c.classfile == null, we are currently compiling this class + // and no further action is necessary. + // if (c.flags_field & seen) != 0, we have already encountered + // a file of the same kind; again no further action is necessary. + if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0) + c.classfile = preferredFileObject(file, c.classfile); + } + c.flags_field |= seen; + } + + /** Implement policy to choose to derive information from a source + * file or a class file when both are present. May be overridden + * by subclasses. + */ + protected JavaFileObject preferredFileObject(JavaFileObject a, + JavaFileObject b) { + + if (preferSource) + return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b; + else { + long adate = a.getLastModified(); + long bdate = b.getLastModified(); + // 6449326: policy for bad lastModifiedTime in ClassReader + //assert adate >= 0 && bdate >= 0; + return (adate > bdate) ? a : b; + } + } + + /** + * specifies types of files to be read when filling in a package symbol + */ + protected EnumSet getPackageFileKinds() { + return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE); + } + + /** + * this is used to support javadoc + */ + protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) { + } + + protected Location currentLoc; // FIXME + + private boolean verbosePath = true; + + // Set to true when the currently selected file should be kept + private boolean preferCurrent; + + /** Load directory of package into members scope. + */ + private void fillIn(PackageSymbol p) throws IOException { + if (p.members_field == null) + p.members_field = new Scope(p); + + preferCurrent = false; + if (userPathsFirst) { + scanUserPaths(p); + preferCurrent = true; + scanPlatformPath(p); + } else { + scanPlatformPath(p); + scanUserPaths(p); + } + verbosePath = false; + } + + /** + * Scans class path and source path for files in given package. + */ + private void scanUserPaths(PackageSymbol p) throws IOException { + Set kinds = getPackageFileKinds(); + + Set classKinds = EnumSet.copyOf(kinds); + classKinds.remove(JavaFileObject.Kind.SOURCE); + boolean wantClassFiles = !classKinds.isEmpty(); + + Set sourceKinds = EnumSet.copyOf(kinds); + sourceKinds.remove(JavaFileObject.Kind.CLASS); + boolean wantSourceFiles = !sourceKinds.isEmpty(); + + boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH); + + if (verbose && verbosePath) { + if (fileManager instanceof StandardJavaFileManager) { + StandardJavaFileManager fm = (StandardJavaFileManager)fileManager; + if (haveSourcePath && wantSourceFiles) { + List path = List.nil(); + for (File file : fm.getLocation(SOURCE_PATH)) { + path = path.prepend(file); + } + log.printVerbose("sourcepath", path.reverse().toString()); + } else if (wantSourceFiles) { + List path = List.nil(); + for (File file : fm.getLocation(CLASS_PATH)) { + path = path.prepend(file); + } + log.printVerbose("sourcepath", path.reverse().toString()); + } + if (wantClassFiles) { + List path = List.nil(); + for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) { + path = path.prepend(file); + } + for (File file : fm.getLocation(CLASS_PATH)) { + path = path.prepend(file); + } + log.printVerbose("classpath", path.reverse().toString()); + } + } + } + + String packageName = p.fullname.toString(); + if (wantSourceFiles && !haveSourcePath) { + fillIn(p, CLASS_PATH, + fileManager.list(CLASS_PATH, + packageName, + kinds, + false)); + } else { + if (wantClassFiles) + fillIn(p, CLASS_PATH, + fileManager.list(CLASS_PATH, + packageName, + classKinds, + false)); + if (wantSourceFiles) + fillIn(p, SOURCE_PATH, + fileManager.list(SOURCE_PATH, + packageName, + sourceKinds, + false)); + } + } + + /** + * Scans platform class path for files in given package. + */ + private void scanPlatformPath(PackageSymbol p) throws IOException { + fillIn(p, PLATFORM_CLASS_PATH, + fileManager.list(PLATFORM_CLASS_PATH, + p.fullname.toString(), + EnumSet.of(JavaFileObject.Kind.CLASS), + false)); + } + // where + private void fillIn(PackageSymbol p, + Location location, + Iterable files) + { + currentLoc = location; + for (JavaFileObject fo : files) { + switch (fo.getKind()) { + case CLASS: + case SOURCE: { + // TODO pass binaryName to includeClassFile + String binaryName = fileManager.inferBinaryName(currentLoc, fo); + String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1); + if (SourceVersion.isIdentifier(simpleName) || + simpleName.equals("package-info")) + includeClassFile(p, fo); + break; + } + default: + extraFileActions(p, fo); + } + } + } + + /** + * Used for bad class definition files, such as bad .class files or + * for .java files with unexpected package or class names. + */ + public static class BadClassFile extends CompletionFailure { + private static final long serialVersionUID = 0; + + public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag, + JCDiagnostic.Factory diagFactory) { + super(sym, createBadClassFileDiagnostic(file, diag, diagFactory)); + } + // where + private static JCDiagnostic createBadClassFileDiagnostic( + JavaFileObject file, JCDiagnostic diag, JCDiagnostic.Factory diagFactory) { + String key = (file.getKind() == JavaFileObject.Kind.SOURCE + ? "bad.source.file.header" : "bad.class.file.header"); + return diagFactory.fragment(key, file, diag); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 7ef823c2157..220c276195c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 59e2e19d7d9..9ced8f07d83 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -50,7 +50,6 @@ import com.sun.tools.javac.code.Type.JCVoidType; import com.sun.tools.javac.code.Type.MethodType; import com.sun.tools.javac.code.Type.UnknownType; import com.sun.tools.javac.jvm.ByteCodes; -import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; @@ -470,8 +469,8 @@ public class Symtab { Scope scope = new Scope(predefClass); predefClass.members_field = scope; - // Get the initial completer for Symbols from the ClassReader - initialCompleter = ClassReader.instance(context).getCompleter(); + // Get the initial completer for Symbols from the ClassFinder + initialCompleter = ClassFinder.instance(context).getCompleter(); rootPackage.completer = initialCompleter; unnamedPackage.completer = initialCompleter; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index dba1b9cd2da..b89542a162f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -72,13 +72,28 @@ import static com.sun.tools.javac.code.TypeTag.*; public abstract class Type extends AnnoConstruct implements TypeMirror { /** Constant type: no type at all. */ - public static final JCNoType noType = new JCNoType(); + public static final JCNoType noType = new JCNoType() { + @Override + public String toString() { + return "none"; + } + }; /** Constant type: special type to be used during recovery of deferred expressions. */ - public static final JCNoType recoveryType = new JCNoType(); + public static final JCNoType recoveryType = new JCNoType(){ + @Override + public String toString() { + return "recovery"; + } + }; /** Constant type: special type to be used for marking stuck trees. */ - public static final JCNoType stuckType = new JCNoType(); + public static final JCNoType stuckType = new JCNoType() { + @Override + public String toString() { + return "stuck"; + } + }; public static final List noAnnotations = List.nil(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 2184d0c1490..783f6282d10 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -42,9 +42,8 @@ import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; -import com.sun.tools.javac.jvm.ClassReader; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.*; + import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Scope.*; @@ -84,7 +83,6 @@ public class Types { final boolean allowBoxing; final boolean allowCovariantReturns; final boolean allowObjectToPrimitiveCast; - final ClassReader reader; final Check chk; final Enter enter; JCDiagnostic.Factory diags; @@ -110,7 +108,6 @@ public class Types { allowBoxing = source.allowBoxing(); allowCovariantReturns = source.allowCovariantReturns(); allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); - reader = ClassReader.instance(context); chk = Check.instance(context); enter = Enter.instance(context); capturedName = names.fromString(""); @@ -121,37 +118,34 @@ public class Types { } // - // + // /** - * The "rvalue conversion".
- * The upper bound of most types is the type - * itself. Wildcards, on the other hand have upper - * and lower bounds. - * @param t a type - * @return the upper bound of the given type + * Get a wildcard's upper bound, returning non-wildcards unchanged. + * @param t a type argument, either a wildcard or a type */ - public Type upperBound(Type t) { - return upperBound.visit(t); + public Type wildUpperBound(Type t) { + if (t.hasTag(WILDCARD)) { + WildcardType w = (WildcardType) t; + if (w.isSuperBound()) + return w.bound == null ? syms.objectType : w.bound.bound; + else + return wildUpperBound(w.type); + } + else return t; } - // where - private final MapVisitor upperBound = new MapVisitor() { - @Override - public Type visitWildcardType(WildcardType t, Void ignored) { - if (t.isSuperBound()) - return t.bound == null ? syms.objectType : t.bound.bound; - else - return visit(t.type); - } + /** + * Get a capture variable's upper bound, returning other types unchanged. + * @param t a type + */ + public Type cvarUpperBound(Type t) { + if (t.hasTag(TYPEVAR)) { + TypeVar v = (TypeVar) t; + return v.isCaptured() ? cvarUpperBound(v.bound) : v; + } + else return t; + } - @Override - public Type visitCapturedType(CapturedType t, Void ignored) { - return visit(t.bound); - } - }; - //
- - // /** * Get a wildcard's lower bound, returning non-wildcards unchanged. * @param t a type argument, either a wildcard or a type @@ -163,9 +157,7 @@ public class Types { } else return t; } - // - // /** * Get a capture variable's lower bound, returning other types unchanged. * @param t a type @@ -897,7 +889,7 @@ public class Types { s.getAnnotationMirrors()); changed = true; } else if (s != orig) { - s = new WildcardType(upperBound(s), + s = new WildcardType(wildUpperBound(s), BoundKind.EXTENDS, syms.boundClass, s.getAnnotationMirrors()); @@ -1107,7 +1099,7 @@ public class Types { //check that u == t, where u has been set by Type.withTypeVar return s.isSuperBound() && !s.isExtendsBound() && - visit(t, upperBound(s)); + visit(t, wildUpperBound(s)); } } default: @@ -1134,7 +1126,7 @@ public class Types { return visit(s, t); if (s.isSuperBound() && !s.isExtendsBound()) - return visit(t, upperBound(s)) && visit(t, wildLowerBound(s)); + return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s)); if (t.isCompound() && s.isCompound()) { if (!visit(supertype(t), supertype(s))) @@ -1301,7 +1293,7 @@ public class Types { switch(wt.kind) { case UNBOUND: //similar to ? extends Object case EXTENDS: { - Type bound = upperBound(s); + Type bound = wildUpperBound(s); undetvar.addBound(InferenceBound.UPPER, bound, this); break; } @@ -1362,28 +1354,6 @@ public class Types { // where private TypeRelation containsType = new TypeRelation() { - private Type U(Type t) { - while (t.hasTag(WILDCARD)) { - WildcardType w = (WildcardType)t; - if (w.isSuperBound()) - return w.bound == null ? syms.objectType : w.bound.bound; - else - t = w.type; - } - return t; - } - - private Type L(Type t) { - while (t.hasTag(WILDCARD)) { - WildcardType w = (WildcardType)t; - if (w.isExtendsBound()) - return syms.botType; - else - t = w.type; - } - return t; - } - public Boolean visitType(Type t, Type s) { if (s.isPartial()) return containedBy(s, t); @@ -1395,13 +1365,13 @@ public class Types { // System.err.println(); // System.err.format(" does %s contain %s?%n", t, s); // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", -// upperBound(s), s, t, U(t), +// wildUpperBound(s), s, t, wildUpperBound(t), // t.isSuperBound() -// || isSubtypeNoCapture(upperBound(s), U(t))); +// || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))); // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", -// L(t), t, s, wildLowerBound(s), +// wildLowerBound(t), t, s, wildLowerBound(s), // t.isExtendsBound() -// || isSubtypeNoCapture(L(t), wildLowerBound(s))); +// || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))); // System.err.println(); // } @@ -1413,8 +1383,9 @@ public class Types { // debugContainsType(t, s); return isSameWildcard(t, s) || isCaptureOf(s, t) - || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) && - (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); + || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) && + // TODO: JDK-8039214, cvarUpperBound call here is incorrect + (t.isSuperBound() || isSubtypeNoCapture(cvarUpperBound(wildUpperBound(s)), wildUpperBound(t)))); } } @@ -1532,7 +1503,7 @@ public class Types { @Override public Boolean visitWildcardType(WildcardType t, Type s) { - return isCastable(upperBound(t), s, warnStack.head); + return isCastable(wildUpperBound(t), s, warnStack.head); } @Override @@ -1773,12 +1744,12 @@ public class Types { if (t.isExtendsBound()) { if (s.isExtendsBound()) - return !isCastableRecursive(t.type, upperBound(s)); + return !isCastableRecursive(t.type, wildUpperBound(s)); else if (s.isSuperBound()) return notSoftSubtypeRecursive(wildLowerBound(s), t.type); } else if (t.isSuperBound()) { if (s.isExtendsBound()) - return notSoftSubtypeRecursive(t.type, upperBound(s)); + return notSoftSubtypeRecursive(t.type, wildUpperBound(s)); } return false; } @@ -1814,7 +1785,7 @@ public class Types { noWarnings); } if (!s.hasTag(WILDCARD)) - s = upperBound(s); + s = cvarUpperBound(s); return !isSubtype(t, relaxBound(s)); } @@ -1871,7 +1842,7 @@ public class Types { // public boolean isArray(Type t) { while (t.hasTag(WILDCARD)) - t = upperBound(t); + t = wildUpperBound(t); return t.hasTag(ARRAY); } @@ -1881,7 +1852,7 @@ public class Types { public Type elemtype(Type t) { switch (t.getTag()) { case WILDCARD: - return elemtype(upperBound(t)); + return elemtype(wildUpperBound(t)); case ARRAY: return ((ArrayType)t).elemtype; case FORALL: @@ -2083,7 +2054,7 @@ public class Types { @Override public Type visitWildcardType(WildcardType t, Symbol sym) { - return memberType(upperBound(t), sym); + return memberType(wildUpperBound(t), sym); } @Override @@ -2211,7 +2182,7 @@ public class Types { @Override public Type visitWildcardType(WildcardType t, Boolean recurse) { final List annos = t.getAnnotationMirrors(); - Type erased = erasure(upperBound(t), recurse); + Type erased = erasure(wildUpperBound(t), recurse); if (!annos.isEmpty()) { erased = erased.annotatedType(annos); } @@ -2420,8 +2391,7 @@ public class Types { if (t.hasErasedSupertypes()) { t.interfaces_field = erasureRecursive(interfaces); } else if (formals.nonEmpty()) { - t.interfaces_field = - upperBounds(subst(interfaces, formals, actuals)); + t.interfaces_field = subst(interfaces, formals, actuals); } else { t.interfaces_field = interfaces; @@ -2990,7 +2960,7 @@ public class Types { t.getAnnotationMirrors()); } else { Type st = subst(supertype(t)); - List is = upperBounds(subst(interfaces(t))); + List is = subst(interfaces(t)); if (st == supertype(t) && is == interfaces(t)) return t; else @@ -3007,7 +2977,7 @@ public class Types { return t; } else { if (t.isExtendsBound() && bound.isExtendsBound()) - bound = upperBound(bound); + bound = wildUpperBound(bound); return new WildcardType(bound, t.kind, syms.boundClass, t.bound, t.getAnnotationMirrors()); } @@ -3461,8 +3431,8 @@ public class Types { TypePair pair = new TypePair(c1, c2); Type m; if (mergeCache.add(pair)) { - m = new WildcardType(lub(upperBound(act1.head), - upperBound(act2.head)), + m = new WildcardType(lub(wildUpperBound(act1.head), + wildUpperBound(act2.head)), BoundKind.EXTENDS, syms.boundClass, Type.noAnnotations); @@ -4044,16 +4014,6 @@ public class Types { // // - private List upperBounds(List ss) { - if (ss.isEmpty()) return ss; - Type head = upperBound(ss.head); - List tail = upperBounds(ss.tail); - if (head != ss.head || tail != ss.tail) - return tail.prepend(head); - else - return ss; - } - private boolean sideCast(Type from, Type to, Warner warn) { // We are casting from type $from$ to type $to$, which are // non-final unrelated types. This method @@ -4210,7 +4170,7 @@ public class Types { @Override public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { if (source.isExtendsBound()) - adaptRecursive(upperBound(source), upperBound(target)); + adaptRecursive(wildUpperBound(source), wildUpperBound(target)); else if (source.isSuperBound()) adaptRecursive(wildLowerBound(source), wildLowerBound(target)); return null; @@ -4227,7 +4187,7 @@ public class Types { val = isSubtype(wildLowerBound(val), wildLowerBound(target)) ? target : val; } else if (val.isExtendsBound() && target.isExtendsBound()) { - val = isSubtype(upperBound(val), upperBound(target)) + val = isSubtype(wildUpperBound(val), wildUpperBound(target)) ? val : target; } else if (!isSameType(val, target)) { throw new AdaptFailure(); @@ -4338,7 +4298,7 @@ public class Types { } public Type visitType(Type t, Void s) { - return high ? upperBound(t) : t; + return t; } @Override @@ -4736,7 +4696,7 @@ public class Types { assembleClassSig(rawOuter ? types.erasure(outer) : outer); - append('.'); + append(rawOuter ? '$' : '.'); Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); append(rawOuter ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength()) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 335704eaef4..ba72525a70f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1176,7 +1176,7 @@ public class Attr extends JCTree.Visitor { //the Formal Parameter of a for-each loop is not in the scope when //attributing the for-each expression; we mimick this by attributing //the for-each expression first (against original scope). - Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv)); + Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv)); attribStat(tree.var, loopEnv); chk.checkNonVoid(tree.pos(), exprType); Type elemtype = types.elemtype(exprType); // perhaps expr is an array? @@ -1193,7 +1193,7 @@ public class Attr extends JCTree.Visitor { List iterableParams = base.allparams(); elemtype = iterableParams.isEmpty() ? syms.objectType - : types.upperBound(iterableParams.head); + : types.wildUpperBound(iterableParams.head); } } chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type); @@ -2060,7 +2060,7 @@ public class Attr extends JCTree.Visitor { tree.constructor = constructor.baseSymbol(); final TypeSymbol csym = clazztype.tsym; - ResultInfo diamondResult = new ResultInfo(MTH, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) { + ResultInfo diamondResult = new ResultInfo(pkind, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) { @Override public void report(DiagnosticPosition _unused, JCDiagnostic details) { enclosingContext.report(tree.clazz, @@ -4678,16 +4678,30 @@ public class Attr extends JCTree.Visitor { private void initTypeIfNeeded(JCTree that) { if (that.type == null) { if (that.hasTag(METHODDEF)) { - that.type = dummyMethodType(); + that.type = dummyMethodType((JCMethodDecl)that); } else { that.type = syms.unknownType; } } } + /* Construct a dummy method type. If we have a method declaration, + * and the declared return type is void, then use that return type + * instead of UNKNOWN to avoid spurious error messages in lambda + * bodies (see:JDK-8041704). + */ + private Type dummyMethodType(JCMethodDecl md) { + Type restype = syms.unknownType; + if (md != null && md.restype.hasTag(TYPEIDENT)) { + JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype; + if (prim.typetag == VOID) + restype = syms.voidType; + } + return new MethodType(List.nil(), restype, + List.nil(), syms.methodClass); + } private Type dummyMethodType() { - return new MethodType(List.nil(), syms.unknownType, - List.nil(), syms.methodClass); + return dummyMethodType(null); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 1b412e39405..7cfb78ec5dd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -282,7 +282,7 @@ public class Check { */ public Type completionError(DiagnosticPosition pos, CompletionFailure ex) { log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue()); - if (ex instanceof ClassReader.BadClassFile + if (ex instanceof ClassFinder.BadClassFile && !suppressAbortOnBadClassFile) throw new Abort(); else return syms.errType; } @@ -621,10 +621,10 @@ public class Check { if (a.isUnbound()) { return true; } else if (!a.hasTag(WILDCARD)) { - a = types.upperBound(a); + a = types.cvarUpperBound(a); return types.isSubtype(a, bound); } else if (a.isExtendsBound()) { - return types.isCastable(bound, types.upperBound(a), types.noWarnings); + return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings); } else if (a.isSuperBound()) { return !types.notSoftSubtype(types.wildLowerBound(a), bound); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 6265199a8d7..151794853f6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -1221,25 +1221,102 @@ public class DeferredAttr extends JCTree.Visitor { } //slow path + Symbol sym = quicklyResolveMethod(env, tree); + + if (sym == null) { + result = ArgumentExpressionKind.POLY; + return; + } + + result = analyzeCandidateMethods(sym, ArgumentExpressionKind.PRIMITIVE, + argumentKindAnalyzer); + } + //where + private boolean isSimpleReceiver(JCTree rec) { + switch (rec.getTag()) { + case IDENT: + return true; + case SELECT: + return isSimpleReceiver(((JCFieldAccess)rec).selected); + case TYPEAPPLY: + case TYPEARRAY: + return true; + case ANNOTATED_TYPE: + return isSimpleReceiver(((JCAnnotatedType)rec).underlyingType); + case APPLY: + return true; + default: + return false; + } + } + private ArgumentExpressionKind reduce(ArgumentExpressionKind kind) { + return argumentKindAnalyzer.reduce(result, kind); + } + MethodAnalyzer argumentKindAnalyzer = + new MethodAnalyzer() { + @Override + public ArgumentExpressionKind process(MethodSymbol ms) { + return ArgumentExpressionKind.methodKind(ms, types); + } + @Override + public ArgumentExpressionKind reduce(ArgumentExpressionKind kind1, + ArgumentExpressionKind kind2) { + switch (kind1) { + case PRIMITIVE: return kind2; + case NO_POLY: return kind2.isPoly() ? kind2 : kind1; + case POLY: return kind1; + default: + Assert.error(); + return null; + } + } + @Override + public boolean shouldStop(ArgumentExpressionKind result) { + return result.isPoly(); + } + }; + + @Override + public void visitLiteral(JCLiteral tree) { + Type litType = attr.litType(tree.typetag); + result = ArgumentExpressionKind.standaloneKind(litType, types); + } + + @Override + void skip(JCTree tree) { + result = ArgumentExpressionKind.NO_POLY; + } + + private Symbol quicklyResolveMethod(Env env, final JCMethodInvocation tree) { final JCExpression rec = tree.meth.hasTag(SELECT) ? ((JCFieldAccess)tree.meth).selected : null; if (rec != null && !isSimpleReceiver(rec)) { - //give up if receiver is too complex (to cut down analysis time) - result = ArgumentExpressionKind.POLY; - return; + return null; } - Type site = rec != null ? - attribSpeculative(rec, env, attr.unknownTypeExprInfo).type : - env.enclClass.sym.type; + Type site; - while (site.hasTag(TYPEVAR)) { - site = site.getUpperBound(); + if (rec != null) { + if (rec.hasTag(APPLY)) { + Symbol recSym = quicklyResolveMethod(env, (JCMethodInvocation) rec); + if (recSym == null) + return null; + Symbol resolvedReturnType = + analyzeCandidateMethods(recSym, syms.errSymbol, returnSymbolAnalyzer); + if (resolvedReturnType == null) + return null; + site = resolvedReturnType.type; + } else { + site = attribSpeculative(rec, env, attr.unknownTypeExprInfo).type; + } + } else { + site = env.enclClass.sym.type; } List args = rs.dummyArgs(tree.args.length()); + Name name = TreeInfo.name(tree.meth); Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args, List.nil(), MethodResolutionPhase.VARARITY) { @Override @@ -1254,61 +1331,60 @@ public class DeferredAttr extends JCTree.Visitor { } }; - Symbol sym = rs.lookupMethod(env, tree, site.tsym, rs.arityMethodCheck, lh); + return rs.lookupMethod(env, tree, site.tsym, rs.arityMethodCheck, lh); + } + //where: + MethodAnalyzer returnSymbolAnalyzer = new MethodAnalyzer() { + @Override + public Symbol process(MethodSymbol ms) { + ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types); + return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null; + } + @Override + public Symbol reduce(Symbol s1, Symbol s2) { + return s1 == syms.errSymbol ? s2 : s1 == s2 ? s1 : null; + } + @Override + public boolean shouldStop(Symbol result) { + return result == null; + } + }; - if (sym.kind == Kinds.AMBIGUOUS) { - Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); - result = ArgumentExpressionKind.PRIMITIVE; - for (Symbol s : err.ambiguousSyms) { - if (result.isPoly()) break; - if (s.kind == Kinds.MTH) { - result = reduce(ArgumentExpressionKind.methodKind(s, types)); + /** + * Process the result of Resolve.lookupMethod. If sym is a method symbol, the result of + * MethodAnalyzer.process is returned. If sym is an ambiguous symbol, all the candidate + * methods are inspected one by one, using MethodAnalyzer.process. The outcomes are + * reduced using MethodAnalyzer.reduce (using defaultValue as the first value over which + * the reduction runs). MethodAnalyzer.shouldStop can be used to stop the inspection early. + */ + E analyzeCandidateMethods(Symbol sym, E defaultValue, MethodAnalyzer analyzer) { + switch (sym.kind) { + case Kinds.MTH: + return analyzer.process((MethodSymbol) sym); + case Kinds.AMBIGUOUS: + Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); + E res = defaultValue; + for (Symbol s : err.ambiguousSyms) { + if (s.kind == Kinds.MTH) { + res = analyzer.reduce(res, analyzer.process((MethodSymbol) s)); + if (analyzer.shouldStop(res)) + return res; + } } - } - } else { - result = (sym.kind == Kinds.MTH) ? - ArgumentExpressionKind.methodKind(sym, types) : - ArgumentExpressionKind.NO_POLY; + return res; + default: + return defaultValue; } } - //where - private boolean isSimpleReceiver(JCTree rec) { - switch (rec.getTag()) { - case IDENT: - return true; - case SELECT: - return isSimpleReceiver(((JCFieldAccess)rec).selected); - case TYPEAPPLY: - case TYPEARRAY: - return true; - case ANNOTATED_TYPE: - return isSimpleReceiver(((JCAnnotatedType)rec).underlyingType); - default: - return false; - } - } - private ArgumentExpressionKind reduce(ArgumentExpressionKind kind) { - switch (result) { - case PRIMITIVE: return kind; - case NO_POLY: return kind.isPoly() ? kind : result; - case POLY: return result; - default: - Assert.error(); - return null; - } - } - - @Override - public void visitLiteral(JCLiteral tree) { - Type litType = attr.litType(tree.typetag); - result = ArgumentExpressionKind.standaloneKind(litType, types); - } - - @Override - void skip(JCTree tree) { - result = ArgumentExpressionKind.NO_POLY; - } } + + /** Analyzer for methods - used by analyzeCandidateMethods. */ + interface MethodAnalyzer { + E process(MethodSymbol ms); + E reduce(E e1, E e2); + boolean shouldStop(E result); + } + //where private EnumSet deferredCheckerTags = EnumSet.of(LAMBDA, REFERENCE, PARENS, TYPECAST, diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index bd189b3b696..65df77a2cc5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -96,7 +96,6 @@ public class Enter extends JCTree.Visitor { Symtab syms; Check chk; TreeMaker make; - ClassReader reader; Annotate annotate; MemberEnter memberEnter; Types types; @@ -118,7 +117,6 @@ public class Enter extends JCTree.Visitor { context.put(enterKey, this); log = Log.instance(context); - reader = ClassReader.instance(context); make = TreeMaker.instance(context); syms = Symtab.instance(context); chk = Check.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index ba2bdc89e20..a9e13874512 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -231,7 +231,8 @@ public class Flow { } } - public List analyzeLambdaThrownTypes(Env env, JCLambda that, TreeMaker make) { + public List analyzeLambdaThrownTypes(final Env env, + JCLambda that, TreeMaker make) { //we need to disable diagnostics temporarily; the problem is that if //a lambda expression contains e.g. an unreachable statement, an error //message will be reported and will cause compilation to skip the flow analyis @@ -239,7 +240,13 @@ public class Flow { //related errors, which will allow for more errors to be detected Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); try { - new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); + new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit) { + @Override + protected boolean trackable(VarSymbol sym) { + return !env.info.scope.includes(sym) && + sym.owner.kind == MTH; + } + }.analyzeTree(env); LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); flowAnalyzer.analyzeTree(env, that, make); return flowAnalyzer.inferredThrownTypes; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index df41f3763a8..d554e0e2cc9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -344,8 +344,10 @@ public class Infer { } private boolean commonSuperWithDiffParameterization(Type t, Type s) { - Pair supers = getParameterizedSupers(t, s); - return (supers != null && !types.isSameType(supers.fst, supers.snd)); + for (Pair supers : getParameterizedSupers(t, s)) { + if (!types.isSameType(supers.fst, supers.snd)) return true; + } + return false; } private Type generateReferenceToTargetConstraint(JCTree tree, UndetVar from, @@ -604,30 +606,38 @@ public class Infer { /** max number of incorporation rounds */ static final int MAX_INCORPORATION_STEPS = 100; - /* If for two types t and s there is a least upper bound that is a - * parameterized type G, then there exists a supertype of 't' of the form - * G and a supertype of 's' of the form G - * which will be returned by this method. If no such supertypes exists then - * null is returned. + /* If for two types t and s there is a least upper bound that contains + * parameterized types G1, G2 ... Gn, then there exists supertypes of 't' of the form + * G1, G2, ... Gn and supertypes of 's' of the form + * G1, G2, ... Gn which will be returned by this method. + * If no such common supertypes exists then an empty list is returned. * * As an example for the following input: * * t = java.util.ArrayList * s = java.util.List * - * we get this ouput: + * we get this ouput (singleton list): * - * Pair[java.util.List,java.util.List] + * [Pair[java.util.List,java.util.List]] */ - private Pair getParameterizedSupers(Type t, Type s) { + private List> getParameterizedSupers(Type t, Type s) { Type lubResult = types.lub(t, s); - if (lubResult == syms.errType || lubResult == syms.botType || - !lubResult.isParameterized()) { - return null; + if (lubResult == syms.errType || lubResult == syms.botType) { + return List.nil(); } - Type asSuperOfT = types.asSuper(t, lubResult.tsym); - Type asSuperOfS = types.asSuper(s, lubResult.tsym); - return new Pair<>(asSuperOfT, asSuperOfS); + List supertypesToCheck = lubResult.isCompound() ? + ((IntersectionClassType)lubResult).getComponents() : + List.of(lubResult); + ListBuffer> commonSupertypes = new ListBuffer<>(); + for (Type sup : supertypesToCheck) { + if (sup.isParameterized()) { + Type asSuperOfT = types.asSuper(t, sup.tsym); + Type asSuperOfS = types.asSuper(s, sup.tsym); + commonSupertypes.add(new Pair<>(asSuperOfT, asSuperOfS)); + } + } + return commonSupertypes.toList(); } /** @@ -813,16 +823,17 @@ public class Infer { Type b1 = boundList.head; Type b2 = tmpTail.head; if (b1 != b2) { - Pair commonSupers = infer.getParameterizedSupers(b1, b2); - if (commonSupers != null) { + for (Pair commonSupers : infer.getParameterizedSupers(b1, b2)) { List allParamsSuperBound1 = commonSupers.fst.allparams(); List allParamsSuperBound2 = commonSupers.snd.allparams(); while (allParamsSuperBound1.nonEmpty() && allParamsSuperBound2.nonEmpty()) { //traverse the list of all params comparing them if (!allParamsSuperBound1.head.hasTag(WILDCARD) && !allParamsSuperBound2.head.hasTag(WILDCARD)) { - isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), - inferenceContext.asUndetVar(allParamsSuperBound2.head), infer); + if (!isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), + inferenceContext.asUndetVar(allParamsSuperBound2.head), infer)) { + infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER); + } } allParamsSuperBound1 = allParamsSuperBound1.tail; allParamsSuperBound2 = allParamsSuperBound2.tail; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index bf3e3c122d4..5bffdebdca7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -67,25 +67,24 @@ public class Lower extends TreeTranslator { return instance; } - private Names names; - private Log log; - private Symtab syms; - private Resolve rs; - private Check chk; - private Attr attr; + private final Names names; + private final Log log; + private final Symtab syms; + private final Resolve rs; + private final Check chk; + private final Attr attr; private TreeMaker make; private DiagnosticPosition make_pos; - private ClassWriter writer; - private ClassReader reader; - private ConstFold cfolder; - private Target target; - private Source source; - private boolean allowEnums; + private final ClassWriter writer; + private final ConstFold cfolder; + private final Target target; + private final Source source; + private final boolean allowEnums; private final Name dollarAssertionsDisabled; private final Name classDollar; - private Types types; - private boolean debugLower; - private PkgInfo pkginfoOpt; + private final Types types; + private final boolean debugLower; + private final PkgInfo pkginfoOpt; protected Lower(Context context) { context.put(lowerKey, this); @@ -97,7 +96,6 @@ public class Lower extends TreeTranslator { attr = Attr.instance(context); make = TreeMaker.instance(context); writer = ClassWriter.instance(context); - reader = ClassReader.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); source = Source.instance(context); @@ -3524,7 +3522,7 @@ public class Lower extends TreeTranslator { private void visitIterableForeachLoop(JCEnhancedForLoop tree) { make_at(tree.expr.pos()); Type iteratorTarget = syms.objectType; - Type iterableType = types.asSuper(types.upperBound(tree.expr.type), + Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type), syms.iterableType.tsym); if (iterableType.getTypeArguments().nonEmpty()) iteratorTarget = types.erasure(iterableType.getTypeArguments().head); @@ -3558,7 +3556,7 @@ public class Lower extends TreeTranslator { List.nil()); JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next)); if (tree.var.type.isPrimitive()) - vardefinit = make.TypeCast(types.upperBound(iteratorTarget), vardefinit); + vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit); else vardefinit = make.TypeCast(tree.var.type, vardefinit); JCVariableDecl indexDef = (JCVariableDecl)make.VarDef(tree.var.mods, diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index ab6e894b739..4fddfb10f85 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -25,10 +25,7 @@ package com.sun.tools.javac.comp; -import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Set; import javax.tools.JavaFileObject; @@ -49,6 +46,7 @@ import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.ERROR; import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.tree.JCTree.Tag.*; + import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -75,7 +73,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final Attr attr; private final Symtab syms; private final TreeMaker make; - private final ClassReader reader; private final Todo todo; private final Annotate annotate; private final TypeAnnotations typeAnnotations; @@ -102,7 +99,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { attr = Attr.instance(context); syms = Symtab.instance(context); make = TreeMaker.instance(context); - reader = ClassReader.instance(context); todo = Todo.instance(context); annotate = Annotate.instance(context); typeAnnotations = TypeAnnotations.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index dc79bfd780a..fffe05c55a0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -87,7 +87,7 @@ public class Resolve { DeferredAttr deferredAttr; Check chk; Infer infer; - ClassReader reader; + ClassFinder finder; TreeInfo treeinfo; Types types; JCDiagnostic.Factory diags; @@ -121,7 +121,7 @@ public class Resolve { deferredAttr = DeferredAttr.instance(context); chk = Check.instance(context); infer = Infer.instance(context); - reader = ClassReader.instance(context); + finder = ClassFinder.instance(context); treeinfo = TreeInfo.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); @@ -347,7 +347,7 @@ public class Resolve { boolean isAccessible(Env env, Type t, boolean checkInner) { return (t.hasTag(ARRAY)) - ? isAccessible(env, types.upperBound(types.elemtype(t))) + ? isAccessible(env, types.cvarUpperBound(types.elemtype(t))) : isAccessible(env, t.tsym, checkInner); } @@ -1014,7 +1014,7 @@ public class Resolve { */ private Type U(Type found) { return found == pt ? - found : types.upperBound(found); + found : types.cvarUpperBound(found); } @Override @@ -1886,9 +1886,9 @@ public class Resolve { */ Symbol loadClass(Env env, Name name) { try { - ClassSymbol c = reader.loadClass(name); + ClassSymbol c = finder.loadClass(name); return isAccessible(env, c) ? c : new AccessError(c); - } catch (ClassReader.BadClassFile err) { + } catch (ClassFinder.BadClassFile err) { throw err; } catch (CompletionFailure ex) { return typeNotFound; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java index e1ff3ac274e..60f12fc4784 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,11 +108,21 @@ public class ClassFile { V50(50, 0), // JDK 1.6: stackmaps V51(51, 0), // JDK 1.7 V52(52, 0); // JDK 1.8: lambda, type annos, param names + // JDK9 still marked as V52 // V53(53, 0); // JDK 1.9 + Version(int major, int minor) { this.major = major; this.minor = minor; } public final int major, minor; + + private static final Version MIN = values()[0]; + /** Return the least version supported, MIN */ + public static Version MIN() { return MIN; } + + private static final Version MAX = values()[values().length-1]; + /** Return the largest version supported, MAX */ + public static Version MAX() { return MAX; } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index ed560d52355..0a585735ba7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -35,13 +35,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import javax.lang.model.SourceVersion; import javax.tools.JavaFileObject; import javax.tools.JavaFileManager; -import javax.tools.JavaFileManager.Location; -import javax.tools.StandardJavaFileManager; - -import static javax.tools.StandardLocation.*; import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.code.*; @@ -119,23 +114,6 @@ public class ClassReader { */ public boolean saveParameterNames; - /** - * Switch: cache completion failures unless -XDdev is used - */ - private boolean cacheCompletionFailure; - - /** - * Switch: prefer source files instead of newer when both source - * and class are available - **/ - public boolean preferSource; - - /** - * Switch: Search classpath and sourcepath for classes before the - * bootclasspath - */ - public boolean userPathsFirst; - /** * The currently selected profile. */ @@ -153,10 +131,6 @@ public class ClassReader { /** The name table. */ final Names names; - /** Force a completion failure on this name - */ - final Name completionFailureName; - /** Access to files */ private final JavaFileManager fileManager; @@ -165,12 +139,6 @@ public class ClassReader { */ JCDiagnostic.Factory diagFactory; - /** Can be reassigned from outside: - * the completer to be used for ".java" files. If this remains unassigned - * ".java" files will not be loaded. - */ - public SourceCompleter sourceCompleter = null; - /** The current scope where type variables are entered. */ protected Scope typevars; @@ -227,20 +195,6 @@ public class ClassReader { */ Set warnedAttrs = new HashSet<>(); - /** - * Completer that delegates to the complete-method of this class. - */ - private final Completer thisCompleter = new Completer() { - @Override - public void complete(Symbol sym) throws CompletionFailure { - ClassReader.this.complete(sym); - } - }; - - public Completer getCompleter() { - return thisCompleter; - } - /** Get the ClassReader instance for this invocation. */ public static ClassReader instance(Context context) { ClassReader instance = context.get(classReaderKey); @@ -274,17 +228,9 @@ public class ClassReader { allowSimplifiedVarargs = source.allowSimplifiedVarargs(); saveParameterNames = options.isSet("save-parameter-names"); - cacheCompletionFailure = options.isUnset("dev"); - preferSource = "source".equals(options.get("-Xprefer")); - userPathsFirst = options.isSet(XXUSERPATHSFIRST); profile = Profile.instance(context); - completionFailureName = - options.isSet("failcomplete") - ? names.fromString(options.get("failcomplete")) - : null; - typevars = new Scope(syms.noSymbol); lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE); @@ -305,26 +251,12 @@ public class ClassReader { * Error Diagnoses ***********************************************************************/ - - public class BadClassFile extends CompletionFailure { - private static final long serialVersionUID = 0; - - public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) { - super(sym, createBadClassFileDiagnostic(file, diag)); - } - } - // where - private JCDiagnostic createBadClassFileDiagnostic(JavaFileObject file, JCDiagnostic diag) { - String key = (file.getKind() == JavaFileObject.Kind.SOURCE - ? "bad.source.file.header" : "bad.class.file.header"); - return diagFactory.fragment(key, file, diag); - } - - public BadClassFile badClassFile(String key, Object... args) { - return new BadClassFile ( + public ClassFinder.BadClassFile badClassFile(String key, Object... args) { + return new ClassFinder.BadClassFile ( currentOwner.enclClass(), currentClassFile, - diagFactory.fragment(key, args)); + diagFactory.fragment(key, args), + diagFactory); } /************************************************************************ @@ -1501,7 +1433,7 @@ public class ClassReader { int tag = nextByte(); // TargetType tag is a byte if (!TargetType.isValidTargetTypeValue(tag)) - throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); + throw badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); TargetType type = TargetType.fromTargetTypeValue(tag); @@ -2080,8 +2012,8 @@ public class ClassReader { Type type = readType(nextChar()); if (currentOwner.isInterface() && (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) { - if (majorVersion > Target.JDK1_8.majorVersion || - (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) { + if (majorVersion > Version.V52.major || + (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) { if ((flags & STATIC) == 0) { currentOwner.flags_field |= DEFAULT; flags |= DEFAULT | ABSTRACT; @@ -2353,20 +2285,20 @@ public class ClassReader { } } - /** Read a class file. + /** Read a class definition from the bytes in buf. */ - private void readClassFile(ClassSymbol c) throws IOException { + private void readClassBuffer(ClassSymbol c) throws IOException { int magic = nextInt(); if (magic != JAVA_MAGIC) throw badClassFile("illegal.start.of.class.file"); minorVersion = nextChar(); majorVersion = nextChar(); - int maxMajor = Target.MAX().majorVersion; - int maxMinor = Target.MAX().minorVersion; + int maxMajor = Version.MAX().major; + int maxMinor = Version.MAX().minor; if (majorVersion > maxMajor || majorVersion * 1000 + minorVersion < - Target.MIN().majorVersion * 1000 + Target.MIN().minorVersion) + Version.MIN().major * 1000 + Version.MIN().minor) { if (majorVersion == (maxMajor + 1)) log.warning("big.major.version", @@ -2395,162 +2327,39 @@ public class ClassReader { readClass(c); } -/************************************************************************ - * Adjusting flags - ***********************************************************************/ - - long adjustFieldFlags(long flags) { - return flags; - } - long adjustMethodFlags(long flags) { - if ((flags & ACC_BRIDGE) != 0) { - flags &= ~ACC_BRIDGE; - flags |= BRIDGE; - if (!allowGenerics) - flags &= ~SYNTHETIC; - } - if ((flags & ACC_VARARGS) != 0) { - flags &= ~ACC_VARARGS; - flags |= VARARGS; - } - return flags; - } - long adjustClassFlags(long flags) { - return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded - } - -/************************************************************************ - * Loading Classes - ***********************************************************************/ - - /** Completion for classes to be loaded. Before a class is loaded - * we make sure its enclosing class (if any) is loaded. - */ - private void complete(Symbol sym) throws CompletionFailure { - if (sym.kind == TYP) { - ClassSymbol c = (ClassSymbol)sym; - c.members_field = new Scope.ErrorScope(c); // make sure it's always defined - annotate.enterStart(); - try { - completeOwners(c.owner); - completeEnclosing(c); - } finally { - // The flush needs to happen only after annotations - // are filled in. - annotate.enterDoneWithoutFlush(); - } - fillIn(c); - } else if (sym.kind == PCK) { - PackageSymbol p = (PackageSymbol)sym; - try { - fillIn(p); - } catch (IOException ex) { - throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); - } - } - if (!filling) - annotate.flush(); // finish attaching annotations - } - - /** complete up through the enclosing package. */ - private void completeOwners(Symbol o) { - if (o.kind != PCK) completeOwners(o.owner); - o.complete(); - } - - /** - * Tries to complete lexically enclosing classes if c looks like a - * nested class. This is similar to completeOwners but handles - * the situation when a nested class is accessed directly as it is - * possible with the Tree API or javax.lang.model.*. - */ - private void completeEnclosing(ClassSymbol c) { - if (c.owner.kind == PCK) { - Symbol owner = c.owner; - for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) { - Symbol encl = owner.members().lookup(name).sym; - if (encl == null) - encl = syms.classes.get(TypeSymbol.formFlatName(name, owner)); - if (encl != null) - encl.complete(); - } - } - } - - /** We can only read a single class file at a time; this - * flag keeps track of when we are currently reading a class - * file. - */ - private boolean filling = false; - - /** Fill in definition of class `c' from corresponding class or - * source file. - */ - private void fillIn(ClassSymbol c) { - if (completionFailureName == c.fullname) { - throw new CompletionFailure(c, "user-selected completion failure by class name"); - } + public void readClassFile(ClassSymbol c) { currentOwner = c; + currentClassFile = c.classfile; warnedAttrs.clear(); - JavaFileObject classfile = c.classfile; - if (classfile != null) { - JavaFileObject previousClassFile = currentClassFile; - try { - if (filling) { - Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile); - } - currentClassFile = classfile; - if (verbose) { - log.printVerbose("loading", currentClassFile.toString()); - } - if (classfile.getKind() == JavaFileObject.Kind.CLASS) { - filling = true; - try { - bp = 0; - buf = readInputStream(buf, classfile.openInputStream()); - readClassFile(c); - if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) { - List missing = missingTypeVariables; - List found = foundTypeVariables; - missingTypeVariables = List.nil(); - foundTypeVariables = List.nil(); - filling = false; - ClassType ct = (ClassType)currentOwner.type; - ct.supertype_field = - types.subst(ct.supertype_field, missing, found); - ct.interfaces_field = - types.subst(ct.interfaces_field, missing, found); - } else if (missingTypeVariables.isEmpty() != - foundTypeVariables.isEmpty()) { - Name name = missingTypeVariables.head.tsym.name; - throw badClassFile("undecl.type.var", name); - } - } finally { - missingTypeVariables = List.nil(); - foundTypeVariables = List.nil(); - filling = false; - } - } else { - if (sourceCompleter != null) { - sourceCompleter.complete(c); - } else { - throw new IllegalStateException("Source completer required to read " - + classfile.toUri()); - } - } - return; - } catch (IOException ex) { - throw badClassFile("unable.to.access.file", ex.getMessage()); - } catch (ArrayIndexOutOfBoundsException ex) { - throw badClassFile("bad.class.file", c.flatname); - } finally { - currentClassFile = previousClassFile; + filling = true; + try { + bp = 0; + buf = readInputStream(buf, c.classfile.openInputStream()); + readClassBuffer(c); + if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) { + List missing = missingTypeVariables; + List found = foundTypeVariables; + missingTypeVariables = List.nil(); + foundTypeVariables = List.nil(); + filling = false; + ClassType ct = (ClassType)currentOwner.type; + ct.supertype_field = + types.subst(ct.supertype_field, missing, found); + ct.interfaces_field = + types.subst(ct.interfaces_field, missing, found); + } else if (missingTypeVariables.isEmpty() != + foundTypeVariables.isEmpty()) { + Name name = missingTypeVariables.head.tsym.name; + throw badClassFile("undecl.type.var", name); } - } else { - JCDiagnostic diag = - diagFactory.fragment("class.file.not.found", c.flatname); - throw - newCompletionFailure(c, diag); + } catch (IOException ex) { + throw badClassFile("unable.to.access.file", ex.getMessage()); + } catch (ArrayIndexOutOfBoundsException ex) { + throw badClassFile("bad.class.file", c.flatname); + } finally { + missingTypeVariables = List.nil(); + foundTypeVariables = List.nil(); + filling = false; } } // where @@ -2590,253 +2399,39 @@ public class ClassReader { } return buf; } - /** Static factory for CompletionFailure objects. - * In practice, only one can be used at a time, so we share one - * to reduce the expense of allocating new exception objects. - */ - private CompletionFailure newCompletionFailure(TypeSymbol c, - JCDiagnostic diag) { - if (!cacheCompletionFailure) { - // log.warning("proc.messager", - // Log.getLocalizedString("class.file.not.found", c.flatname)); - // c.debug.printStackTrace(); - return new CompletionFailure(c, diag); - } else { - CompletionFailure result = cachedCompletionFailure; - result.sym = c; - result.diag = diag; - return result; - } - } - private CompletionFailure cachedCompletionFailure = - new CompletionFailure(null, (JCDiagnostic) null); - { - cachedCompletionFailure.setStackTrace(new StackTraceElement[0]); - } - - /** Load a toplevel class with given fully qualified name - * The class is entered into `classes' only if load was successful. + /** We can only read a single class file at a time; this + * flag keeps track of when we are currently reading a class + * file. */ - public ClassSymbol loadClass(Name flatname) throws CompletionFailure { - boolean absent = syms.classes.get(flatname) == null; - ClassSymbol c = syms.enterClass(flatname); - if (c.members_field == null && c.completer != null) { - try { - c.complete(); - } catch (CompletionFailure ex) { - if (absent) syms.classes.remove(flatname); - throw ex; - } - } - return c; - } + public boolean filling = false; /************************************************************************ - * Loading Packages + * Adjusting flags ***********************************************************************/ - /** Include class corresponding to given class file in package, - * unless (1) we already have one the same kind (.class or .java), or - * (2) we have one of the other kind, and the given class file - * is older. - */ - protected void includeClassFile(PackageSymbol p, JavaFileObject file) { - if ((p.flags_field & EXISTS) == 0) - for (Symbol q = p; q != null && q.kind == PCK; q = q.owner) - q.flags_field |= EXISTS; - JavaFileObject.Kind kind = file.getKind(); - int seen; - if (kind == JavaFileObject.Kind.CLASS) - seen = CLASS_SEEN; - else - seen = SOURCE_SEEN; - String binaryName = fileManager.inferBinaryName(currentLoc, file); - int lastDot = binaryName.lastIndexOf("."); - Name classname = names.fromString(binaryName.substring(lastDot + 1)); - boolean isPkgInfo = classname == names.package_info; - ClassSymbol c = isPkgInfo - ? p.package_info - : (ClassSymbol) p.members_field.lookup(classname).sym; - if (c == null) { - c = syms.enterClass(classname, p); - if (c.classfile == null) // only update the file if's it's newly created - c.classfile = file; - if (isPkgInfo) { - p.package_info = c; - } else { - if (c.owner == p) // it might be an inner class - p.members_field.enter(c); - } - } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) { - // if c.classfile == null, we are currently compiling this class - // and no further action is necessary. - // if (c.flags_field & seen) != 0, we have already encountered - // a file of the same kind; again no further action is necessary. - if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0) - c.classfile = preferredFileObject(file, c.classfile); + long adjustFieldFlags(long flags) { + return flags; + } + + long adjustMethodFlags(long flags) { + if ((flags & ACC_BRIDGE) != 0) { + flags &= ~ACC_BRIDGE; + flags |= BRIDGE; + if (!allowGenerics) + flags &= ~SYNTHETIC; } - c.flags_field |= seen; - } - - /** Implement policy to choose to derive information from a source - * file or a class file when both are present. May be overridden - * by subclasses. - */ - protected JavaFileObject preferredFileObject(JavaFileObject a, - JavaFileObject b) { - - if (preferSource) - return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b; - else { - long adate = a.getLastModified(); - long bdate = b.getLastModified(); - // 6449326: policy for bad lastModifiedTime in ClassReader - //assert adate >= 0 && bdate >= 0; - return (adate > bdate) ? a : b; + if ((flags & ACC_VARARGS) != 0) { + flags &= ~ACC_VARARGS; + flags |= VARARGS; } + return flags; } - /** - * specifies types of files to be read when filling in a package symbol - */ - protected EnumSet getPackageFileKinds() { - return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE); + long adjustClassFlags(long flags) { + return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded } - /** - * this is used to support javadoc - */ - protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) { - } - - protected Location currentLoc; // FIXME - - private boolean verbosePath = true; - - // Set to true when the currently selected file should be kept - private boolean preferCurrent; - - /** Load directory of package into members scope. - */ - private void fillIn(PackageSymbol p) throws IOException { - if (p.members_field == null) - p.members_field = new Scope(p); - - preferCurrent = false; - if (userPathsFirst) { - scanUserPaths(p); - preferCurrent = true; - scanPlatformPath(p); - } else { - scanPlatformPath(p); - scanUserPaths(p); - } - verbosePath = false; - } - - /** - * Scans class path and source path for files in given package. - */ - private void scanUserPaths(PackageSymbol p) throws IOException { - Set kinds = getPackageFileKinds(); - - Set classKinds = EnumSet.copyOf(kinds); - classKinds.remove(JavaFileObject.Kind.SOURCE); - boolean wantClassFiles = !classKinds.isEmpty(); - - Set sourceKinds = EnumSet.copyOf(kinds); - sourceKinds.remove(JavaFileObject.Kind.CLASS); - boolean wantSourceFiles = !sourceKinds.isEmpty(); - - boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH); - - if (verbose && verbosePath) { - if (fileManager instanceof StandardJavaFileManager) { - StandardJavaFileManager fm = (StandardJavaFileManager)fileManager; - if (haveSourcePath && wantSourceFiles) { - List path = List.nil(); - for (File file : fm.getLocation(SOURCE_PATH)) { - path = path.prepend(file); - } - log.printVerbose("sourcepath", path.reverse().toString()); - } else if (wantSourceFiles) { - List path = List.nil(); - for (File file : fm.getLocation(CLASS_PATH)) { - path = path.prepend(file); - } - log.printVerbose("sourcepath", path.reverse().toString()); - } - if (wantClassFiles) { - List path = List.nil(); - for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) { - path = path.prepend(file); - } - for (File file : fm.getLocation(CLASS_PATH)) { - path = path.prepend(file); - } - log.printVerbose("classpath", path.reverse().toString()); - } - } - } - - String packageName = p.fullname.toString(); - if (wantSourceFiles && !haveSourcePath) { - fillIn(p, CLASS_PATH, - fileManager.list(CLASS_PATH, - packageName, - kinds, - false)); - } else { - if (wantClassFiles) - fillIn(p, CLASS_PATH, - fileManager.list(CLASS_PATH, - packageName, - classKinds, - false)); - if (wantSourceFiles) - fillIn(p, SOURCE_PATH, - fileManager.list(SOURCE_PATH, - packageName, - sourceKinds, - false)); - } - } - - /** - * Scans platform class path for files in given package. - */ - private void scanPlatformPath(PackageSymbol p) throws IOException { - fillIn(p, PLATFORM_CLASS_PATH, - fileManager.list(PLATFORM_CLASS_PATH, - p.fullname.toString(), - EnumSet.of(JavaFileObject.Kind.CLASS), - false)); - } - // where - private void fillIn(PackageSymbol p, - Location location, - Iterable files) - { - currentLoc = location; - for (JavaFileObject fo : files) { - switch (fo.getKind()) { - case CLASS: - case SOURCE: { - // TODO pass binaryName to includeClassFile - String binaryName = fileManager.inferBinaryName(currentLoc, fo); - String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1); - if (SourceVersion.isIdentifier(simpleName) || - simpleName.equals("package-info")) - includeClassFile(p, fo); - break; - } - default: - extraFileActions(p, fo); - } - } - } - /** Output for "-checkclassfile" option. * @param key The key to look up the correct internationalized string. * @param arg An argument for substitution into the output string. @@ -2845,12 +2440,6 @@ public class ClassReader { log.printLines(key, arg); } - - public interface SourceCompleter { - void complete(ClassSymbol sym) - throws CompletionFailure; - } - /** * A subclass of JavaFileObject for the sourcefile attribute found in a classfile. * The attribute is only the last component of the original filename, so is unlikely diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 5580d06831f..d86644d864b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -459,11 +459,11 @@ public class ClassWriter extends ClassFile { poolbuf.appendChar(pool.put(names.fromString((String)value))); } else if (value instanceof UniqueType) { Type type = ((UniqueType)value).type; - if (type instanceof MethodType) { + if (type.hasTag(METHOD)) { poolbuf.appendByte(CONSTANT_MethodType); poolbuf.appendChar(pool.put(typeSig((MethodType)type))); } else { - if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym); + Assert.check(type.hasTag(ARRAY)); poolbuf.appendByte(CONSTANT_Class); poolbuf.appendChar(pool.put(xClassName(type))); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index 8f28fa0550e..b933b4632b6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -1925,6 +1925,13 @@ public class Code { return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1); } + void removeLastRange() { + Range lastRange = lastRange(); + if (lastRange != null) { + aliveRanges.remove(lastRange); + } + } + @Override public String toString() { if (aliveRanges == null) { @@ -1955,9 +1962,7 @@ public class Code { } } } else { - if (!aliveRanges.isEmpty()) { - aliveRanges.remove(aliveRanges.size() - 1); - } + removeLastRange(); } } @@ -1965,16 +1970,14 @@ public class Code { if (aliveRanges.isEmpty()) { return false; } - Range range = lastRange(); - return range.length == Character.MAX_VALUE; + return lastRange().length == Character.MAX_VALUE; } public boolean isLastRangeInitialized() { if (aliveRanges.isEmpty()) { return false; } - Range range = lastRange(); - return range.start_pc != Character.MAX_VALUE; + return lastRange().start_pc != Character.MAX_VALUE; } public Range getWidestRange() { @@ -2095,7 +2098,7 @@ public class Code { v.closeRange(length); putVar(v); } else { - v.lastRange().start_pc = Character.MAX_VALUE; + v.removeLastRange(); } } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index 943fbb58d62..37050775fb8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1800,8 +1800,7 @@ public class Gen extends JCTree.Visitor { genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); thenExit = code.branch(goto_); if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) { - code.closeAliveRanges(tree.thenpart, - thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp); + code.closeAliveRanges(tree.thenpart, code.cp); } } if (elseChain != null) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java index cef21cf52e1..9c9a93df143 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java @@ -28,6 +28,7 @@ package com.sun.tools.javac.jvm; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types.UniqueType; @@ -127,7 +128,14 @@ public class Pool { } else if (o instanceof VarSymbol) { return new Variable((VarSymbol)o, types); } else if (o instanceof Type) { - return new UniqueType((Type)o, types); + Type t = (Type)o; + // ClassRefs can come from ClassSymbols or from Types. + // Return the symbol for these types to avoid duplicates + // in the constant pool + if (t.hasTag(TypeTag.CLASS)) + return t.tsym; + else + return new UniqueType(t, types); } else { return o; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 6c7ccc11ffa..ff8ff35581a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -219,6 +219,10 @@ public class JavaCompiler { */ protected TreeMaker make; + /** The class finder. + */ + protected ClassFinder finder; + /** The class reader. */ protected ClassReader reader; @@ -296,13 +300,13 @@ public class JavaCompiler { protected MultiTaskListener taskListener; /** - * SourceCompleter that delegates to the complete-method of this class. + * SourceCompleter that delegates to the readSourceFile method of this class. */ - protected final ClassReader.SourceCompleter thisCompleter = - new ClassReader.SourceCompleter() { + protected final Symbol.Completer sourceCompleter = + new Symbol.Completer() { @Override - public void complete(ClassSymbol sym) throws CompletionFailure { - JavaCompiler.this.complete(sym); + public void complete(Symbol sym) throws CompletionFailure { + readSourceFile((ClassSymbol) sym); } }; @@ -338,6 +342,7 @@ public class JavaCompiler { names = Names.instance(context); log = Log.instance(context); diagFactory = JCDiagnostic.Factory.instance(context); + finder = ClassFinder.instance(context); reader = ClassReader.instance(context); make = TreeMaker.instance(context); writer = ClassWriter.instance(context); @@ -355,7 +360,7 @@ public class JavaCompiler { } catch (CompletionFailure ex) { // inlined Check.completionError as it is not initialized yet log.error("cant.access", ex.sym, ex.getDetailValue()); - if (ex instanceof ClassReader.BadClassFile) + if (ex instanceof ClassFinder.BadClassFile) throw new Abort(); } source = Source.instance(context); @@ -370,7 +375,7 @@ public class JavaCompiler { types = Types.instance(context); taskListener = MultiTaskListener.instance(context); - reader.sourceCompleter = thisCompleter; + finder.sourceCompleter = sourceCompleter; options = Options.instance(context); @@ -663,7 +668,7 @@ public class JavaCompiler { public Symbol resolveBinaryNameOrIdent(String name) { try { Name flatname = names.fromString(name.replace("/", ".")); - return reader.loadClass(flatname); + return finder.loadClass(flatname); } catch (CompletionFailure ignore) { return resolveIdent(name); } @@ -737,22 +742,20 @@ public class JavaCompiler { return null; } - /** Complete compiling a source file that has been accessed - * by the class file reader. + /** Compile a source file that has been accessed by the class finder. * @param c The class the source file of which needs to be compiled. */ - public void complete(ClassSymbol c) throws CompletionFailure { - complete(null, c); + private void readSourceFile(ClassSymbol c) throws CompletionFailure { + readSourceFile(null, c); } - /** Complete a ClassSymbol from source, optionally using the given compilation unit as + /** Compile a ClassSymbol from source, optionally using the given compilation unit as * the source tree. - * @param tree the compilation unit int which the given ClassSymbol resides, + * @param tree the compilation unit in which the given ClassSymbol resides, * or null if should be parsed from source * @param c the ClassSymbol to complete */ - public void complete(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure { -// System.err.println("completing " + c);//DEBUG + public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure { if (completionFailureName == c.fullname) { throw new CompletionFailure(c, "user-selected completion failure by class name"); } @@ -791,13 +794,13 @@ public class JavaCompiler { JCDiagnostic diag = diagFactory.fragment("file.does.not.contain.package", c.location()); - throw reader.new BadClassFile(c, filename, diag); + throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); } } else { JCDiagnostic diag = diagFactory.fragment("file.doesnt.contain.class", c.getQualifiedName()); - throw reader.new BadClassFile(c, filename, diag); + throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); } } @@ -1663,6 +1666,7 @@ public class JavaCompiler { */ public void close() { rootClasses = null; + finder = null; reader = null; make = null; writer = null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 5ffe456db60..4e3be1145b7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -54,8 +54,6 @@ import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.jvm.*; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacTypes; @@ -203,7 +201,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea symtab = Symtab.instance(context); names = Names.instance(context); enter = Enter.instance(context); - initialCompleter = ClassReader.instance(context).getCompleter(); + initialCompleter = ClassFinder.instance(context).getCompleter(); chk = Check.instance(context); initProcessorClassLoader(); } @@ -799,7 +797,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea RoundEnvironment renv) { try { return proc.process(tes, renv); - } catch (BadClassFile ex) { + } catch (ClassFinder.BadClassFile ex) { log.error("proc.cant.access.1", ex.sym, ex.getDetailValue()); return false; } catch (CompletionFailure ex) { @@ -1308,7 +1306,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } @Override public void complete(Symbol sym) throws CompletionFailure { - compiler.complete(topLevel, (ClassSymbol) sym); + compiler.readSourceFile(topLevel, (ClassSymbol) sym); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java index 57058c99340..af96c77b066 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java @@ -317,9 +317,9 @@ public class Names { protected Name.Table createTable(Options options) { boolean useUnsharedTable = options.isSet("useUnsharedTable"); if (useUnsharedTable) - return new UnsharedNameTable(this); + return UnsharedNameTable.create(this); else - return new SharedNameTable(this); + return SharedNameTable.create(this); } public void dispose() { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java index 4f6d36ab03e..b23af8e5f14 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ package com.sun.tools.javac.util; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** A collection of utilities for String manipulation. * @@ -50,4 +52,19 @@ public class StringUtils { return source.toUpperCase(Locale.US); } + /**Case insensitive version of {@link String#indexOf(java.lang.String)}. Equivalent to + * {@code text.indexOf(str)}, except the matching is case insensitive. + */ + public static int indexOfIgnoreCase(String text, String str) { + return indexOfIgnoreCase(text, str, 0); + } + + /**Case insensitive version of {@link String#indexOf(java.lang.String, int)}. Equivalent to + * {@code text.indexOf(str, startIndex)}, except the matching is case insensitive. + */ + public static int indexOfIgnoreCase(String text, String str, int startIndex) { + Matcher m = Pattern.compile(Pattern.quote(str), Pattern.CASE_INSENSITIVE).matcher(text); + return m.find(startIndex) ? m.start() : -1; + } + } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java index dfe014ca1fc..17a08f958e4 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java @@ -37,11 +37,19 @@ import com.sun.tools.doclint.DocLint; import com.sun.tools.javac.api.BasicJavacTask; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import com.sun.tools.javac.code.Symbol.CompletionFailure; +import com.sun.tools.javac.code.Symbol.MethodSymbol; +import com.sun.tools.javac.code.Symbol.PackageSymbol; +import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.comp.Check; +import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCPackageDecl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Names; @@ -71,21 +79,21 @@ public class DocEnv { return instance; } - private Messager messager; - DocLocale doclocale; + private final Messager messager; + /** Predefined symbols known to the compiler. */ - Symtab syms; + final Symtab syms; /** Referenced directly in RootDocImpl. */ - JavadocClassReader reader; + private final ClassFinder finder; /** Javadoc's own version of the compiler's enter phase. */ - JavadocEnter enter; + final Enter enter; /** The name table. */ - Names names; + private Names names; /** The encoding name. */ private String encoding; @@ -139,8 +147,8 @@ public class DocEnv { messager = Messager.instance0(context); syms = Symtab.instance(context); - reader = JavadocClassReader.instance0(context); - enter = JavadocEnter.instance0(context); + finder = JavadocClassFinder.instance(context); + enter = JavadocEnter.instance(context); names = Names.instance(context); externalizableSym = syms.enterClass(names.fromString("java.io.Externalizable")); chk = Check.instance(context); @@ -176,7 +184,7 @@ public class DocEnv { */ public ClassDocImpl loadClass(String name) { try { - ClassSymbol c = reader.loadClass(names.fromString(name)); + ClassSymbol c = finder.loadClass(names.fromString(name)); return getClassDoc(c); } catch (CompletionFailure ex) { chk.completionError(null, ex); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java similarity index 82% rename from langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java rename to langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java index d9a1e7392b4..ecb3659f174 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java @@ -29,10 +29,10 @@ import java.util.EnumSet; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.Symbol.PackageSymbol; -import com.sun.tools.javac.jvm.ClassReader; +import com.sun.tools.javac.code.ClassFinder; import com.sun.tools.javac.util.Context; -/** Javadoc uses an extended class reader that records package.html entries +/** Javadoc uses an extended class finder that records package.html entries * *

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. @@ -41,19 +41,19 @@ import com.sun.tools.javac.util.Context; * * @author Neal Gafter */ -public class JavadocClassReader extends ClassReader { +public class JavadocClassFinder extends ClassFinder { - public static JavadocClassReader instance0(Context context) { - ClassReader instance = context.get(classReaderKey); + public static JavadocClassFinder instance(Context context) { + ClassFinder instance = context.get(classFinderKey); if (instance == null) - instance = new JavadocClassReader(context); - return (JavadocClassReader)instance; + instance = new JavadocClassFinder(context); + return (JavadocClassFinder)instance; } public static void preRegister(Context context) { - context.put(classReaderKey, new Context.Factory() { - public ClassReader make(Context c) { - return new JavadocClassReader(c); + context.put(classFinderKey, new Context.Factory() { + public ClassFinder make(Context c) { + return new JavadocClassFinder(c); } }); } @@ -65,7 +65,7 @@ public class JavadocClassReader extends ClassReader { private EnumSet noSource = EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.HTML); - public JavadocClassReader(Context context) { + public JavadocClassFinder(Context context) { super(context); docenv = DocEnv.instance(context); preferSource = true; diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java index 5215edcb894..50386acabe2 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ import com.sun.tools.javac.util.List; * @author Neal Gafter */ public class JavadocEnter extends Enter { - public static JavadocEnter instance0(Context context) { + public static JavadocEnter instance(Context context) { Enter instance = context.get(enterKey); if (instance == null) instance = new JavadocEnter(context); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index 17d12b864a5..3937ff95720 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -33,12 +33,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; +import com.sun.tools.javac.code.ClassFinder; import com.sun.tools.javac.code.Symbol.CompletionFailure; +import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -66,8 +69,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { DocEnv docenv; final Messager messager; - final JavadocClassReader javadocReader; - final JavadocEnter javadocEnter; + final ClassFinder javadocFinder; + final Enter javadocEnter; final Set uniquefiles; /** @@ -77,8 +80,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { protected JavadocTool(Context context) { super(context); messager = Messager.instance0(context); - javadocReader = JavadocClassReader.instance0(context); - javadocEnter = JavadocEnter.instance0(context); + javadocFinder = JavadocClassFinder.instance(context); + javadocEnter = JavadocEnter.instance(context); uniquefiles = new HashSet<>(); } @@ -95,8 +98,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { public static JavadocTool make0(Context context) { Messager messager = null; try { - // force the use of Javadoc's class reader - JavadocClassReader.preRegister(context); + // force the use of Javadoc's class finder + JavadocClassFinder.preRegister(context); // force the use of Javadoc's own enter phase JavadocEnter.preRegister(context); @@ -137,7 +140,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { docenv.setEncoding(encoding); docenv.docClasses = docClasses; docenv.legacyDoclet = legacyDoclet; - javadocReader.sourceCompleter = docClasses ? null : thisCompleter; + + javadocFinder.sourceCompleter = docClasses ? null : sourceCompleter; ListBuffer names = new ListBuffer<>(); ListBuffer classTrees = new ListBuffer<>(); diff --git a/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java b/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java index 8d53c8dc014..34bd4f5fa4f 100644 --- a/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java +++ b/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4460354 8014636 + * @bug 4460354 8014636 8043186 * @summary Test to make sure that relative paths are redirected in the * output so that they are not broken. * @author jamieh diff --git a/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java b/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java index c899eca037b..12af871502e 100644 --- a/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java +++ b/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ package pkg; public class C { /** - * Here is a relative link in a field: + * Here is a relative link in a field:\u0130 * relative field link. */ public C field = null; diff --git a/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java b/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java index 7d173ed24e6..35bf0337a4d 100644 --- a/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java +++ b/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6227616 + * @bug 6227616 8043186 * @summary Test the new -top option. * @author jamieh * @library ../lib @@ -43,7 +43,30 @@ public class TestTopOption extends JavadocTester { javadoc("-overview", testSrc("overview.html"), "-use", "-top", "TOP TEXT", - "-d", "out", + "-d", "out-1", + "-sourcepath", testSrc, + "pkg"); + checkExit(Exit.OK); + + checkTopText( + "pkg/AnnotationType.html", + "pkg/class-use/AnnotationType.html", + "pkg/Cl.html", + "pkg/class-use/Cl.html", + "pkg/package-summary.html", + "pkg/package-use.html", + "overview-summary.html", + "overview-tree.html", + "constant-values.html", + "help-doc.html"); + } + + @Test + void testDocRootRewrite() { + javadoc("-overview", testSrc("overview.html"), + "-use", + "-top", "\u0130{@docroot}TOP TEXT", + "-d", "out-2", "-sourcepath", testSrc, "pkg"); checkExit(Exit.OK); diff --git a/langtools/test/tools/javac/6330997/T6330997.java b/langtools/test/tools/javac/6330997/T6330997.java index 98c76e22828..8995c1b32a1 100644 --- a/langtools/test/tools/javac/6330997/T6330997.java +++ b/langtools/test/tools/javac/6330997/T6330997.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ import java.nio.*; import java.io.*; import java.nio.channels.*; import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; +import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.main.JavaCompiler; import javax.tools.ToolProvider; diff --git a/langtools/test/tools/javac/CaptureInSubtype.java b/langtools/test/tools/javac/CaptureInSubtype.java index 02d2f0e76e7..41d5a3b0b1b 100644 --- a/langtools/test/tools/javac/CaptureInSubtype.java +++ b/langtools/test/tools/javac/CaptureInSubtype.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 5044157 + * @test /nodynamiccopyright/ + * @bug 5044626 * @summary type system loophole in wildcard substitution * @author Gilad Bracha * - * @compile/fail CaptureInSubtype.java + * @compile/fail/ref=CaptureInSubtype.out -XDrawDiagnostics CaptureInSubtype.java */ import java.util.List; diff --git a/langtools/test/tools/javac/CaptureInSubtype.out b/langtools/test/tools/javac/CaptureInSubtype.out new file mode 100644 index 00000000000..9f3b9d65600 --- /dev/null +++ b/langtools/test/tools/javac/CaptureInSubtype.out @@ -0,0 +1,2 @@ +CaptureInSubtype.java:38:17: compiler.err.override.incompatible.ret: (compiler.misc.cant.override: m(), CaptureInSubtype.ShowFlaw, m(), CaptureInSubtype.SuperOfShowFlaw), CaptureInSubtype.Flaw, CaptureInSubtype.SuperOfFlaw> +1 error diff --git a/langtools/test/tools/javac/MethodParametersTest.java b/langtools/test/tools/javac/MethodParametersTest.java index 515eee34e23..c2570b7bed1 100644 --- a/langtools/test/tools/javac/MethodParametersTest.java +++ b/langtools/test/tools/javac/MethodParametersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,14 +129,14 @@ public class MethodParametersTest { if (out.length() > 0) System.err.println(out); - // Now get the class reader, construct a name for Baz, and load it. - com.sun.tools.javac.jvm.ClassReader cr = - com.sun.tools.javac.jvm.ClassReader.instance(context); + // Now get the class finder, construct a name for Baz, and load it. + com.sun.tools.javac.code.ClassFinder cf = + com.sun.tools.javac.code.ClassFinder.instance(context); Name name = Names.instance(context).fromString(Baz_name); // Now walk down the language model and check the name of the // parameter. - final Element baz = cr.loadClass(name); + final Element baz = cf.loadClass(name); for (Element e : baz.getEnclosedElements()) { if (e instanceof ExecutableElement) { final ExecutableElement ee = (ExecutableElement) e; diff --git a/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.java b/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.java index 40ee562cad1..89438c1cf07 100644 --- a/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.java +++ b/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.java @@ -1,34 +1,11 @@ /* - * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4041948 + * @test /nodynamiccopyright/ + * @bug 4041948 * @summary javac previously allowed interfaces to inherit methods with * inconsistent return types. - * @author turnidge + * @author turnidge * - * @compile/fail InconsistentReturn.java + * @compile/fail/ref=InconsistentReturn.out -XDrawDiagnostics InconsistentReturn.java */ interface I1{ int f(); diff --git a/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.out b/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.out new file mode 100644 index 00000000000..6adccb4a11f --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/InconsistentReturn.out @@ -0,0 +1,2 @@ +InconsistentReturn.java:17:1: compiler.err.types.incompatible.diff.ret: I2, I1, f() +1 error diff --git a/langtools/test/tools/javac/OverrideChecks/Private.java b/langtools/test/tools/javac/OverrideChecks/Private.java index 5c107828b63..1b52fbfe461 100644 --- a/langtools/test/tools/javac/OverrideChecks/Private.java +++ b/langtools/test/tools/javac/OverrideChecks/Private.java @@ -1,32 +1,9 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 6399361 * @summary java.lang.Override specification should be revised * @author Peter von der Ah\u00e9 - * @compile/fail Private.java + * @compile/fail/ref=Private.out -XDrawDiagnostics Private.java */ public class Private { diff --git a/langtools/test/tools/javac/OverrideChecks/Private.out b/langtools/test/tools/javac/OverrideChecks/Private.out new file mode 100644 index 00000000000..f49ef46a255 --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/Private.out @@ -0,0 +1,2 @@ +Private.java:14:5: compiler.err.method.does.not.override.superclass +1 error diff --git a/langtools/test/tools/javac/OverrideChecks/StaticOverride.java b/langtools/test/tools/javac/OverrideChecks/StaticOverride.java index 4a31721cecf..149faa2550a 100644 --- a/langtools/test/tools/javac/OverrideChecks/StaticOverride.java +++ b/langtools/test/tools/javac/OverrideChecks/StaticOverride.java @@ -1,34 +1,11 @@ /* - * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4041948 4022450 + * @test /nodynamiccopyright/ + * @bug 4041948 4022450 * @summary javac previously allowed static methods to override non-static * methods in some cases. - * @author turnidge + * @author turnidge * - * @compile/fail StaticOverride.java + * @compile/fail/ref=StaticOverride.out -XDrawDiagnostics StaticOverride.java */ interface I{ int f(); diff --git a/langtools/test/tools/javac/OverrideChecks/StaticOverride.out b/langtools/test/tools/javac/OverrideChecks/StaticOverride.out new file mode 100644 index 00000000000..fe4bde62e9a --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/StaticOverride.out @@ -0,0 +1,2 @@ +StaticOverride.java:20:1: compiler.err.override.static: (compiler.misc.cant.implement: f(), C, f(), I) +1 error diff --git a/langtools/test/tools/javac/OverrideChecks/T4720356a.java b/langtools/test/tools/javac/OverrideChecks/T4720356a.java index d0d0eeba527..308f7646cc4 100644 --- a/langtools/test/tools/javac/OverrideChecks/T4720356a.java +++ b/langtools/test/tools/javac/OverrideChecks/T4720356a.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4720356 + * @test /nodynamiccopyright/ + * @bug 4720356 * @summary compiler fails to check cross-package overriding - * @author gafter + * @author gafter * - * @compile/fail T4720356a.java T4720356b.java + * @compile/fail/ref=T4720356a.out -XDrawDiagnostics T4720356a.java T4720356b.java */ package p1; diff --git a/langtools/test/tools/javac/OverrideChecks/T4720356a.out b/langtools/test/tools/javac/OverrideChecks/T4720356a.out new file mode 100644 index 00000000000..4c00ed53e2b --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/T4720356a.out @@ -0,0 +1,2 @@ +T4720356a.java:16:16: compiler.err.override.incompatible.ret: (compiler.misc.cant.override: m(), p1.T4720356c, m(), p1.T4720356a), int, void +1 error diff --git a/langtools/test/tools/javac/OverrideChecks/T4720359a.java b/langtools/test/tools/javac/OverrideChecks/T4720359a.java index 1eb122182fa..c11a1d5578c 100644 --- a/langtools/test/tools/javac/OverrideChecks/T4720359a.java +++ b/langtools/test/tools/javac/OverrideChecks/T4720359a.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4720359 + * @test /nodynamiccopyright/ + * @bug 4720359 * @summary javac fails to check cross-package hiding - * @author gafter + * @author gafter * - * @compile/fail T4720359a.java T4720359b.java + * @compile/fail/ref=T4720359a.out -XDrawDiagnostics T4720359a.java T4720359b.java */ package p1; diff --git a/langtools/test/tools/javac/OverrideChecks/T4720359a.out b/langtools/test/tools/javac/OverrideChecks/T4720359a.out new file mode 100644 index 00000000000..54635de3a1f --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/T4720359a.out @@ -0,0 +1,2 @@ +T4720359a.java:16:23: compiler.err.override.incompatible.ret: (compiler.misc.cant.override: m(), p1.T4720359c, m(), p1.T4720359a), int, void +1 error diff --git a/langtools/test/tools/javac/OverrideChecks/T4721069.java b/langtools/test/tools/javac/OverrideChecks/T4721069.java index 0913f786de9..18259f791d4 100644 --- a/langtools/test/tools/javac/OverrideChecks/T4721069.java +++ b/langtools/test/tools/javac/OverrideChecks/T4721069.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4721069 + * @test /nodynamiccopyright/ + * @bug 4721069 * @summary javac allows an interface to override a final method in Object - * @author gafter + * @author gafter * - * @compile/fail T4721069.java + * @compile/fail/ref=T4721069.out -XDrawDiagnostics T4721069.java */ interface I { diff --git a/langtools/test/tools/javac/OverrideChecks/T4721069.out b/langtools/test/tools/javac/OverrideChecks/T4721069.out new file mode 100644 index 00000000000..d60f8efc465 --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/T4721069.out @@ -0,0 +1,2 @@ +T4721069.java:11:11: compiler.err.override.meth: (compiler.misc.cant.override: getClass(), I, getClass(), java.lang.Object), final +1 error diff --git a/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.java b/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.java index df8767b6425..d6b1db528b0 100644 --- a/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.java +++ b/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4022674 + * @test /nodynamiccopyright/ + * @bug 4022674 * @summary Compiler should detect throws-clauses' conflict. - * @author turnidge + * @author turnidge * - * @compile/fail ThrowsConflict.java + * @compile/fail/ref=ThrowsConflict.out -XDrawDiagnostics ThrowsConflict.java */ interface I { diff --git a/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.out b/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.out new file mode 100644 index 00000000000..b70bdaa45ce --- /dev/null +++ b/langtools/test/tools/javac/OverrideChecks/ThrowsConflict.out @@ -0,0 +1,2 @@ +ThrowsConflict.java:20:1: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: method(), A, method(), I), java.lang.Exception +1 error diff --git a/langtools/test/tools/javac/T6435291/T6435291.java b/langtools/test/tools/javac/T6435291/T6435291.java index d710f9c4fc5..73985a635f2 100644 --- a/langtools/test/tools/javac/T6435291/T6435291.java +++ b/langtools/test/tools/javac/T6435291/T6435291.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ */ import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; +import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.main.JavaCompiler; import javax.tools.ToolProvider; diff --git a/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out b/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out index d253b9c660b..3b2266c0b21 100644 --- a/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out +++ b/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out @@ -1,3 +1,2 @@ -CrashLambdaExpressionWithNonAccessibleIdTest.java:15:35: compiler.err.missing.ret.stmt CrashLambdaExpressionWithNonAccessibleIdTest.java:14:17: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, CrashLambdaExpressionWithNonAccessibleIdTest, null) -2 errors +1 error diff --git a/langtools/test/tools/javac/api/6410643/T6410643.java b/langtools/test/tools/javac/api/6410643/T6410643.java index 80ac51d8742..d423ef67423 100644 --- a/langtools/test/tools/javac/api/6410643/T6410643.java +++ b/langtools/test/tools/javac/api/6410643/T6410643.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ public class T6410643 extends ToolTester { Iterable classes, Iterable compilationUnits) { try { - task = tool.getTask(null, null, null, null, null, singleton((JavaFileObject)null)); + task = tool.getTask(null, null, null, options, classes, compilationUnits); throw new AssertionError("Error expected"); } catch (NullPointerException e) { System.err.println("Expected error occurred: " + e); diff --git a/langtools/test/tools/javac/capture/Capture2.java b/langtools/test/tools/javac/capture/Capture2.java index 6a8c6832cb3..a844cf47091 100644 --- a/langtools/test/tools/javac/capture/Capture2.java +++ b/langtools/test/tools/javac/capture/Capture2.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 5029773 - * @summary soundness problem with failure to subsitute wildcard as type formal argument + * @summary soundness problem with failure to substitute wildcard as type formal argument * @author gafter * - * @compile/fail Capture2.java + * @compile/fail/ref=Capture2.out -XDrawDiagnostics Capture2.java */ package capture2; diff --git a/langtools/test/tools/javac/capture/Capture2.out b/langtools/test/tools/javac/capture/Capture2.out new file mode 100644 index 00000000000..062aaa6393d --- /dev/null +++ b/langtools/test/tools/javac/capture/Capture2.out @@ -0,0 +1,2 @@ +Capture2.java:17:23: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, T) +1 error diff --git a/langtools/test/tools/javac/capture/Martin.java b/langtools/test/tools/javac/capture/Martin.java index 0429f55186d..05052fdb1e1 100644 --- a/langtools/test/tools/javac/capture/Martin.java +++ b/langtools/test/tools/javac/capture/Martin.java @@ -1,32 +1,9 @@ -/* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - /** - * @test + * @test /nodynamiccopyright/ * @bug 6384510 * @summary improper handling of wildcard captures * @author Martin Buchholz - * @compile/fail Martin.java + * @compile/fail/ref=Martin.out -XDrawDiagnostics Martin.java */ import java.util.List; diff --git a/langtools/test/tools/javac/capture/Martin.out b/langtools/test/tools/javac/capture/Martin.out new file mode 100644 index 00000000000..58e306063e9 --- /dev/null +++ b/langtools/test/tools/javac/capture/Martin.out @@ -0,0 +1,2 @@ +Martin.java:15:11: compiler.err.cant.apply.symbols: kindname.method, addAll, java.util.List,{(compiler.misc.inapplicable.method: kindname.method, java.util.Collection, addAll(java.util.Collection), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.util.List, java.util.Collection))),(compiler.misc.inapplicable.method: kindname.method, java.util.List, addAll(java.util.Collection), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.util.List, java.util.Collection))),(compiler.misc.inapplicable.method: kindname.method, java.util.List, addAll(int,java.util.Collection), (compiler.misc.arg.length.mismatch))} +1 error diff --git a/langtools/test/tools/javac/capture/T6594284.java b/langtools/test/tools/javac/capture/T6594284.java index d6bba17f701..cb8f2e94a51 100644 --- a/langtools/test/tools/javac/capture/T6594284.java +++ b/langtools/test/tools/javac/capture/T6594284.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 6594284 * @summary NPE thrown when calling a method on an intersection type * @author Maurizio Cimadamore * - * @compile/fail T6594284.java + * @compile/fail/ref=T6594284.out -XDrawDiagnostics T6594284.java */ public class T6594284 { diff --git a/langtools/test/tools/javac/capture/T6594284.out b/langtools/test/tools/javac/capture/T6594284.out new file mode 100644 index 00000000000..80a9c47c9aa --- /dev/null +++ b/langtools/test/tools/javac/capture/T6594284.out @@ -0,0 +1,2 @@ +T6594284.java:18:24: compiler.err.not.within.bounds: ? extends T6594284.E, T +1 error diff --git a/langtools/test/tools/javac/cast/5064736/T5064736.java b/langtools/test/tools/javac/cast/5064736/T5064736.java index c12562cdcec..7b4cd3cbf7b 100644 --- a/langtools/test/tools/javac/cast/5064736/T5064736.java +++ b/langtools/test/tools/javac/cast/5064736/T5064736.java @@ -1,31 +1,8 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 5064736 * @summary Incompatible types are cast without error - * @compile/fail T5064736.java + * @compile/fail/ref=T5064736.out -XDrawDiagnostics T5064736.java */ public class T5064736 { diff --git a/langtools/test/tools/javac/cast/5064736/T5064736.out b/langtools/test/tools/javac/cast/5064736/T5064736.out new file mode 100644 index 00000000000..3afe295b4a3 --- /dev/null +++ b/langtools/test/tools/javac/cast/5064736/T5064736.out @@ -0,0 +1,2 @@ +T5064736.java:14:34: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: T5064736.Foo, T5064736.Foo) +1 error diff --git a/langtools/test/tools/javac/cast/6219964/T6219964.java b/langtools/test/tools/javac/cast/6219964/T6219964.java index e952f134cce..6372f77435c 100644 --- a/langtools/test/tools/javac/cast/6219964/T6219964.java +++ b/langtools/test/tools/javac/cast/6219964/T6219964.java @@ -1,31 +1,8 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 6219964 * @summary Compiler allows illegal cast of anonymous inner class - * @compile/fail T6219964.java + * @compile/fail/ref=T6219964.out -XDrawDiagnostics T6219964.java */ public class T6219964 { diff --git a/langtools/test/tools/javac/cast/6219964/T6219964.out b/langtools/test/tools/javac/cast/6219964/T6219964.out new file mode 100644 index 00000000000..ef807150d9e --- /dev/null +++ b/langtools/test/tools/javac/cast/6219964/T6219964.out @@ -0,0 +1,2 @@ +T6219964.java:13:27: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.anonymous.class: java.lang.Object, T6219964.I) +1 error diff --git a/langtools/test/tools/javac/cast/6302956/T6302956.java b/langtools/test/tools/javac/cast/6302956/T6302956.java index 53eb12de3d8..cd6f3b88a9c 100644 --- a/langtools/test/tools/javac/cast/6302956/T6302956.java +++ b/langtools/test/tools/javac/cast/6302956/T6302956.java @@ -1,31 +1,8 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 6302956 * @summary Illegal cast allowed Properties -> Map - * @compile/fail T6302956.java + * @compile/fail/ref=T6302956.out -XDrawDiagnostics T6302956.java */ import java.util.Map; diff --git a/langtools/test/tools/javac/cast/6302956/T6302956.out b/langtools/test/tools/javac/cast/6302956/T6302956.out new file mode 100644 index 00000000000..ffe6a4eab18 --- /dev/null +++ b/langtools/test/tools/javac/cast/6302956/T6302956.out @@ -0,0 +1,2 @@ +T6302956.java:12:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.Properties, java.util.Map) +1 error diff --git a/langtools/test/tools/javac/cast/6548436/T6548436d.java b/langtools/test/tools/javac/cast/6548436/T6548436d.java index bf8833b26b0..52ea32b1fc2 100644 --- a/langtools/test/tools/javac/cast/6548436/T6548436d.java +++ b/langtools/test/tools/javac/cast/6548436/T6548436d.java @@ -1,33 +1,10 @@ /* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6548436 + * @test /nodynamiccopyright/ + * @bug 6548436 * @summary Incorrect inconvertible types error * @author Maurizio Cimadamore * - * @compile/fail T6548436d.java + * @compile/fail/ref=T6548436d.out -XDrawDiagnostics T6548436d.java */ public class T6548436d { diff --git a/langtools/test/tools/javac/cast/6548436/T6548436d.out b/langtools/test/tools/javac/cast/6548436/T6548436d.out new file mode 100644 index 00000000000..6d5bb7c1155 --- /dev/null +++ b/langtools/test/tools/javac/cast/6548436/T6548436d.out @@ -0,0 +1,2 @@ +T6548436d.java:15:35: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: T6548436d.Base, T6548436d.Base) +1 error diff --git a/langtools/test/tools/javac/cast/BoxedArray.java b/langtools/test/tools/javac/cast/BoxedArray.java index 58d3678897e..13a6f4ca88e 100644 --- a/langtools/test/tools/javac/cast/BoxedArray.java +++ b/langtools/test/tools/javac/cast/BoxedArray.java @@ -1,33 +1,10 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 5014309 * @summary REGRESSION: compiler allows cast from Integer[] to int[] * @author gafter * - * @compile/fail BoxedArray.java + * @compile/fail/ref=BoxedArray.out -XDrawDiagnostics BoxedArray.java */ public class BoxedArray { diff --git a/langtools/test/tools/javac/cast/BoxedArray.out b/langtools/test/tools/javac/cast/BoxedArray.out new file mode 100644 index 00000000000..2d8770c3a12 --- /dev/null +++ b/langtools/test/tools/javac/cast/BoxedArray.out @@ -0,0 +1,2 @@ +BoxedArray.java:13:22: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer[], int[]) +1 error diff --git a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java index 835f801d209..90321ed2901 100644 --- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java +++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java @@ -24,10 +24,11 @@ /* * @test * @summary sourcefile attribute test for file compiled without debug information. + * @bug 8040129 * @library /tools/javac/lib ../lib * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox * @compile -g:none NoSourceFileAttribute.java - * @run main NoSourceFileAttribute + * @run main NoSourceFileAttribute */ import com.sun.tools.classfile.Attribute; diff --git a/langtools/test/tools/javac/defaultMethods/BadClassfile.java b/langtools/test/tools/javac/defaultMethods/BadClassfile.java index 424d3acf102..28d0dcf6d41 100644 --- a/langtools/test/tools/javac/defaultMethods/BadClassfile.java +++ b/langtools/test/tools/javac/defaultMethods/BadClassfile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,8 @@ import com.sun.tools.classfile.*; import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.code.Symbol; -import com.sun.tools.javac.jvm.ClassReader.BadClassFile; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.JCDiagnostic; diff --git a/langtools/test/tools/javac/flow/LVTHarness.java b/langtools/test/tools/javac/flow/LVTHarness.java index c679f52f526..7039a626a57 100644 --- a/langtools/test/tools/javac/flow/LVTHarness.java +++ b/langtools/test/tools/javac/flow/LVTHarness.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ /* * @test - * @bug 7047734 8027660 - * @summary The LVT is not generated correctly during some try/catch scenarios; + * @bug 7047734 8027660 8037937 + * @summary The LVT is not generated correctly during some try/catch scenarios * javac crash while creating LVT entry for a local variable defined in * an inner block * @library /tools/javac/lib @@ -120,7 +120,7 @@ public class LVTHarness { for (Map.Entry entry : aliveRangeMap.entrySet()) { if (!seenAliveRanges.contains(entry.getKey())) { error("Redundant @AliveRanges annotation on method " + - entry.getKey().elem); + entry.getKey().elem + " with key " + entry.getKey()); } } } @@ -134,7 +134,7 @@ public class LVTHarness { for (Method method : classFile.methods) { for (ElementKey elementKey: aliveRangeMap.keySet()) { String methodDesc = method.getName(constantPool) + - method.descriptor.getParameterTypes(constantPool); + method.descriptor.getParameterTypes(constantPool).replace(" ", ""); if (methodDesc.equals(elementKey.elem.toString())) { checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); seenAliveRanges.add(elementKey); diff --git a/langtools/test/tools/javac/flow/T8042741/A.java b/langtools/test/tools/javac/flow/T8042741/A.java new file mode 100644 index 00000000000..36deb2d172f --- /dev/null +++ b/langtools/test/tools/javac/flow/T8042741/A.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// str must be at absolute position greater than that of lambda +// expression in PositionTest.java +// padding..........................................................padding +// padding..........................................................padding +// padding..........................................................padding +// padding..........................................................padding +// padding..........................................................padding + +public class A { + public final String str; + { + str = ""; + } +} diff --git a/langtools/test/tools/javac/flow/T8042741/PositionTest.java b/langtools/test/tools/javac/flow/T8042741/PositionTest.java new file mode 100644 index 00000000000..cc0da15e4f5 --- /dev/null +++ b/langtools/test/tools/javac/flow/T8042741/PositionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8042741 + * @summary Java 8 compiler throws NullPointerException depending location in source file + * @compile A.java PositionTest.java + */ + +public class PositionTest extends A { + void test(SAM r) throws E { + test(() -> { System.err.println(str); }); + } + interface SAM { + public void run() throws E; + } + void f() { + try { + test(() -> { + test(() -> { + try { + test(() -> { System.err.println(str); }); + System.err.println(str); + } catch (Exception e) {} + System.err.println(str); + }); + System.err.println(str); + }); + } catch (Exception e) { } + } + void g() throws Exception { + test(() -> { + try { + try { + test(() -> { System.err.println(str); }); + } catch (Exception e) {} + System.err.println(str); + } catch (Exception e) {} + System.err.println(str); + }); + } +} diff --git a/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java index 3e6cc893794..d789853b43a 100644 --- a/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java +++ b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java @@ -33,7 +33,7 @@ public class TestCaseIfElse { @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9) - void m2(String[] args) { + void m2() { Object o; int i = 5; if (i != 5) { @@ -45,4 +45,19 @@ public class TestCaseIfElse { } o = "finish"; } + + @AliveRange(varName="o", bytecodeStart=11, bytecodeLength=3) + @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=2) + Object m3(boolean cond1, boolean cond2) { + Object o; + if (cond1) { + if (cond2) { + o = "then"; + } else { + o = "else"; + return null; + } + } + return null; + } } diff --git a/langtools/test/tools/javac/generics/diamond/T8041713/DiamondPlusUnexistingMethodRefCrashTest.java b/langtools/test/tools/javac/generics/diamond/T8041713/DiamondPlusUnexistingMethodRefCrashTest.java new file mode 100644 index 00000000000..40014d68c25 --- /dev/null +++ b/langtools/test/tools/javac/generics/diamond/T8041713/DiamondPlusUnexistingMethodRefCrashTest.java @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8041713 + * @summary Type inference of non-existent method references crashes the compiler + * @compile/fail/ref=DiamondPlusUnexistingMethodRefCrashTest.out -XDrawDiagnostics DiamondPlusUnexistingMethodRefCrashTest.java + */ + +public class DiamondPlusUnexistingMethodRefCrashTest { + DiamondPlusUnexistingMethodRefCrashTest m = + new DiamondPlusUnexistingMethodRefCrashTest<>(DiamondPlusUnexistingMethodRefCrashTest::doNotExists); +} diff --git a/langtools/test/tools/javac/generics/diamond/T8041713/DiamondPlusUnexistingMethodRefCrashTest.out b/langtools/test/tools/javac/generics/diamond/T8041713/DiamondPlusUnexistingMethodRefCrashTest.out new file mode 100644 index 00000000000..c7bba78d87d --- /dev/null +++ b/langtools/test/tools/javac/generics/diamond/T8041713/DiamondPlusUnexistingMethodRefCrashTest.out @@ -0,0 +1,2 @@ +DiamondPlusUnexistingMethodRefCrashTest.java:10:55: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, doNotExists, , , (compiler.misc.location: kindname.class, DiamondPlusUnexistingMethodRefCrashTest, null)) +1 error diff --git a/langtools/test/tools/javac/generics/inference/8043893/T8043893.java b/langtools/test/tools/javac/generics/inference/8043893/T8043893.java new file mode 100644 index 00000000000..9897582eae1 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/8043893/T8043893.java @@ -0,0 +1,43 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8043893 + * @summary Inference doesn't report error on incompatible upper bounds + * + * @compile -source 7 T8043893.java + * @compile/fail/ref=T8043893.out -Xlint:-options -XDrawDiagnostics -source 8 T8043893.java + */ + +class T8043893 { + + interface S1 { } + + interface S2 { } + + interface T0 { } + + interface T1 extends S1, S2 { } + + interface T2 extends S1, S2 { } + + interface T3 extends S1, S2 { } + + interface T4 extends S1 { } + + interface T5 extends S1 { } + + void m_intersection(T8043893 a) { } + + void m_class(T8043893 a) { } + + void test() { + //intersection type checks + m_intersection(new T8043893()); //ok in both 7 and 8 - Z = T1 + m_intersection(new T8043893()); //ok in 7, fails in 8 + m_intersection(new T8043893()); //ok in 7, fails in 8 + m_intersection(new T8043893()); //ok in both 7 and 8 - Z = T0 & T1 + //class type checks + m_class(new T8043893()); //ok in both 7 and 8 - Z = T4 + m_class(new T8043893()); //ok in 7, fails in 8 + m_class(new T8043893()); //ok in both 7 and 8 - Z = T0 & T4 + } +} diff --git a/langtools/test/tools/javac/generics/inference/8043893/T8043893.out b/langtools/test/tools/javac/generics/inference/8043893/T8043893.out new file mode 100644 index 00000000000..5fd584a0669 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/8043893/T8043893.out @@ -0,0 +1,4 @@ +T8043893.java:35:9: compiler.err.cant.apply.symbol: kindname.method, m_intersection, T8043893, T8043893, kindname.class, T8043893, (compiler.misc.incompatible.upper.bounds: Z, T8043893.T2,T8043893.T1) +T8043893.java:36:9: compiler.err.cant.apply.symbol: kindname.method, m_intersection, T8043893, T8043893, kindname.class, T8043893, (compiler.misc.incompatible.upper.bounds: Z, T8043893.T3,T8043893.T1) +T8043893.java:40:9: compiler.err.cant.apply.symbol: kindname.method, m_class, T8043893, T8043893, kindname.class, T8043893, (compiler.misc.incompatible.upper.bounds: Z, T8043893.T5,T8043893.T4) +3 errors diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out similarity index 88% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out index 52b1702f12a..22d9a9729fc 100644 --- a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out +++ b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out @@ -3,37 +3,37 @@ EagerReturnTypeResolutionTestb.java:43:9: compiler.err.cant.apply.symbol: kindna EagerReturnTypeResolutionTestb.java:44:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:45:26: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:74:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) -EagerReturnTypeResolutionTestb.java:75:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:75:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:77:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object)) EagerReturnTypeResolutionTestb.java:78:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) -EagerReturnTypeResolutionTestb.java:79:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:79:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:81:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:82:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) -EagerReturnTypeResolutionTestb.java:83:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:83:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:85:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) EagerReturnTypeResolutionTestb.java:86:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object)) EagerReturnTypeResolutionTestb.java:87:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) EagerReturnTypeResolutionTestb.java:89:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:90:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) EagerReturnTypeResolutionTestb.java:91:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J) -EagerReturnTypeResolutionTestb.java:92:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:92:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) EagerReturnTypeResolutionTestb.java:94:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.J>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J>>, EagerReturnTypeResolutionTestb.I,java.lang.Object)) EagerReturnTypeResolutionTestb.java:95:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J) -EagerReturnTypeResolutionTestb.java:96:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:96:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) EagerReturnTypeResolutionTestb.java:98:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J>>, EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:99:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J) -EagerReturnTypeResolutionTestb.java:100:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:100:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) EagerReturnTypeResolutionTestb.java:102:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) EagerReturnTypeResolutionTestb.java:103:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) EagerReturnTypeResolutionTestb.java:104:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) EagerReturnTypeResolutionTestb.java:105:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) -EagerReturnTypeResolutionTestb.java:106:9: compiler.err.cant.apply.symbol: kindname.method, takeI, EagerReturnTypeResolutionTestb.I, java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Integer, java.lang.Integer,java.lang.String) +EagerReturnTypeResolutionTestb.java:106:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object) EagerReturnTypeResolutionTestb.java:108:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object)) EagerReturnTypeResolutionTestb.java:109:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) -EagerReturnTypeResolutionTestb.java:110:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:110:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object) EagerReturnTypeResolutionTestb.java:112:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object) EagerReturnTypeResolutionTestb.java:113:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) -EagerReturnTypeResolutionTestb.java:114:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:114:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.incompatible.upper.bounds: T, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object) EagerReturnTypeResolutionTestb.java:174:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long)) EagerReturnTypeResolutionTestb.java:175:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long)) EagerReturnTypeResolutionTestb.java:176:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long)) diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out b/langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out similarity index 100% rename from langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out rename to langtools/test/tools/javac/generics/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out diff --git a/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java b/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java new file mode 100644 index 00000000000..98c7cf8dabb --- /dev/null +++ b/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8015927 + * @summary Class reference duplicates in constant pool + * @clean ClassRefDupInConstantPoolTest$Duplicates.class + * @run main ClassRefDupInConstantPoolTest + */ + +import java.util.TreeSet; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.*; + +public class ClassRefDupInConstantPoolTest { + public static void main(String[] args) throws Exception { + ClassFile cls = ClassFile.read(ClassRefDupInConstantPoolTest.class. + getResourceAsStream("ClassRefDupInConstantPoolTest$Duplicates.class")); + ConstantPool pool = cls.constant_pool; + + int duplicates = 0; + TreeSet set = new TreeSet<>(); + for (CPInfo i : pool.entries()) { + if (i.getTag() == ConstantPool.CONSTANT_Class) { + CONSTANT_Class_info ci = (CONSTANT_Class_info)i; + if (!set.add(ci.name_index)) { + duplicates++; + System.out.println("DUPLICATE CLASS REF " + ci.getName()); + } + } + } + if (duplicates > 0) + throw new Exception("Test Failed"); + } + + class Duplicates { + String concat(String s1, String s2) { + return s1 + (s2 == s1 ? " " : s2); + } + } +} diff --git a/langtools/test/tools/javac/lambda/T8031967.java b/langtools/test/tools/javac/lambda/T8031967.java new file mode 100644 index 00000000000..3836ecd0406 --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8031967.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8031967 + * @summary Ensure javac can handle very deeply nested chain of method invocations occurring as + * a parameter to other method invocations. + * @run main T8031967 + */ + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; + +public class T8031967 { + + public static void main(String... args) throws IOException { + new T8031967().run(); + } + + final int depth = 50; + + private void run() throws IOException { + runTestCase(true); + runTestCase(false); + } + + private void runTestCase(boolean withErrors) throws IOException { + StringBuilder code = new StringBuilder(); + + code.append("public class Test {\n" + + " private void test() {\n" + + " GroupLayout l = new GroupLayout();\n" + + " l.setHorizontalGroup(\n"); + + gen(code, depth); + code.append(" );\n" + + " }\n"); + if (!withErrors) { + code.append(" class GroupLayout {\n" + + " ParallelGroup createParallelGroup() {return null;}\n" + + " ParallelGroup createParallelGroup(int i) {return null;}\n" + + " ParallelGroup createParallelGroup(int i, int j) {return null;}\n" + + " void setHorizontalGroup(Group g) { }\n" + + " }\n" + + " \n" + + " class Group {\n" + + " Group addGroup(Group g) { return this; }\n" + + " Group addGroup(int i, Group g) { return this; }\n" + + " Group addGap(int i) { return this; }\n" + + " Group addGap(long l) { return this; }\n" + + " Group addGap(int i, int j) { return this; }\n" + + " Group addComponent(Object c) { return this; }\n" + + " Group addComponent(int i, Object c) { return this; }\n" + + " }\n" + + " class ParallelGroup extends Group {\n" + + " Group addGroup(Group g) { return this; }\n" + + " Group addGroup(int i, Group g) { return this; }\n" + + " Group addGap(int i) { return this; }\n" + + " Group addGap(int i, int j) { return this; }\n" + + " Group addComponent(Object c) { return this; }\n" + + " Group addComponent(int i, Object c) { return this; }\n" + + " }\n"); + } + + code.append("}\n"); + + JavaSource source = new JavaSource(code.toString()); + List sourceList = Arrays.asList(source); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticListener noErrors = (diagnostic) -> { + throw new IllegalStateException("Should not produce errors: " + diagnostic); + }; + JavacTask task = (JavacTask) compiler.getTask(null, null, withErrors ? null : noErrors, + null, null, sourceList); + + task.analyze(); + } + + private void gen(StringBuilder code, int depth) { + code.append("l.createParallelGroup()\n"); + if (depth > 0) { + code.append(".addGroup(\n"); + gen(code, depth - 1); + code.append(")"); + } + + code.append(".addGap(1)\n" + + ".addComponent(new Object())\n" + + ".addGap(1)\n" + + ".addComponent(new Object())"); + } + + class JavaSource extends SimpleJavaFileObject { + + final String code; + public JavaSource(String code) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } + } +} diff --git a/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java new file mode 100644 index 00000000000..5bd38c79d59 --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java @@ -0,0 +1,12 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8041704 + * @summary wrong error message when mixing lambda expression and inner class + * @compile/fail/ref=ErrorMessageTest.out -XDrawDiagnostics ErrorMessageTest.java + */ + +public class ErrorMessageTest { + void f(Runnable r) { + f(() -> { f(new MISSING() { public void run() {} }); }); + } +} diff --git a/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out new file mode 100644 index 00000000000..bdd25993c86 --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out @@ -0,0 +1,2 @@ +ErrorMessageTest.java:10:25: compiler.err.cant.resolve.location: kindname.class, MISSING, , , (compiler.misc.location: kindname.class, ErrorMessageTest, null) +1 error diff --git a/langtools/test/tools/javac/lambda/TargetType23.java b/langtools/test/tools/javac/lambda/TargetType23.java index bac45e9351e..4f20232a3cc 100644 --- a/langtools/test/tools/javac/lambda/TargetType23.java +++ b/langtools/test/tools/javac/lambda/TargetType23.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8003280 + * @bug 8003280 8034223 * @summary Add lambda tests * check case of ambiguous method call with lambda whose body cannot complete normally diff --git a/langtools/test/tools/javac/types/BadSigTest.java b/langtools/test/tools/javac/types/BadSigTest.java new file mode 100644 index 00000000000..14b3ff9cbb0 --- /dev/null +++ b/langtools/test/tools/javac/types/BadSigTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8037934 + * @summary Javac generates invalid signatures for local types + * @run main BadSigTest + */ + +public class BadSigTest { + void m(){ + class Local1{} + class Local2 extends Local1{} + Local2.class.getTypeParameters(); + } + public static void main(String[] args) { + new BadSigTest().m(); + } +} diff --git a/langtools/test/tools/javac/util/StringUtilsTest.java b/langtools/test/tools/javac/util/StringUtilsTest.java index ec8db20ef77..854a77381b1 100644 --- a/langtools/test/tools/javac/util/StringUtilsTest.java +++ b/langtools/test/tools/javac/util/StringUtilsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8029800 + * @bug 8029800 8043186 * @summary Unit test StringUtils * @run main StringUtilsTest */ @@ -44,12 +44,14 @@ public class StringUtilsTest { assertEquals("\u0131", "I".toLowerCase()); assertEquals("\u0130", "i".toUpperCase()); - //verify the StringUtils does what it should + //verify the StringUtils.toLowerCase/toUpperCase do what they should: assertEquals("i", StringUtils.toLowerCase("I")); assertEquals("I", StringUtils.toUpperCase("i")); - //verify we can use index from indexOf of toLowerCase String in the original: - assertEquals(2, StringUtils.toLowerCase("\u0130\u0130lookFor").indexOf("lookfor")); + //verify StringUtils.caseInsensitiveIndexOf works: + assertEquals(2, StringUtils.indexOfIgnoreCase(" lookFor", "lookfor")); + assertEquals(11, StringUtils.indexOfIgnoreCase(" lookFor LOOKfor", "lookfor", 11)); + assertEquals(2, StringUtils.indexOfIgnoreCase("\u0130\u0130lookFor", "lookfor")); } void assertEquals(String expected, String actual) { diff --git a/make/Jprt.gmk b/make/Jprt.gmk index 75ee37da374..a7f9226d99f 100644 --- a/make/Jprt.gmk +++ b/make/Jprt.gmk @@ -23,8 +23,22 @@ # questions. # -# This file is contains targets utilities needed by JPRT. +# This file contains targets and utilities needed by JPRT. +# Cygpath is only defined when running on Cygwin +ifneq ($(CYGPATH), ) + # If we get JPRT_ARCHIVE_*BUNDLE externally, make sure they have /cygdrive + # style paths + ifdef JPRT_ARCHIVE_BUNDLE + override JPRT_ARCHIVE_BUNDLE := $(shell $(CYGPATH) -u $(JPRT_ARCHIVE_BUNDLE)) + endif + ifdef JPRT_ARCHIVE_INSTALL_BUNDLE + override JPRT_ARCHIVE_INSTALL_BUNDLE := $(shell $(CYGPATH) -u $(JPRT_ARCHIVE_INSTALL_BUNDLE)) + endif +endif + +# When running in JPRT these will be provided. Need defaults so that this makefile +# is valid anyway. ifndef JPRT_ARCHIVE_BUNDLE JPRT_ARCHIVE_BUNDLE=/tmp/jprt_bundles/j2sdk-image.zip endif diff --git a/nashorn/.hgignore b/nashorn/.hgignore index 6d68c1d476d..6cfabad507b 100644 --- a/nashorn/.hgignore +++ b/nashorn/.hgignore @@ -13,6 +13,8 @@ webrev.zip *.clazz *.log *.orig +*.rej +*~ genfiles.properties hotspot.log .DS_Store* diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 4eb279cc390..31e3bb77617 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -247,3 +247,6 @@ b3517e51f40477f10db8bc30a557aa0ea712c274 jdk9-b02 4d60c3292e14aac90dc3b8232496ba4af4254cc3 jdk9-b11 282e9a675e079cc84dbfaa4c10050f08397faab0 jdk9-b12 be4580ae56e2ef0ce521d3f840753eaa83cacf33 jdk9-b13 +806df06b6ac58d3e9c9c6a680dbdd7a6c94ca700 jdk9-b14 +32b66f4661eac52f8b04fb3d7703feb2c96febb7 jdk9-b15 +fed8c83dfba4dce94d2ae1cb82f026634ff2a3e4 jdk9-b16 diff --git a/nashorn/bin/checkintest.sh b/nashorn/bin/checkintest.sh deleted file mode 100644 index c4a9e96ca12..00000000000 --- a/nashorn/bin/checkintest.sh +++ /dev/null @@ -1,266 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -#best pass rate at test 262 known -TEST262_PASS_AT_LEAST=435 - -RUN_TEST="true" -RUN_TEST262="true" -RUN_NODE="true" -KEEP_OUTPUT="true" -CLEAN_AND_BUILD_NASHORN="true" - -#the stable node version to sync against -NODE_LAST_STABLE=v0.6.18 - -#parse args -for arg in $* -do - if [ $arg = "--no-test" ]; then - RUN_TEST="false" - echo "**** WARNING - you have disabled 'ant test', which is a minimum checkin requirement..." - elif [ $arg = "--no-262" ]; then - RUN_TEST262="false" - elif [ $arg = "--no-node" ]; then - RUN_NODE="false" - elif [ $arg = "--no-build" ]; then - CLEAN_AND_BUILD_NASHORN="false" - elif [ $arg = "--no-logs" ]; then - KEEP_OUTPUT="false" - fi -done - -function lastpart() { - arr=$(echo $1 | tr "/" "\n") - for x in $arr - do - _last=$x - done - echo $_last -} - -function check_installed() { - which $1 >/dev/null - if [ $? -ne 0 ]; then - echo "Error $1 not installed: $?" - exit 2 - fi -} - -check_installed hg -check_installed git -check_installed mv -check_installed git - -PWD=$(pwd); - -while [ -z $NASHORN_ROOT ] -do - if [ -e $PWD/.hg ]; then - NASHORN_ROOT=${PWD} - break - fi - PWD=$(dirname ${PWD}) -done - -echo "Nashorn root detected at ${NASHORN_ROOT}" - -COMMON_ROOT=$(dirname $NASHORN_ROOT) -echo "Common root is ${COMMON_ROOT}" - -echo "Running checkintest..." - -ABSOLUTE_NASHORN_HOME=$COMMON_ROOT/$(lastpart $NASHORN_ROOT) - -if [ $CLEAN_AND_BUILD_NASHORN != "false" ]; then - echo "Cleaning and building nashorn at $ABSOLUTE_NASHORN_HOME/nashorn..." - $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant clean >/dev/null 2>/dev/null) - $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant jar >/dev/null 2>/dev/null) - echo "Done." -fi - -function failure_check() { - while read line - do - LINE=$(echo $line | grep "Tests run") - if [ "${LINE}" != "" ]; then - RESULT=$(echo $line | grep "Failures: 0" | grep "Errors: 0") - if [ "${RESULT}" == "" ]; then - TESTNAME=$2 - echo "There were errors in ${TESTNAME} : ${LINE}" - exit 1 - fi - fi - done < $1 -} - -function test() { - TEST_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX) - echo "Running 'ant test' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..." - $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test >$TEST_OUTPUT) - echo "Done." - - failure_check $TEST_OUTPUT - - echo "**** SUCCESS: 'ant test' successful" - - if [ $KEEP_OUTPUT == "true" ]; then - cp $TEST_OUTPUT ./checkintest.test.log - rm -fr $TEST_OUTPUT - fi -} - -if [ $RUN_TEST != "false" ]; then - test; -fi - -function test262() { - - echo "Running 'ant test262parallel' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..." - TEST262_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX) - - echo "Looking for ${ABSOLUTE_NASHORN_HOME}/test/test262..." - - if [ ! -e $ABSOLUTE_NASHORN_HOME/nashorn/test/test262 ]; then - echo "test262 is missing... looking in $COMMON_ROOT..." - if [ ! -e $COMMON_ROOT/test262 ]; then - echo "... not there either... cloning from repo..." - hg clone http://hg.ecmascript.org/tests/test262 $COMMON_ROOT/test262 >/dev/null 2>/dev/null - echo "Done." - fi - echo "Adding soft link ${COMMON_ROOT}/test262 -> ${ABSOLUTE_NASHORN_HOME}/test/test262..." - ln -s $COMMON_ROOT/test262 $ABSOLUTE_NASHORN_HOME/nashorn/test/test262 - echo "Done." - fi - - echo "Ensuring test262 is up to date..." - $(cd $ABSOLUTE_NASHORN_HOME/nashorn/test/test262; hg pull -u >/dev/null 2>/dev/null) - echo "Done." - - echo "Running test262..." - $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test262parallel > $TEST262_OUTPUT) - - FAILED=$(cat $TEST262_OUTPUT|grep "Tests run:"| cut -d ' ' -f 15 |tr -cd '"[[:digit:]]') - if [ $FAILED -gt $TEST262_PASS_AT_LEAST ]; then - echo "FAILURE: There are ${FAILED} failures in test262 and can be no more than ${TEST262_PASS_AT_LEAST}" - cp $TEST262_OUTPUT ./checkintest.test262.log - echo "See ./checkintest.test262.log" - echo "Terminating due to error" - exit 1 - elif [ $FAILED -lt $TEST262_PASS_AT_LEAST ]; then - echo "There seem to have been fixes to 262. ${FAILED} < ${TEST262_PASS_AT_LEAST}. Please update limit in bin/checkintest.sh" - fi - - echo "**** SUCCESS: Test262 passed with no more than ${TEST262_PASS_AT_LEAST} failures." - - if [ $KEEP_OUTPUT == "true" ]; then - cp $TEST262_OUTPUT ./checkintest.test262.log - rm -fr $TEST262_OUTPUT - fi -} - -if [ $RUN_TEST262 != "false" ]; then - test262; -fi; - -function testnode() { - TESTNODEJAR_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX) - - echo "Running node tests..." -#replace node jar properties nashorn with this nashorn - - NODEJAR_PROPERTIES=~/nodejar.properties - - NODE_HOME=$(cat $NODEJAR_PROPERTIES | grep ^node.home | cut -f2 -d=) - NASHORN_HOME=$(cat $NODEJAR_PROPERTIES | grep ^nashorn.home | cut -f2 -d=) - - ABSOLUTE_NODE_HOME=$COMMON_ROOT/$(lastpart $NODE_HOME) - - echo "Writing nodejar.properties..." - - cat > $NODEJAR_PROPERTIES << EOF -node.home=../node -nashorn.home=../$(lastpart $NASHORN_ROOT) -EOF - echo "Done." - echo "Checking node home ${ABSOLUTE_NODE_HOME}..." - - if [ ! -e $ABSOLUTE_NODE_HOME ]; then - echo "Node base dir not found. Cloning node..." - $(cd $COMMON_ROOT; git clone https://github.com/joyent/node.git $(lastpart $NODE_HOME) >/dev/null 2>/dev/null) - echo "Done." - echo "Updating to last stable version ${NODE_LAST_STABLE}..." - $(cd $ABSOLUTE_NODE_HOME; git checkout $NODE_LAST_STABLE >/dev/null 2>/dev/null) - echo "Done." - echo "Running configure..." - $(cd $ABSOLUTE_NODE_HOME; ./configure >/dev/null 2>/dev/null) - echo "Done." - fi - - echo "Ensuring node is built..." -#make sure node is built - $(cd $ABSOLUTE_NODE_HOME; make >/dev/null 2>/dev/null) - echo "Done." - - NODEJAR_HOME=$COMMON_ROOT/nodejar - - if [ ! -e $NODEJAR_HOME ]; then - echo "No node jar home found. cloning from depot..." - $(cd $COMMON_ROOT; hg clone https://hg.kenai.com/hg/nodejs~source nodejar >/dev/null 2>/dev/null) - $(cd $COMMON_ROOT/nodejar; ant >/dev/null) - echo "Done." - echo "Copying node files..." - $(cd $COMMON_ROOT/nodejar; ant copy-node-files >/dev/null 2>/dev/null) - echo "Patching node files..." - $(cd $COMMON_ROOT/nodejar; ant patch-node-files >/dev/null 2>/dev/null) - echo "Done." - fi - - echo "Ensuring node.jar is up to date from source depot..." - $(cd $COMMON_ROOT/nodejar; hg pull -u >/dev/null 2>/dev/null) - echo "Done." - - echo "Installing nashorn..." - $(cd $COMMON_ROOT/nodejar; ant >/dev/null) - echo "Done." - - echo "Running node.jar test..." - $(cd $COMMON_ROOT/nodejar; mvn clean verify >$TESTNODEJAR_OUTPUT) - echo "Done." - - failure_check $TESTNODEJAR_OUTPUT - - echo "**** SUCCESS: Node test successful." - - if [ $KEEP_OUTPUT == "true" ]; then - rm -fr $TESTNODEJAR_OUTPUT - cp $TESTNODEJAR_OUTPUT ./checkintest.nodejar.log - fi -} - -if [ $RUN_NODE != "false" ]; then - testnode; -fi; - -echo "Finished" diff --git a/nashorn/bin/fixwhitespace.sh b/nashorn/bin/fixwhitespace.sh index cac757db100..d3274700f71 100644 --- a/nashorn/bin/fixwhitespace.sh +++ b/nashorn/bin/fixwhitespace.sh @@ -22,9 +22,16 @@ # questions. # -#convert tabs to spaces -find . -name "*.java" -exec sed -i "" 's/ / /g' {} \; - -#remove trailing whitespace -find . -name "*.java" -exec sed -i "" 's/[ ]*$//' \{} \; +fix() { + #convert tabs to spaces + find . -name $1 -exec sed -i "" 's/ / /g' {} \; + #remove trailing whitespace + find . -name $1 -exec sed -i "" 's/[ ]*$//' \{} \; +} +if [ ! -z $1 ]; then + fix $1; +else + fix "*.java" + fix "*.js" +fi diff --git a/nashorn/bin/run_octane.sh b/nashorn/bin/run_octane.sh new file mode 100644 index 00000000000..a50137f06fa --- /dev/null +++ b/nashorn/bin/run_octane.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +LOG="./octane_$(date|sed "s/ /_/g"|sed "s/:/_/g").log" + +run_one() { + sh ../bin/runopt.sh -scripting ../test/script/basic/run-octane.js -- $1 --verbose --iterations 25 | tee -a $LOG +} + +if [ -z $1 ]; then + + run_one "box2d" + run_one "code-load" + run_one "crypto" + run_one "deltablue" + run_one "earley-boyer" + run_one "gbemu" + run_one "mandreel" + run_one "navier-stokes" + run_one "pdfjs" + run_one "raytrace" + run_one "regexp" + run_one "richards" + run_one "splay" + run_one "typescript" + run_one "zlib" + +else + run_one $1 +fi diff --git a/nashorn/bin/rundiff.sh b/nashorn/bin/rundiff.sh new file mode 100644 index 00000000000..a672104ae7c --- /dev/null +++ b/nashorn/bin/rundiff.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# do two runs of a script, one optimistic and one pessimistic, expect identical outputs +# if not, display and error message and a diff + +which opendiff >/dev/null +RES=$? +if [ $RES = 0 ]; then + DIFFTOOL=opendiff +else + DIFFTOOL=diff +fi + +OPTIMISTIC=out_optimistic +PESSIMISTIC=out_pessimistic +$JAVA_HOME/bin/java -ea -jar ../dist/nashorn.jar ${@} >$PESSIMISTIC +$JAVA_HOME/bin/java -ea -Dnashorn.optimistic -jar ../dist/nashorn.jar ${@} >$OPTIMISTIC + +if ! diff -q $PESSIMISTIC $OPTIMISTIC >/dev/null ; then + echo "Failure! Results are different" + echo "" + $DIFFTOOL $PESSIMISTIC $OPTIMISTIC +else + echo "OK - Results are identical" +fi diff --git a/nashorn/bin/runopt.sh b/nashorn/bin/runopt.sh new file mode 100644 index 00000000000..7c308bd1b64 --- /dev/null +++ b/nashorn/bin/runopt.sh @@ -0,0 +1,110 @@ +#!/bin/sh +# +# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +########################################################################################### +# This is a helper script to evaluate nashorn with optimistic types +# it produces a flight recording for every run, and uses the best +# known flags for performance for the current configration +########################################################################################### + +# Flags to instrument lambdaform computation, caching, interpretation and compilation +# Default compile threshold for lambdaforms is 30 +#FLAGS="-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true" + + +# Flags to run trusted tests from the Nashorn test suite +#FLAGS="-Djava.security.manager -Djava.security.policy=../build/nashorn.policy -Dnashorn.debug" + + +# Unique timestamped file name for JFR recordings. For JFR, we also have to +# crank up the stack cutoff depth to 1024, because of ridiculously long lambda form +# stack traces. +# +# It is also recommended that you go into $JAVA_HOME/jre/lib/jfr/default.jfc and +# set the "method-sampling-interval" Normal and Maximum sample time as low as you +# can go (10 ms on most platforms). The default is normally higher. The increased +# sampling overhead is usually negligible for Nashorn runs, but the data is better + +JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr" + + +# Directory where to look for nashorn.jar in a dist folder. The default is "..", assuming +# that we run the script from the make dir +DIR=.. +NASHORN_JAR=$DIR/dist/nashorn.jar + + +# The built Nashorn jar is placed first in the bootclasspath to override the JDK +# nashorn.jar in $JAVA_HOME/jre/lib/ext. Thus, we also need -esa, as assertions in +# nashorn count as system assertions in this configuration + +# Type profiling default level is 111, 222 adds some compile time, but is faster + +$JAVA_HOME/bin/java \ +$FLAGS \ +-ea \ +-esa \ +-Xbootclasspath/p:$NASHORN_JAR \ +-Xms2G -Xmx2G \ +-XX:TypeProfileLevel=222 \ +-cp $CLASSPATH:../build/test/classes/ \ +jdk.nashorn.tools.Shell ${@} + +# Below are flags that may come in handy, but aren't used for default runs + +# Testing out new code optimizations using the generic hotspot "new code" parameter +#-XX:+UnlockDiagnosticVMOptions \ +#-XX:+UseNewCode \ + +# Flight recorder +#-XX:+UnlockCommercialFeatures \ +#-XX:+FlightRecorder \ +#-XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024 \ + + +# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine, +# keeping this flag around for experimental reasons. Replace + with - to switch it off +#-XX:+UseTypeSpeculation \ + + +# Same with math intrinsics. They should be enabled by default in 8u20 and 9 +#-XX:+UseMathExactIntrinsics \ + + +# Add -Dnashorn.time to time the compilation phases. +#-Dnashorn.time \ + + +# Add ShowHiddenFrames to get lambda form internals on the stack traces +#-XX:+ShowHiddenFrames \ + + +# Add print optoassembly to get an asm dump. This requires 1) a debug build, not product, +# That tired compilation is switched off, for C2 only output and that the number of +# compiler threads is set to 1 for determinsm. +#-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \ + +# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments) +# -XX:IncreaseFirstTierCompileThresholdAt=XX + diff --git a/nashorn/bin/runopt_noassert.sh b/nashorn/bin/runopt_noassert.sh new file mode 100644 index 00000000000..6331972ab64 --- /dev/null +++ b/nashorn/bin/runopt_noassert.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +#FLAGS="-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true" + +FILENAME="./optimistic_noassert_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr" + +DIR=.. +NASHORN_JAR=$DIR/dist/nashorn.jar + +$JAVA_HOME/bin/java \ +$FLAGS \ +-Xbootclasspath/p:$NASHORN_JAR \ +-Xms2G -Xmx2G \ +-XX:+UnlockCommercialFeatures \ +-XX:+FlightRecorder \ +-XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$FILENAME,stackdepth=1024 \ +-XX:TypeProfileLevel=222 \ +-XX:+UnlockExperimentalVMOptions \ +-XX:+UseTypeSpeculation \ +-XX:+UseMathExactIntrinsics \ +-XX:+UnlockDiagnosticVMOptions \ +-cp $CLASSPATH:../build/test/classes/ \ +jdk.nashorn.tools.Shell ${@} + +#-XX:+ShowHiddenFrames \ +#-XX:+PrintOptoAssembly \ +#-XX:-TieredCompilation \ +#-XX:CICompilerCount=1 \ diff --git a/nashorn/bin/runopt_nojfr.sh b/nashorn/bin/runopt_nojfr.sh new file mode 100644 index 00000000000..daf3c6a0073 --- /dev/null +++ b/nashorn/bin/runopt_nojfr.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +#FLAGS="-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true" + +DIR=.. +NASHORN_JAR=$DIR/dist/nashorn.jar + +$JAVA_HOME/bin/java \ +$FLAGS \ +-ea \ +-esa \ +-Xbootclasspath/p:$NASHORN_JAR \ +-Xms2G -Xmx2G \ +-XX:+UnlockCommercialFeatures \ +-XX:TypeProfileLevel=222 \ +-XX:+UnlockExperimentalVMOptions \ +-XX:+UseTypeSpeculation \ +-XX:+UseMathExactIntrinsics \ +-XX:+UnlockDiagnosticVMOptions \ +-XX:+UseNewCode \ +-cp $CLASSPATH:../build/test/classes/ \ +jdk.nashorn.tools.Shell ${@} + +#-XX:+ShowHiddenFrames \ +#-XX:+PrintOptoAssembly \ +#-XX:-TieredCompilation \ +#-XX:CICompilerCount=1 \ diff --git a/nashorn/bin/verbose_octane.bat b/nashorn/bin/verbose_octane.bat deleted file mode 100644 index ab9e48469a5..00000000000 --- a/nashorn/bin/verbose_octane.bat +++ /dev/null @@ -1,59 +0,0 @@ -rem -rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. -rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -rem -rem This code is free software; you can redistribute it and/or modify it -rem under the terms of the GNU General Public License version 2 only, as -rem published by the Free Software Foundation. -rem -rem This code is distributed in the hope that it will be useful, but WITHOUT -rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -rem version 2 for more details (a copy is included in the LICENSE file that -rem accompanied this code). -rem -rem You should have received a copy of the GNU General Public License version -rem 2 along with this work; if not, write to the Free Software Foundation, -rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -rem -rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -rem or visit www.oracle.com if you need additional information or have any -rem questions. -rem -@echo off - -if "%JAVA_HOME%" neq "" ( - call :run "%JAVA_HOME%/bin/java" -) else ( - call :run java -) -goto :EOF - -:run -setlocal -set NASHORN_JAR=dist/nashorn.jar -set JVM_FLAGS=-Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -jar %NASHORN_JAR% -set JVM_FLAGS7=-Xbootclasspath/p:%NASHORN_JAR% %JVM_FLAGS% -set OCTANE_ARGS=--verbose --iterations 7 - -%1 -fullversion 2>&1 | findstr /L /C:"version ""1.7" -if %errorlevel% equ 0 ( - set CMD=%1 %JVM_FLAGS7% -) else ( - %1 -fullversion - set CMD=%1 %JVM_FLAGS% -) - -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/box2d.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/code-load.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/crypto.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/deltablue.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/gbemu.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/navier-stokes.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/pdfjs.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/raytrace.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/regexp.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/richards.js %OCTANE_ARGS% -%CMD% test/script/basic/run-octane.js -- test/script/external/octane/splay.js %OCTANE_ARGS% -endlocal -goto :EOF diff --git a/nashorn/bin/verbose_octane.sh b/nashorn/bin/verbose_octane.sh deleted file mode 100644 index 1895afed146..00000000000 --- a/nashorn/bin/verbose_octane.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -ITERS=$1 -if [ -z $ITERS ]; then - ITERS=7 -fi -NASHORN_JAR=dist/nashorn.jar -JVM_FLAGS="-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+UnlockDiagnosticVMOptions -Dnashorn.unstable.relink.threshold=8 -Xms2G -Xmx2G -XX:+TieredCompilation -server -jar ${NASHORN_JAR}" -JVM_FLAGS7="-Xbootclasspath/p:${NASHORN_JAR} ${JVM_FLAGS}" -OCTANE_ARGS="--verbose --iterations ${ITERS}" - -BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "navier-stokes.js" "pdfjs.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" ) -# TODO mandreel.js has metaspace issues - -if [ ! -z $JAVA7_HOME ]; then - echo "running ${ITERS} iterations with java7 using JAVA_HOME=${JAVA7_HOME}..." - for BENCHMARK in "${BENCHMARKS[@]}" - do - CMD="${JAVA7_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/${BENCHMARK} ${OCTANE_ARGS}" - $CMD - done -else - echo "no JAVA7_HOME set. skipping java7" -fi - -if [ ! -z $JAVA8_HOME ]; then - echo "running ${ITERS} iterations with java8 using JAVA_HOME=${JAVA8_HOME}..." - for BENCHMARK in "${BENCHMARKS[@]}" - do - CMD="${JAVA8_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/${BENCHMARK} ${OCTANE_ARGS}" - $CMD - done -else - echo "no JAVA8_HOME set." -fi - -echo "Done" diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java index bb6abbc0170..2059567bb31 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java @@ -31,29 +31,29 @@ import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.GETTER_PREFIX; import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.LIST_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC; diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java index 67cbde44fdd..2661e096a48 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java @@ -32,9 +32,9 @@ import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java index e47f8b160ad..1132db98541 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java @@ -319,7 +319,7 @@ public final class MemberInfo implements Cloneable { break; case FUNCTION: { final Type returnType = Type.getReturnType(javaDesc); - if (!isValidJSType(returnType)) { + if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) { error("return value of a @Function method should be a valid JS type, found " + returnType); } final Type[] argTypes = Type.getArgumentTypes(javaDesc); @@ -351,7 +351,7 @@ public final class MemberInfo implements Cloneable { break; case SPECIALIZED_FUNCTION: { final Type returnType = Type.getReturnType(javaDesc); - if (!isValidJSType(returnType)) { + if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) { error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType); } final Type[] argTypes = Type.getArgumentTypes(javaDesc); @@ -371,9 +371,8 @@ public final class MemberInfo implements Cloneable { error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]); } - final Type returnType = Type.getReturnType(javaDesc); - if (!isJavaLangObject(returnType)) { - error("return type of a @Getter method should be Object, found: " + javaDesc); + if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) { + error("return type of getter should not be void"); } } break; diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java index 479d1d31f21..a8d6ae2b981 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java @@ -413,7 +413,8 @@ public class MethodGenerator extends MethodVisitor { super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", - "(Ljava/lang/String;)V", false); + "(Ljava/lang/String;)V", + false); } // print the object on the top of the stack @@ -426,6 +427,7 @@ public class MethodGenerator extends MethodVisitor { super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", - "(Ljava/lang/Object;)V", false); + "(Ljava/lang/Object;)V", + false); } } diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java index 7b1fff7607e..8eb19b7d112 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java @@ -31,9 +31,9 @@ import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java index 1d724187dbe..fb72bbe65ec 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java @@ -26,9 +26,8 @@ package jdk.nashorn.internal.tools.nasgen; import java.lang.invoke.MethodHandle; -import java.lang.reflect.Method; -import java.util.Collection; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import jdk.internal.org.objectweb.asm.Type; diff --git a/nashorn/docs/DEVELOPER_README b/nashorn/docs/DEVELOPER_README index 9a2fffdf84a..fe140954c1a 100644 --- a/nashorn/docs/DEVELOPER_README +++ b/nashorn/docs/DEVELOPER_README @@ -737,26 +737,6 @@ an implementation based on Joni, the regular expression engine used by the JRuby project. The default value for this flag is "joni" -SYSTEM PROPERTY: -Dnashorn.time - -This enables timers for various phases of script compilation. The timers -will be dumped when the Nashorn process exits. We see a percentage value -of how much time was spent not executing bytecode (i.e. compilation and -internal tasks) at the end of the report. - -Here is an example: - -[JavaScript Parsing] 61 ms -[Constant Folding] 11 ms -[Control Flow Lowering] 26 ms -[Type Attribution] 81 ms -[Range Analysis] 0 ms -[Code Splitting] 29 ms -[Type Finalization] 19 ms -[Bytecode Generation] 189 ms -[Code Installation] 7 ms -Total runtime: 508 ms (Non-runtime: 423 ms [83%]) - =============== 2. The loggers. =============== @@ -887,6 +867,34 @@ etc. It will also show the internal representation of respective field (Object in the normal case, unless running with the dual field representation) +* time + +This enables timers for various phases of script compilation. The timers +will be dumped when the Nashorn process exits. We see a percentage value +of how much time was spent not executing bytecode (i.e. compilation and +internal tasks) at the end of the report. + +A finer level than "info" will show individual compilation timings as they +happen. + +Here is an example: + +[time] Accumulated complation phase Timings: +[time] +[time] 'JavaScript Parsing' 1076 ms +[time] 'Constant Folding' 159 ms +[time] 'Control Flow Lowering' 303 ms +[time] 'Program Point Calculation' 282 ms +[time] 'Builtin Replacement' 71 ms +[time] 'Code Splitting' 670 ms +[time] 'Symbol Assignment' 474 ms +[time] 'Scope Depth Computation' 249 ms +[time] 'Optimistic Type Assignment' 186 ms +[time] 'Local Variable Type Calculation' 526 ms +[time] 'Bytecode Generation' 5177 ms +[time] 'Class Installation' 1854 ms +[time] +[time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%]) ======================= 3. Undocumented options @@ -914,11 +922,10 @@ A short summary follows: -cp, -classpath (-cp path. Specify where to find user class files.) - -co, --compile-only (Compile script without running. Exit after compilation) + -co, --compile-only (Compile without running.) param: [true|false] default: false - -d, --dump-debug-dir (specify a destination directory to dump class files. - This must be combined with the --compile-only option to work) + -d, --dump-debug-dir (specify a destination directory to dump class files.) param: --debug-lines (Generate line number table in .class files.) @@ -954,10 +961,6 @@ A short summary follows: -h, -help (Print help for command line flags.) param: [true|false] default: false - --lazy-compilation (EXPERIMENTAL: Use lazy code generation strategies - do not compile - the entire script at once.) - param: [true|false] default: false - --loader-per-compile (Create a new class loader per compile.) param: [true|false] default: true @@ -965,16 +968,16 @@ A short summary follows: param: default: en-US --log (Enable logging of a given level for a given number of sub systems. - [for example: --log=fields:finest,codegen:info]) + [for example: --log=fields:finest,codegen:info].) param: ,* - -nj, --no-java (No Java support) + -nj, --no-java (Disable Java support.) param: [true|false] default: false - -nse, --no-syntax-extensions (No non-standard syntax extensions) + -nse, --no-syntax-extensions (Disallow non-standard syntax extensions.) param: [true|false] default: false - -nta, --no-typed-arrays (No Typed arrays support) + -nta, --no-typed-arrays (Disable typed arrays support.) param: [true|false] default: false --parse-only (Parse without compiling.) @@ -983,13 +986,15 @@ A short summary follows: --print-ast (Print abstract syntax tree.) param: [true|false] default: false - --print-code (Print bytecode.) - param: [true|false] default: false + -pc, --print-code (Print generated bytecode. If a directory is specified, nothing will + be dumped to stderr. Also, in that case, .dot files will be generated + for all functions or for the function with the specified name only.) + param: [dir:,function:] --print-lower-ast (Print lowered abstract syntax tree.) param: [true|false] default: false - --print-lower-parse (Print the parse tree after lowering.) + -plp, --print-lower-parse (Print the parse tree after lowering.) param: [true|false] default: false --print-mem-usage (Print memory usage of IR after each compile stage.) @@ -998,7 +1003,7 @@ A short summary follows: --print-no-newline (Print function will not print new line char.) param: [true|false] default: false - --print-parse (Print the parse tree.) + -pp, --print-parse (Print the parse tree.) param: [true|false] default: false --print-symbols (Print the symbol table.) @@ -1007,21 +1012,13 @@ A short summary follows: -pcs, --profile-callsites (Dump callsite profile data.) param: [true|false] default: false - --range-analysis (EXPERIMENTAL: Do range analysis using known compile time types, - and try to narrow number types) - param: [true|false] default: false - -scripting (Enable scripting features.) param: [true|false] default: false - --specialize-calls (EXPERIMENTAL: Specialize all or a set of method according - to callsite parameter types) - param: [=function_1,...,function_n] - - --stderr (Redirect stderr to a filename or to another tty, e.g. stdout) + --stderr (Redirect stderr to a filename or to another tty, e.g. stdout.) param: - --stdout (Redirect stdout to a filename or to another tty, e.g. stderr) + --stdout (Redirect stdout to a filename or to another tty, e.g. stderr.) param: -strict (Run scripts in strict mode.) @@ -1031,7 +1028,7 @@ A short summary follows: param: default: Europe/Stockholm -tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses] - enterexit [trace callsite enter/exit], objects [print object properties]) + enterexit [trace callsite enter/exit], objects [print object properties].) param: [=[option,]*] --verify-code (Verify byte code before running.) diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml index 8225df1cf0c..ae76718fd03 100644 --- a/nashorn/make/build-benchmark.xml +++ b/nashorn/make/build-benchmark.xml @@ -1,384 +1,333 @@ - - - - - - - - - - + + + + + + - - - - + + + - - - - + - - - - + - - - - - - + + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - - - + + + + + - - - - + - - - - + - - - - - - + + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - - + + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - + + + - - - - + - - - - + - - - - - + + + + - - - - + - - - - + - - - - + + + - - - - + - - - + + + + + + + + + + + + + + + + + + + - - - + + + + + - - - - - - - - - - - - + + - - + + + + - - + + + + - - + + + + + + + + + + + + + + - + - + @@ -386,11 +335,11 @@ - + - + @@ -400,12 +349,14 @@ fork="true" dir="."> + + - + - + @@ -416,18 +367,22 @@ - + + dir="${sunspider-test-sys-prop.test.js.roots}" + excludes="${sunspider-test-sys-prop.test.js.exclude.list}"> + + - + + + + + + @@ -448,6 +406,9 @@ + + + @@ -458,8 +419,13 @@ fork="true" dir="."> + + + + + diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index e8058a32f9b..0edc7e9e4c9 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -1,4 +1,5 @@ + + - - @@ -51,7 +51,7 @@ - + @@ -196,14 +196,16 @@ - - + + - + @@ -211,6 +213,19 @@ + + + + + + + + + + + + @@ -349,6 +364,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { + @@ -360,6 +376,10 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { + + + + @@ -376,18 +396,22 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { - - - - + - - - - - - + + + + + + + + + + + + @@ -398,15 +422,15 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { - + - + - + - - + + @@ -421,7 +445,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { - + @@ -440,7 +464,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { - + @@ -480,6 +504,26 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { + + + + + + + + + + + + + + + + + + @@ -587,7 +631,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { - + @@ -608,4 +652,6 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" { + + diff --git a/nashorn/make/nbproject/ide-targets.xml b/nashorn/make/nbproject/ide-targets.xml index 70b3e68fcb7..a592cff6a07 100644 --- a/nashorn/make/nbproject/ide-targets.xml +++ b/nashorn/make/nbproject/ide-targets.xml @@ -31,9 +31,10 @@ + - + diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 5af728794e2..dd43dda4f2b 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -53,12 +53,15 @@ parallel.test.runner=jdk.nashorn.internal.test.framework.ParallelTestRunner # test classes directory build.test.classes.dir=${build.dir}/test/classes + # nashorn test jar - internal tests jar and api tests jar nashorn.internal.tests.jar=${build.dir}/nashorn-internal-tests.jar nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar # test results directory build.test.results.dir=${build.dir}/test/reports +build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports +build.nooptimistic.test.results.dir=${build.dir}/test/nooptimistic/reports # This directory is removed when the project is cleaned: dist.dir=dist @@ -113,6 +116,7 @@ run.classpath=\ # test scripts to run test.dir=test +test.nosecurity.dir=test/script/nosecurity test.script.dir=test/script test.basic.dir=test/script/basic test.maptests.dir=test/script/maptests @@ -131,8 +135,12 @@ test-sys-prop.test262.suite.dir=${test262.suite.dir} test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases test-sys-prop.test.basic.dir=${test.basic.dir} +test-sys-prop-no-security.test.dir=${test.dir} +test-sys-prop-no-security.test.js.roots=${test.nosecurity.dir} + # framework root for our script tests test-sys-prop.test.js.framework=${test.script.dir}/assert.js +test-sys-prop-no-security.test.js.framework=${test.script.dir}/assert.js # Control the verbosity of ParserTest test-sys-prop.parsertest.verbose=false @@ -161,21 +169,14 @@ test-sys-prop.test.js.unchecked.dir=${test262.dir} # test root for octane octane-test-sys-prop.test.js.roots=${test.external.dir}/octane/ -# run octane benchmars in separate processes? +# run octane benchmars in separate processes? (recommended) octane-test-sys-prop.separate.process=true # framework root for octane octane-test-sys-prop.test.js.framework=${test.basic.dir}/run-octane.js -# list of tests to be excluded -# mandreel excluded due to OOM -octane-test-sys-prop.test.js.exclude.list=\ - base.js \ - run.js \ - mandreel.js - # test root for sunspider -sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/tests/sunspider-1.0/ +sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/tests/sunspider-1.0.2/ # framework root for sunspider sunspider-test-sys-prop.test.js.framework=${test.basic.dir}/runsunspider.js @@ -191,6 +192,7 @@ test262-test-sys-prop.test.js.shared.context=true # test262 test root test262-test-sys-prop.test.js.roots=${test262.suite.dir} + # test262 enable/disable strict mode tests test262-test-sys-prop.test.js.enable.strict.mode=true @@ -259,51 +261,116 @@ src.dir=src test.src.dir=test/src # -Xmx is used for all tests, -Xms only for octane benchmark -run.test.xmx=3G +run.test.xmx=2G run.test.xms=2G +# uncomment this jfr.args to enable light recordings. the stack needs to be cranked up to 1024 frames, +# or everything will as of the now drown in lambda forms and be cut off. +# +#jfr.args=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath="test_suite.jfr",stackdepth=1024 \ + +jfr.args= + run.test.user.language=tr run.test.user.country=TR -run.test.jvmargs.common=-server -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError - -#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M -# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods +run.test.jvmargs.common=\ + -server \ + -Dfile.encoding=UTF-8 \ + -Duser.language=${run.test.user.language} \ + -Duser.country=${run.test.user.country} \ + ${jfr.args} \ + -XX:+HeapDumpOnOutOfMemoryError # turn on assertions for tests -run.test.jvmargs.main=${run.test.jvmargs.common} -ea +run.test.jvmargs.main=${run.test.jvmargs.common} -ea -Dnashorn.lazy -#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M -run.test.jvmargs.octane.main=${run.test.jvmargs.common} +# extra jvmargs that might be useful for debugging +# +# -XX:+UnlockDiagnosticVMOptions +# +# turn off compressed class pointers in metaspace +# -XX:-UseCompressedKlassPointers +# +# dump the heap after every GC +# -XX:+PrintHeapAtGC +# +# manually set a metaspace size for class data +# -XX:ClassMetaspaceSize=300M +# +# print out methods compiled +# -XX:+PrintCompilation +# +# print all compiled nmethods with oopmaps and lots of other info +# -XX:+PrintNMethods +# Use best known performance options for octane +run.test.jvmargs.octane.main=${run.test.jvmargs.common} -Dnashorn.lazy -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode -XX:TypeProfileLevel=222 + +# Security manager args - make sure that we run with the nashorn.policy that the build creates run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy # VM options for script tests with @fork option test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -cp ${run.test.classpath} # path of rhino.jar for benchmarks -rhino.jar= +rhino.dir= +rhino.jar=${rhino.dir}/js.jar v8.shell=d8 +# How many iterations should 'ant octane' run for each +# benchmark +octane.iterations=25 + +# List of octane tests to run, as properties prefixed with +# "octane.benchmark." mapping to the benchmark name in +# the test harness +# +# Octane tests that are disabled should have their entire line +# commented out Tests may be disabled for functionality reasons when +# they have bugs or when the runtime doesn't handle them (yet) +octane.benchmark.box2d=box2d +#octane.benchmark.code-load=code-load +octane.benchmark.crypto=crypto +octane.benchmark.deltablue=deltablue +octane.benchmark.earley-boyer=earley-boyer +octane.benchmark.gbemu=gbemu +octane.benchmark.navier-stokes=navier-stokes +octane.benchmark.mandreel=mandreel +octane.benchmark.pdfjs=pdfjs +octane.benchmark.raytrace=raytrace +octane.benchmark.regexp=regexp +octane.benchmark.richards=richards +octane.benchmark.splay=splay +#octane.benchmark.typescript=typescript +#octane.benchmark.zlib=zlib + #path to rhino jar file octaneperf-sys-prop.rhino.jar=${rhino.jar} #timeout for performance tests in minutes octaneperf-sys-prop.timeout.value=10 -################ -# codecoverage # -################ - #enable/disable code coverage; please redifine in the ${user.home}/.nashorn.project.local.properties +#how many iterations to run sunspider after warmup +sunspider.iterations=3000 + +################# +# code coverage # +################# + +#enable/disable code coverage; please redifine in the ${user.home}/.nashorn.project.local.properties make.code.coverage=false - #type of codecoverage; one of static or dynamic. Now only dynamic is supported + +#type of codecoverage; one of static or dynamic. Now only dynamic is supported jcov=dynamic - #naming of CC results - #NB directory specified in the cc.dir will be cleaned up!!! + +#naming of CC results +#NB directory specified in the cc.dir will be cleaned up!!! cc.dir=${basedir}/../Codecoverage_Nashorn cc.result.file.name=CC_${jcov}_nashorn.xml - #dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties + +#dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties jcov2.lib.dir=${basedir}/../jcov2/lib jcov.jar=${jcov2.lib.dir}/jcov.jar cc.include=jdk\.nashorn\.* diff --git a/nashorn/samples/filebrowser.js b/nashorn/samples/filebrowser.js new file mode 100644 index 00000000000..da00553a4ec --- /dev/null +++ b/nashorn/samples/filebrowser.js @@ -0,0 +1,100 @@ +#// Usage: jjs -fx filebrowser.js -- + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Uses -fx and javafx TreeView to visualize directories +if (!$OPTIONS._fx) { + print("Usage: jjs -fx filebrowser.js -- "); + exit(1); +} + +// Java classes used +var File = Java.type("java.io.File"); +var Files = Java.type("java.nio.file.Files"); + +// check directory argument, if passed +var dir = arguments.length > 0? new File(arguments[0]) : new File("."); +if (! dir.isDirectory()) { + print(dir + " is not a directory!"); + exit(2); +} + +// JavaFX classes used +var FXCollections = Java.type("javafx.collections.FXCollections"); +var Scene = Java.type("javafx.scene.Scene"); +var TreeItem = Java.type("javafx.scene.control.TreeItem"); +var TreeView = Java.type("javafx.scene.control.TreeView"); + +// create a subclass of JavaFX TreeItem class +var LazyTreeItem = Java.extend(TreeItem); + +// lazily filling children of a directory LazyTreeItem +function buildChildren(dir) { + var children = FXCollections.observableArrayList(); + var stream = Files.list(dir.toPath()); + stream.forEach(function(path) { + var file = path.toFile(); + var item = file.isDirectory()? + makeLazyTreeItem(file) : new TreeItem(file.name); + children.add(item); + }); + stream.close(); + return children; +} + +// create an instance LazyTreeItem with override methods +function makeLazyTreeItem(dir) { + var item = new LazyTreeItem(dir.name) { + expanded: false, + isLeaf: function() false, + getChildren: function() { + if (! this.expanded) { + // call super class (TreeItem) method + Java.super(item).getChildren().setAll(buildChildren(dir)); + this.expanded = true; + } + // call super class (TreeItem) method + return Java.super(item).getChildren(); + } + } + return item; +} + +// JavaFX start method +function start(stage) { + stage.title = dir.absolutePath; + var rootItem = makeLazyTreeItem(dir); + rootItem.expanded = true; + var tree = new TreeView(rootItem); + stage.scene = new Scene(tree, 300, 450); + stage.show(); +} diff --git a/nashorn/samples/word_histogram.js b/nashorn/samples/word_histogram.js new file mode 100644 index 00000000000..9c739ea0375 --- /dev/null +++ b/nashorn/samples/word_histogram.js @@ -0,0 +1,53 @@ +#nashorn word histogram of a file + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This example demonstrates how to print word histogram + * of a given text file using regex, array and JSON + * functions. + */ + +if (arguments.length < 1) { + print("Usage: jjs -scripting word_histogram.js -- "); + exit(1); +} + +var obj = {}; + +readFully(arguments[0]). + split(/[^\w+]/). + forEach(function(x) + (x in obj? obj[x]++ : obj[x] = 1)); + +print(JSON.stringify(obj)); + diff --git a/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java b/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java index c2ad4eb26c9..45f191a042f 100644 --- a/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java +++ b/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java @@ -103,8 +103,27 @@ import jdk.internal.dynalink.support.Lookup; * handle is always at the start of the chain. */ public class ChainedCallSite extends AbstractRelinkableCallSite { - private static final MethodHandle PRUNE = Lookup.findOwnSpecial(MethodHandles.lookup(), "prune", MethodHandle.class, - MethodHandle.class); + private static final MethodHandle PRUNE_CATCHES = + MethodHandles.insertArguments( + Lookup.findOwnSpecial( + MethodHandles.lookup(), + "prune", + MethodHandle.class, + MethodHandle.class, + boolean.class), + 2, + true); + + private static final MethodHandle PRUNE_SWITCHPOINTS = + MethodHandles.insertArguments( + Lookup.findOwnSpecial( + MethodHandles.lookup(), + "prune", + MethodHandle.class, + MethodHandle.class, + boolean.class), + 2, + false); private final AtomicReference> invocations = new AtomicReference<>(); @@ -112,7 +131,7 @@ public class ChainedCallSite extends AbstractRelinkableCallSite { * Creates a new chained call site. * @param descriptor the descriptor for the call site. */ - public ChainedCallSite(CallSiteDescriptor descriptor) { + public ChainedCallSite(final CallSiteDescriptor descriptor) { super(descriptor); } @@ -126,24 +145,26 @@ public class ChainedCallSite extends AbstractRelinkableCallSite { } @Override - public void relink(GuardedInvocation guardedInvocation, MethodHandle fallback) { - relinkInternal(guardedInvocation, fallback, false); + public void relink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) { + relinkInternal(guardedInvocation, fallback, false, false); } @Override - public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle fallback) { - relinkInternal(guardedInvocation, fallback, true); + public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) { + relinkInternal(guardedInvocation, fallback, true, false); } - private MethodHandle relinkInternal(GuardedInvocation invocation, MethodHandle relink, boolean reset) { + private MethodHandle relinkInternal(final GuardedInvocation invocation, final MethodHandle relink, final boolean reset, final boolean removeCatches) { final LinkedList currentInvocations = invocations.get(); @SuppressWarnings({ "unchecked", "rawtypes" }) final LinkedList newInvocations = currentInvocations == null || reset ? new LinkedList<>() : (LinkedList)currentInvocations.clone(); - // First, prune the chain of invalidated switchpoints. - for(Iterator it = newInvocations.iterator(); it.hasNext();) { - if(it.next().hasBeenInvalidated()) { + // First, prune the chain of invalidated switchpoints, we always do this + // We also remove any catches if the remove catches flag is set + for(final Iterator it = newInvocations.iterator(); it.hasNext();) { + final GuardedInvocation inv = it.next(); + if(inv.hasBeenInvalidated() || (removeCatches && inv.getException() != null)) { it.remove(); } } @@ -160,12 +181,13 @@ public class ChainedCallSite extends AbstractRelinkableCallSite { // prune-and-invoke is used as the fallback for invalidated switchpoints. If a switchpoint gets invalidated, we // rebuild the chain and get rid of all invalidated switchpoints instead of letting them linger. - final MethodHandle pruneAndInvoke = makePruneAndInvokeMethod(relink); + final MethodHandle pruneAndInvokeSwitchPoints = makePruneAndInvokeMethod(relink, getPruneSwitchpoints()); + final MethodHandle pruneAndInvokeCatches = makePruneAndInvokeMethod(relink, getPruneCatches()); // Fold the new chain MethodHandle target = relink; - for(GuardedInvocation inv: newInvocations) { - target = inv.compose(pruneAndInvoke, target); + for(final GuardedInvocation inv: newInvocations) { + target = inv.compose(target, pruneAndInvokeSwitchPoints, pruneAndInvokeCatches); } // If nobody else updated the call site while we were rebuilding the chain, set the target to our chain. In case @@ -177,15 +199,31 @@ public class ChainedCallSite extends AbstractRelinkableCallSite { return target; } + /** + * Get the switchpoint pruning function for a chained call site + * @return function that removes invalidated switchpoints tied to callsite guard chain and relinks + */ + protected MethodHandle getPruneSwitchpoints() { + return PRUNE_SWITCHPOINTS; + } + + /** + * Get the catch pruning function for a chained call site + * @return function that removes all catches tied to callsite guard chain and relinks + */ + protected MethodHandle getPruneCatches() { + return PRUNE_CATCHES; + } + /** * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that * chain. * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink). * @return a method handle for prune-and-invoke */ - private MethodHandle makePruneAndInvokeMethod(MethodHandle relink) { + private MethodHandle makePruneAndInvokeMethod(final MethodHandle relink, final MethodHandle prune) { // Bind prune to (this, relink) - final MethodHandle boundPrune = MethodHandles.insertArguments(PRUNE, 0, this, relink); + final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relink); // Make it ignore all incoming arguments final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList()); // Invoke prune, then invoke the call site target with original arguments @@ -193,7 +231,7 @@ public class ChainedCallSite extends AbstractRelinkableCallSite { } @SuppressWarnings("unused") - private MethodHandle prune(MethodHandle relink) { - return relinkInternal(null, relink, false); + private MethodHandle prune(final MethodHandle relink, final boolean catches) { + return relinkInternal(null, relink, false, catches); } } diff --git a/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java b/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java index b7edb9d8399..d687fd62f2c 100644 --- a/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java +++ b/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java @@ -117,7 +117,7 @@ public class DefaultBootstrapper { * @param type the method signature at the call site * @return a new {@link MonomorphicCallSite} linked with the default dynamic linker. */ - public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) { + public static CallSite bootstrap(final MethodHandles.Lookup caller, final String name, final MethodType type) { return bootstrapInternal(caller, name, type); } @@ -133,11 +133,11 @@ public class DefaultBootstrapper { * @param type the method signature at the call site * @return a new {@link MonomorphicCallSite} linked with the default dynamic linker. */ - public static CallSite publicBootstrap(MethodHandles.Lookup caller, String name, MethodType type) { + public static CallSite publicBootstrap(final MethodHandles.Lookup caller, final String name, final MethodType type) { return bootstrapInternal(MethodHandles.publicLookup(), name, type); } - private static CallSite bootstrapInternal(MethodHandles.Lookup caller, String name, MethodType type) { + private static CallSite bootstrapInternal(final MethodHandles.Lookup caller, final String name, final MethodType type) { return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(caller, name, type))); } } diff --git a/nashorn/src/jdk/internal/dynalink/DynamicLinker.java b/nashorn/src/jdk/internal/dynalink/DynamicLinker.java index 155ff309d01..e7e58d2a8f4 100644 --- a/nashorn/src/jdk/internal/dynalink/DynamicLinker.java +++ b/nashorn/src/jdk/internal/dynalink/DynamicLinker.java @@ -140,7 +140,6 @@ import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl; * @author Attila Szegedi */ public class DynamicLinker { - private static final String CLASS_NAME = DynamicLinker.class.getName(); private static final String RELINK_METHOD_NAME = "relink"; @@ -148,6 +147,7 @@ public class DynamicLinker { private static final String INITIAL_LINK_METHOD_NAME = "linkCallSite"; private final LinkerServices linkerServices; + private final GuardedInvocationFilter prelinkFilter; private final int runtimeContextArgCount; private final boolean syncOnRelink; private final int unstableRelinkThreshold; @@ -156,18 +156,20 @@ public class DynamicLinker { * Creates a new dynamic linker. * * @param linkerServices the linkerServices used by the linker, created by the factory. + * @param prelinkFilter see {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter)} * @param runtimeContextArgCount see {@link DynamicLinkerFactory#setRuntimeContextArgCount(int)} */ - DynamicLinker(LinkerServices linkerServices, int runtimeContextArgCount, boolean syncOnRelink, - int unstableRelinkThreshold) { + DynamicLinker(final LinkerServices linkerServices, final GuardedInvocationFilter prelinkFilter, final int runtimeContextArgCount, + final boolean syncOnRelink, final int unstableRelinkThreshold) { if(runtimeContextArgCount < 0) { throw new IllegalArgumentException("runtimeContextArgCount < 0"); } if(unstableRelinkThreshold < 0) { throw new IllegalArgumentException("unstableRelinkThreshold < 0"); } - this.runtimeContextArgCount = runtimeContextArgCount; this.linkerServices = linkerServices; + this.prelinkFilter = prelinkFilter; + this.runtimeContextArgCount = runtimeContextArgCount; this.syncOnRelink = syncOnRelink; this.unstableRelinkThreshold = unstableRelinkThreshold; } @@ -199,7 +201,7 @@ public class DynamicLinker { private static final MethodHandle RELINK = Lookup.findOwnSpecial(MethodHandles.lookup(), RELINK_METHOD_NAME, MethodHandle.class, RelinkableCallSite.class, int.class, Object[].class); - private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, int relinkCount) { + private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) { // Make a bound MH of invoke() for this linker and call site final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf( relinkCount)); @@ -219,16 +221,15 @@ public class DynamicLinker { * @throws Exception rethrows any exception thrown by the linkers */ @SuppressWarnings("unused") - private MethodHandle relink(RelinkableCallSite callSite, int relinkCount, Object... arguments) throws Exception { + private MethodHandle relink(final RelinkableCallSite callSite, final int relinkCount, final Object... arguments) throws Exception { final CallSiteDescriptor callSiteDescriptor = callSite.getDescriptor(); final boolean unstableDetectionEnabled = unstableRelinkThreshold > 0; final boolean callSiteUnstable = unstableDetectionEnabled && relinkCount >= unstableRelinkThreshold; final LinkRequest linkRequest = - runtimeContextArgCount == 0 ? new LinkRequestImpl(callSiteDescriptor, callSiteUnstable, arguments) - : new RuntimeContextLinkRequestImpl(callSiteDescriptor, callSiteUnstable, arguments, - runtimeContextArgCount); + runtimeContextArgCount == 0 ? + new LinkRequestImpl(callSiteDescriptor, callSite, relinkCount, callSiteUnstable, arguments) : + new RuntimeContextLinkRequestImpl(callSiteDescriptor, callSite, relinkCount, callSiteUnstable, arguments, runtimeContextArgCount); - // Find a suitable method handle with a guard GuardedInvocation guardedInvocation = linkerServices.getGuardedInvocation(linkRequest); // None found - throw an exception @@ -248,6 +249,11 @@ public class DynamicLinker { } } + // Make sure we filter the invocation before linking it into the call site. This is typically used to match the + // return type of the invocation to the call site. + guardedInvocation = prelinkFilter.filter(guardedInvocation, linkRequest, linkerServices); + guardedInvocation.getClass(); // null pointer check + int newRelinkCount = relinkCount; // Note that the short-circuited "&&" evaluation below ensures we'll increment the relinkCount until // threshold + 1 but not beyond that. Threshold + 1 is treated as a special value to signal that resetAndRelink diff --git a/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java b/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java index 72fbebe33be..af5eb119184 100644 --- a/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java +++ b/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java @@ -102,14 +102,15 @@ import jdk.internal.dynalink.support.BottomGuardingDynamicLinker; import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider; import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker; import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker; +import jdk.internal.dynalink.support.DefaultPrelinkFilter; import jdk.internal.dynalink.support.LinkerServicesImpl; import jdk.internal.dynalink.support.TypeConverterFactory; /** * A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition * of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any - * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker}. See - * {@link DynamicLinker} documentation for tips on how to use this class. + * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker} and a + * {@link DefaultPrelinkFilter}. See {@link DynamicLinker} documentation for tips on how to use this class. * * @author Attila Szegedi */ @@ -128,6 +129,7 @@ public class DynamicLinkerFactory { private int runtimeContextArgCount = 0; private boolean syncOnRelink = false; private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD; + private GuardedInvocationFilter prelinkFilter; /** * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread @@ -135,7 +137,7 @@ public class DynamicLinkerFactory { * * @param classLoader the class loader used for the autodiscovery of available linkers. */ - public void setClassLoader(ClassLoader classLoader) { + public void setClassLoader(final ClassLoader classLoader) { this.classLoader = classLoader; classLoaderExplicitlySet = true; } @@ -149,7 +151,7 @@ public class DynamicLinkerFactory { * @param prioritizedLinkers the list of prioritized linkers. Null can be passed to indicate no prioritized linkers * (this is also the default value). */ - public void setPrioritizedLinkers(List prioritizedLinkers) { + public void setPrioritizedLinkers(final List prioritizedLinkers) { this.prioritizedLinkers = prioritizedLinkers == null ? null : new ArrayList<>(prioritizedLinkers); } @@ -162,7 +164,7 @@ public class DynamicLinkerFactory { * * @param prioritizedLinkers a list of prioritized linkers. */ - public void setPrioritizedLinkers(GuardingDynamicLinker... prioritizedLinkers) { + public void setPrioritizedLinkers(final GuardingDynamicLinker... prioritizedLinkers) { setPrioritizedLinkers(Arrays.asList(prioritizedLinkers)); } @@ -173,7 +175,7 @@ public class DynamicLinkerFactory { * @param prioritizedLinker the single prioritized linker. Must not be null. * @throws IllegalArgumentException if null is passed. */ - public void setPrioritizedLinker(GuardingDynamicLinker prioritizedLinker) { + public void setPrioritizedLinker(final GuardingDynamicLinker prioritizedLinker) { if(prioritizedLinker == null) { throw new IllegalArgumentException("prioritizedLinker == null"); } @@ -188,7 +190,7 @@ public class DynamicLinkerFactory { * @param fallbackLinkers the list of fallback linkers. Can be empty to indicate the caller wishes to set no * fallback linkers. */ - public void setFallbackLinkers(List fallbackLinkers) { + public void setFallbackLinkers(final List fallbackLinkers) { this.fallbackLinkers = fallbackLinkers == null ? null : new ArrayList<>(fallbackLinkers); } @@ -200,7 +202,7 @@ public class DynamicLinkerFactory { * @param fallbackLinkers the list of fallback linkers. Can be empty to indicate the caller wishes to set no * fallback linkers. If it is left as null, the standard fallback {@link BeansLinker} will be used. */ - public void setFallbackLinkers(GuardingDynamicLinker... fallbackLinkers) { + public void setFallbackLinkers(final GuardingDynamicLinker... fallbackLinkers) { setFallbackLinkers(Arrays.asList(fallbackLinkers)); } @@ -214,7 +216,7 @@ public class DynamicLinkerFactory { * * @param runtimeContextArgCount the number of language runtime context arguments in call sites. */ - public void setRuntimeContextArgCount(int runtimeContextArgCount) { + public void setRuntimeContextArgCount(final int runtimeContextArgCount) { if(runtimeContextArgCount < 0) { throw new IllegalArgumentException("runtimeContextArgCount < 0"); } @@ -227,7 +229,7 @@ public class DynamicLinkerFactory { * multithreaded execution of dynamically linked code. * @param syncOnRelink true for invoking sync on relink, false otherwise. */ - public void setSyncOnRelink(boolean syncOnRelink) { + public void setSyncOnRelink(final boolean syncOnRelink) { this.syncOnRelink = syncOnRelink; } @@ -238,7 +240,7 @@ public class DynamicLinkerFactory { * call sites will never be considered unstable. * @see LinkRequest#isCallSiteUnstable() */ - public void setUnstableRelinkThreshold(int unstableRelinkThreshold) { + public void setUnstableRelinkThreshold(final int unstableRelinkThreshold) { if(unstableRelinkThreshold < 0) { throw new IllegalArgumentException("unstableRelinkThreshold < 0"); } @@ -246,7 +248,19 @@ public class DynamicLinkerFactory { } /** - * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers. + * Set the pre-link filter. This is a {@link GuardedInvocationFilter} that will get the final chance to modify the + * guarded invocation after it has been created by a component linker and before the dynamic linker links it into + * the call site. It is normally used to adapt the return value type of the invocation to the type of the call site. + * When not set explicitly, {@link DefaultPrelinkFilter} will be used. + * @param prelinkFilter the pre-link filter for the dynamic linker. + */ + public void setPrelinkFilter(final GuardedInvocationFilter prelinkFilter) { + this.prelinkFilter = prelinkFilter; + } + + /** + * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers as well as + * the pre-link filter. * * @return the new dynamic Linker */ @@ -275,7 +289,7 @@ public class DynamicLinkerFactory { // ... prioritized linkers, ... linkers.addAll(prioritizedLinkers); // ... filtered discovered linkers, ... - for(GuardingDynamicLinker linker: discovered) { + for(final GuardingDynamicLinker linker: discovered) { if(!knownLinkerClasses.contains(linker.getClass())) { linkers.add(linker); } @@ -300,14 +314,18 @@ public class DynamicLinkerFactory { } final List typeConverters = new LinkedList<>(); - for(GuardingDynamicLinker linker: linkers) { + for(final GuardingDynamicLinker linker: linkers) { if(linker instanceof GuardingTypeConverterFactory) { typeConverters.add((GuardingTypeConverterFactory)linker); } } + if(prelinkFilter == null) { + prelinkFilter = new DefaultPrelinkFilter(); + } + return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite), - runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold); + prelinkFilter, runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold); } private static ClassLoader getThreadContextClassLoader() { @@ -319,9 +337,9 @@ public class DynamicLinkerFactory { }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT); } - private static void addClasses(Set> knownLinkerClasses, - List linkers) { - for(GuardingDynamicLinker linker: linkers) { + private static void addClasses(final Set> knownLinkerClasses, + final List linkers) { + for(final GuardingDynamicLinker linker: linkers) { knownLinkerClasses.add(linker.getClass()); } } diff --git a/nashorn/src/jdk/internal/dynalink/GuardedInvocationFilter.java b/nashorn/src/jdk/internal/dynalink/GuardedInvocationFilter.java new file mode 100644 index 00000000000..8560d82f68d --- /dev/null +++ b/nashorn/src/jdk/internal/dynalink/GuardedInvocationFilter.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package jdk.internal.dynalink; + +import jdk.internal.dynalink.linker.GuardedInvocation; +import jdk.internal.dynalink.linker.LinkRequest; +import jdk.internal.dynalink.linker.LinkerServices; + +/** + * Interface for objects that are used to transform one guarded invocation into another one. Typical usage is for + * implementing {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter) pre-link filters}. + */ +public interface GuardedInvocationFilter { + /** + * Given a guarded invocation, return a potentially different guarded invocation. + * @param inv the original guarded invocation. Null is never passed. + * @param linkRequest the link request for which the invocation was generated (usually by some linker). + * @param linkerServices the linker services that can be used during creation of a new invocation. + * @return either the passed guarded invocation or a different one, with the difference usually determined based on + * information in the link request and the differing invocation created with the assistance of the linker services. + * Whether or not {@code null} is an accepted return value is dependent on the user of the filter. + */ + public GuardedInvocation filter(GuardedInvocation inv, LinkRequest linkRequest, LinkerServices linkerServices); +} diff --git a/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java b/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java index 7f1bbedebaf..98541f288f2 100644 --- a/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java +++ b/nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java @@ -99,17 +99,17 @@ public class MonomorphicCallSite extends AbstractRelinkableCallSite { * Creates a new call site with monomorphic inline caching strategy. * @param descriptor the descriptor for this call site */ - public MonomorphicCallSite(CallSiteDescriptor descriptor) { + public MonomorphicCallSite(final CallSiteDescriptor descriptor) { super(descriptor); } @Override - public void relink(GuardedInvocation guardedInvocation, MethodHandle relink) { + public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relink) { setTarget(guardedInvocation.compose(relink)); } @Override - public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle relink) { + public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relink) { relink(guardedInvocation, relink); } } diff --git a/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java b/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java index 8a73af922ea..879a4b0ed5e 100644 --- a/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java +++ b/nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java @@ -97,7 +97,7 @@ public class NoSuchDynamicMethodException extends RuntimeException { * Creates a new NoSuchDynamicMethodException * @param message the message of the exception. */ - public NoSuchDynamicMethodException(String message) { + public NoSuchDynamicMethodException(final String message) { super(message); } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java index a6ef8c11b90..9e3fbe8231f 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java @@ -97,7 +97,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType; import jdk.internal.dynalink.linker.GuardedInvocation; @@ -107,6 +106,7 @@ import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.internal.dynalink.support.Guards; import jdk.internal.dynalink.support.Lookup; +import jdk.internal.dynalink.support.TypeUtilities; /** * A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property @@ -123,18 +123,18 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { private final Map propertySetters = new HashMap<>(); private final Map methods = new HashMap<>(); - AbstractJavaLinker(Class clazz, MethodHandle classGuard) { + AbstractJavaLinker(final Class clazz, final MethodHandle classGuard) { this(clazz, classGuard, classGuard); } - AbstractJavaLinker(Class clazz, MethodHandle classGuard, MethodHandle assignableGuard) { + AbstractJavaLinker(final Class clazz, final MethodHandle classGuard, final MethodHandle assignableGuard) { this.clazz = clazz; this.classGuard = classGuard; this.assignableGuard = assignableGuard; final FacetIntrospector introspector = createFacetIntrospector(); // Add methods and properties - for(Method method: introspector.getMethods()) { + for(final Method method: introspector.getMethods()) { final String name = method.getName(); // Add method addMember(name, method, methods); @@ -153,7 +153,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } // Add field getter/setters as property getters/setters. - for(Field field: introspector.getFields()) { + for(final Field field: introspector.getFields()) { final String name = field.getName(); // Only add a property getter when one is not defined already as a getXxx()/isXxx() method. if(!propertyGetters.containsKey(name)) { @@ -166,7 +166,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } // Add inner classes, but only those for which we don't hide a property with it - for(Map.Entry innerClassSpec: introspector.getInnerClassGetters().entrySet()) { + for(final Map.Entry innerClassSpec: introspector.getInnerClassGetters().entrySet()) { final String name = innerClassSpec.getKey(); if(!propertyGetters.containsKey(name)) { setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS); @@ -174,7 +174,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } } - private static String decapitalize(String str) { + private static String decapitalize(final String str) { assert str != null; if(str.isEmpty()) { return str; @@ -209,7 +209,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { return getUnmodifiableKeys(methods); } - private static Collection getUnmodifiableKeys(Map m) { + private static Collection getUnmodifiableKeys(final Map m) { return Collections.unmodifiableCollection(m.keySet()); } @@ -222,7 +222,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param handle the method handle that implements the property getter * @param validationType the validation type for the property */ - private void setPropertyGetter(String name, SingleDynamicMethod handle, ValidationType validationType) { + private void setPropertyGetter(final String name, final SingleDynamicMethod handle, final ValidationType validationType) { propertyGetters.put(name, new AnnotatedDynamicMethod(handle, validationType)); } @@ -232,7 +232,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param prefixLen the getter prefix in the method name; should be 3 for getter names starting with "get" and 2 for * names starting with "is". */ - private void setPropertyGetter(Method getter, int prefixLen) { + private void setPropertyGetter(final Method getter, final int prefixLen) { setPropertyGetter(decapitalize(getter.getName().substring(prefixLen)), createDynamicMethod( getMostGenericGetter(getter)), ValidationType.INSTANCE_OF); } @@ -246,15 +246,15 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param handle the method handle that implements the property getter * @param validationType the validation type for the property */ - void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) { + void setPropertyGetter(final String name, final MethodHandle handle, final ValidationType validationType) { setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType); } - private void addMember(String name, AccessibleObject ao, Map methodMap) { + private void addMember(final String name, final AccessibleObject ao, final Map methodMap) { addMember(name, createDynamicMethod(ao), methodMap); } - private void addMember(String name, SingleDynamicMethod method, Map methodMap) { + private void addMember(final String name, final SingleDynamicMethod method, final Map methodMap) { final DynamicMethod existingMethod = methodMap.get(name); final DynamicMethod newMethod = mergeMethods(method, existingMethod, clazz, name); if(newMethod != existingMethod) { @@ -270,9 +270,9 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param name the common name of the reflective members. * @return a dynamic method representing all the specified reflective members. */ - static DynamicMethod createDynamicMethod(Iterable members, Class clazz, String name) { + static DynamicMethod createDynamicMethod(final Iterable members, final Class clazz, final String name) { DynamicMethod dynMethod = null; - for(AccessibleObject method: members) { + for(final AccessibleObject method: members) { dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name); } return dynMethod; @@ -285,7 +285,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param m the reflective member * @return the single dynamic method representing the reflective member */ - private static SingleDynamicMethod createDynamicMethod(AccessibleObject m) { + private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m) { if(CallerSensitiveDetector.isCallerSensitive(m)) { return new CallerSensitiveDynamicMethod(m); } @@ -301,7 +301,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param m the method or constructor * @return the method handle */ - private static MethodHandle unreflectSafely(AccessibleObject m) { + private static MethodHandle unreflectSafely(final AccessibleObject m) { if(m instanceof Method) { final Method reflMethod = (Method)m; final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod); @@ -313,7 +313,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { return StaticClassIntrospector.editConstructorMethodHandle(Lookup.PUBLIC.unreflectConstructor((Constructor)m)); } - private static DynamicMethod mergeMethods(SingleDynamicMethod method, DynamicMethod existing, Class clazz, String name) { + private static DynamicMethod mergeMethods(final SingleDynamicMethod method, final DynamicMethod existing, final Class clazz, final String name) { if(existing == null) { return method; } else if(existing.contains(method)) { @@ -331,7 +331,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices) + public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { final LinkRequest ncrequest = request.withoutRuntimeContext(); // BeansLinker already checked that the name is at least 2 elements long and the first element is "dyn". @@ -353,8 +353,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { return null; } - protected GuardedInvocationComponent getGuardedInvocationComponent(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, List operations) throws Exception { + protected GuardedInvocationComponent getGuardedInvocationComponent(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final List operations) throws Exception { if(operations.isEmpty()) { return null; } @@ -374,27 +374,27 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { return null; } - static final List pop(List l) { + static final List pop(final List l) { return l.subList(1, l.size()); } - MethodHandle getClassGuard(CallSiteDescriptor desc) { + MethodHandle getClassGuard(final CallSiteDescriptor desc) { return getClassGuard(desc.getMethodType()); } - MethodHandle getClassGuard(MethodType type) { + MethodHandle getClassGuard(final MethodType type) { return Guards.asType(classGuard, type); } - GuardedInvocationComponent getClassGuardedInvocationComponent(MethodHandle invocation, MethodType type) { + GuardedInvocationComponent getClassGuardedInvocationComponent(final MethodHandle invocation, final MethodType type) { return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS); } - private MethodHandle getAssignableGuard(MethodType type) { + private MethodHandle getAssignableGuard(final MethodType type) { return Guards.asType(assignableGuard, type); } - private GuardedInvocation getCallPropWithThis(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) { + private GuardedInvocation getCallPropWithThis(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { switch(callSiteDescriptor.getNameTokenCount()) { case 3: { return createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices, @@ -406,25 +406,25 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } } - private GuardedInvocation createGuardedDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, String methodName, Map methodMap){ + private GuardedInvocation createGuardedDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final String methodName, final Map methodMap){ final MethodHandle inv = getDynamicMethodInvocation(callSiteDescriptor, linkerServices, methodName, methodMap); return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteDescriptor.getMethodType())); } - private static MethodHandle getDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, String methodName, Map methodMap) { + private static MethodHandle getDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final String methodName, final Map methodMap) { final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap); return dynaMethod != null ? dynaMethod.getInvocation(callSiteDescriptor, linkerServices) : null; } - private static DynamicMethod getDynamicMethod(String methodName, Map methodMap) { + private static DynamicMethod getDynamicMethod(final String methodName, final Map methodMap) { final DynamicMethod dynaMethod = methodMap.get(methodName); return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap); } - private static SingleDynamicMethod getExplicitSignatureDynamicMethod(String methodName, - Map methodsMap) { + private static SingleDynamicMethod getExplicitSignatureDynamicMethod(final String methodName, + final Map methodsMap) { // What's below is meant to support the "name(type, type, ...)" syntax that programmers can use in a method name // to manually pin down an exact overloaded variant. This is not usually required, as the overloaded method // resolution works correctly in almost every situation. However, in presence of many language-specific @@ -457,14 +457,18 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { private static final MethodHandle CONSTANT_NULL_DROP_METHOD_HANDLE = MethodHandles.dropArguments( MethodHandles.constant(Object.class, null), 0, MethodHandle.class); - private GuardedInvocationComponent getPropertySetter(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, List operations) throws Exception { - final MethodType type = callSiteDescriptor.getMethodType(); + private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final List operations) throws Exception { switch(callSiteDescriptor.getNameTokenCount()) { case 2: { // Must have three arguments: target object, property name, and property value. assertParameterCount(callSiteDescriptor, 3); + // We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be + // valid for us to convert return values proactively. Also, since we don't know what setters will be + // invoked, we'll conservatively presume Object return type. + final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class); + // What's below is basically: // foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation), // get_setter_handle(type, linkerServices)) @@ -473,8 +477,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // component's invocation. // Call site type is "ret_type(object_type,property_name_type,property_value_type)", which we'll - // abbreviate to R(O, N, V) going forward. - // We want setters that conform to "R(O, V)" + // abbreviate to R(O, N, V) going forward, although we don't really use R here (see above about using + // Object return type). final MethodType setterType = type.dropParameterTypes(1, 2); // Bind property setter handle to the expected setter type and linker services. Type is // MethodHandle(Object, String, Object) @@ -495,11 +499,11 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { final MethodHandle fallbackFolded; if(nextComponent == null) { - // Object(MethodHandle)->R(MethodHandle, O, N, V); returns constant null + // Object(MethodHandle)->Object(MethodHandle, O, N, V); returns constant null fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_METHOD_HANDLE, 1, type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class)); } else { - // R(O, N, V)->R(MethodHandle, O, N, V); adapts the next component's invocation to drop the + // Object(O, N, V)->Object(MethodHandle, O, N, V); adapts the next component's invocation to drop the // extra argument resulting from fold fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(), 0, MethodHandle.class); @@ -543,11 +547,14 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { "getTarget", MethodType.methodType(MethodHandle.class, MethodHandles.Lookup.class)); private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class)); - private GuardedInvocationComponent getPropertyGetter(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, List ops) throws Exception { - final MethodType type = callSiteDescriptor.getMethodType(); + private GuardedInvocationComponent getPropertyGetter(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final List ops) throws Exception { switch(callSiteDescriptor.getNameTokenCount()) { case 2: { + // Since we can't know what kind of a getter we'll get back on different invocations, we'll just + // conservatively presume Object. Note we can't just coerce to a narrower call site type as the linking + // runtime might not allow coercing at that call site. + final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class); // Must have exactly two arguments: receiver and name assertParameterCount(callSiteDescriptor, 2); @@ -563,11 +570,11 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup()); final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0, callSiteBoundMethodGetter); - // Object(AnnotatedDynamicMethod, Object)->R(AnnotatedDynamicMethod, T0) + // Object(AnnotatedDynamicMethod, Object)->Object(AnnotatedDynamicMethod, T0) final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker, MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0))); // Since it's in the target of a fold, drop the unnecessary second argument - // R(AnnotatedDynamicMethod, T0)->R(AnnotatedDynamicMethod, T0, T1) + // Object(AnnotatedDynamicMethod, T0)->Object(AnnotatedDynamicMethod, T0, T1) final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2, type.parameterType(1)); final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor, @@ -575,17 +582,19 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { final MethodHandle fallbackFolded; if(nextComponent == null) { - // Object(AnnotatedDynamicMethod)->R(AnnotatedDynamicMethod, T0, T1); returns constant null + // Object(AnnotatedDynamicMethod)->Object(AnnotatedDynamicMethod, T0, T1); returns constant null fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1, type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class)); } else { - // R(T0, T1)->R(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to drop the - // extra argument resulting from fold - fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(), - 0, AnnotatedDynamicMethod.class); + // Object(T0, T1)->Object(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to + // drop the extra argument resulting from fold and to change its return type to Object. + final MethodHandle nextInvocation = nextComponent.getGuardedInvocation().getInvocation(); + final MethodType nextType = nextInvocation.type(); + fallbackFolded = MethodHandles.dropArguments(nextInvocation.asType( + nextType.changeReturnType(Object.class)), 0, AnnotatedDynamicMethod.class); } - // fold(R(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1)) + // fold(Object(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1)) final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest( IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter); if(nextComponent == null) { @@ -612,8 +621,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // value is null. final ValidationType validationType = annGetter.validationType; // TODO: we aren't using the type that declares the most generic getter here! - return new GuardedInvocationComponent(linkerServices.asType(getter, type), getGuard(validationType, - type), clazz, validationType); + return new GuardedInvocationComponent(getter, getGuard(validationType, + callSiteDescriptor.getMethodType()), clazz, validationType); } default: { // Can't do anything with more than 3 name components @@ -622,7 +631,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } } - private MethodHandle getGuard(ValidationType validationType, MethodType methodType) { + private MethodHandle getGuard(final ValidationType validationType, final MethodType methodType) { switch(validationType) { case EXACT_CLASS: { return getClassGuard(methodType); @@ -642,21 +651,25 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } } - private static final MethodHandle IS_DYNAMIC_METHOD_NOT_NULL = Guards.asType(Guards.isNotNull(), - MethodType.methodType(boolean.class, DynamicMethod.class)); - private static final MethodHandle DYNAMIC_METHOD_IDENTITY = MethodHandles.identity(DynamicMethod.class); + private static final MethodHandle IS_DYNAMIC_METHOD = Guards.isInstance(DynamicMethod.class, + MethodType.methodType(boolean.class, Object.class)); + private static final MethodHandle OBJECT_IDENTITY = MethodHandles.identity(Object.class); - private GuardedInvocationComponent getMethodGetter(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, List ops) throws Exception { - final MethodType type = callSiteDescriptor.getMethodType(); + private GuardedInvocationComponent getMethodGetter(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final List ops) throws Exception { + // The created method handle will always return a DynamicMethod (or null), but since we don't want that type to + // be visible outside of this linker, declare it to return Object. + final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class); switch(callSiteDescriptor.getNameTokenCount()) { case 2: { // Must have exactly two arguments: receiver and name assertParameterCount(callSiteDescriptor, 2); final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops); - if(nextComponent == null) { - // No next component operation; just return a component for this operation. + if(nextComponent == null || !TypeUtilities.areAssignable(DynamicMethod.class, + nextComponent.getGuardedInvocation().getInvocation().type().returnType())) { + // No next component operation, or it can never produce a dynamic method; just return a component + // for this operation. return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type); } @@ -665,21 +678,20 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // bunch of method signature adjustments. Basically, execute method getter; if it returns a non-null // DynamicMethod, use identity to return it, otherwise delegate to nextComponent's invocation. - final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType( - DynamicMethod.class)); + final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type); // Since it is part of the foldArgument() target, it will have extra args that we need to drop. final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments( - DYNAMIC_METHOD_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0, - DynamicMethod.class)); + OBJECT_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0, Object.class)); final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation(); - // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly - assert nextComponentInvocation.type().equals(type); + // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly modulo the + // return type. + assert nextComponentInvocation.type().changeReturnType(type.returnType()).equals(type); // Since it is part of the foldArgument() target, we have to drop an extra arg it receives. final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0, - DynamicMethod.class); + Object.class); // Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get) final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest( - IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter); + IS_DYNAMIC_METHOD, returnMethodHandle, nextCombinedInvocation), typedGetter); return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS); } @@ -695,7 +707,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // No delegation to the next component of the composite operation; if we have a method with that name, // we'll always return it at this point. return getClassGuardedInvocationComponent(linkerServices.asType(MethodHandles.dropArguments( - MethodHandles.constant(DynamicMethod.class, method), 0, type.parameterType(0)), type), type); + MethodHandles.constant(Object.class, method), 0, type.parameterType(0)), type), type); } default: { // Can't do anything with more than 3 name components @@ -704,7 +716,31 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } } - private static void assertParameterCount(CallSiteDescriptor descriptor, int paramCount) { + static class MethodPair { + final MethodHandle method1; + final MethodHandle method2; + + MethodPair(final MethodHandle method1, final MethodHandle method2) { + this.method1 = method1; + this.method2 = method2; + } + + MethodHandle guardWithTest(final MethodHandle test) { + return MethodHandles.guardWithTest(test, method1, method2); + } + } + + static MethodPair matchReturnTypes(final MethodHandle m1, final MethodHandle m2) { + final MethodType type1 = m1.type(); + final MethodType type2 = m2.type(); + final Class commonRetType = TypeUtilities.getCommonLosslessConversionType(type1.returnType(), + type2.returnType()); + return new MethodPair( + m1.asType(type1.changeReturnType(commonRetType)), + m2.asType(type2.changeReturnType(commonRetType))); + } + + private static void assertParameterCount(final CallSiteDescriptor descriptor, final int paramCount) { if(descriptor.getMethodType().parameterCount() != paramCount) { throw new BootstrapMethodError(descriptor.getName() + " must have exactly " + paramCount + " parameters."); } @@ -719,7 +755,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @return the method handle for retrieving the property, or null if the property does not exist */ @SuppressWarnings("unused") - private Object getPropertyGetterHandle(Object id) { + private Object getPropertyGetterHandle(final Object id) { return propertyGetters.get(id); } @@ -733,17 +769,20 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this); @SuppressWarnings("unused") - private MethodHandle getPropertySetterHandle(CallSiteDescriptor setterDescriptor, LinkerServices linkerServices, - Object id) { + private MethodHandle getPropertySetterHandle(final CallSiteDescriptor setterDescriptor, final LinkerServices linkerServices, + final Object id) { return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters); } private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial( - "getDynamicMethod", DynamicMethod.class, Object.class), 1, Object.class); + "getDynamicMethod", Object.class, Object.class), 1, Object.class); private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this); @SuppressWarnings("unused") - private DynamicMethod getDynamicMethod(Object name) { + // This method is marked to return Object instead of DynamicMethod as it's used as a linking component and we don't + // want to make the DynamicMethod type observable externally (e.g. as the return type of a MethodHandle returned for + // "dyn:getMethod" linking). + private Object getDynamicMethod(final Object name) { return getDynamicMethod(String.valueOf(name), methods); } @@ -754,7 +793,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the * method with the specified name does not exist. */ - DynamicMethod getDynamicMethod(String name) { + DynamicMethod getDynamicMethod(final String name) { return getDynamicMethod(name, methods); } @@ -765,16 +804,16 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { * @param getter the getter * @return getter with same name, declared on the most generic superclass/interface of the declaring class */ - private static Method getMostGenericGetter(Method getter) { + private static Method getMostGenericGetter(final Method getter) { return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass()); } - private static Method getMostGenericGetter(String name, Class returnType, Class declaringClass) { + private static Method getMostGenericGetter(final String name, final Class returnType, final Class declaringClass) { if(declaringClass == null) { return null; } // Prefer interfaces - for(Class itf: declaringClass.getInterfaces()) { + for(final Class itf: declaringClass.getInterfaces()) { final Method itfGetter = getMostGenericGetter(name, returnType, itf); if(itfGetter != null) { return itfGetter; @@ -787,7 +826,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { if(!CheckRestrictedPackage.isRestrictedClass(declaringClass)) { try { return declaringClass.getMethod(name); - } catch(NoSuchMethodException e) { + } catch(final NoSuchMethodException e) { // Intentionally ignored, meant to fall through } } @@ -798,18 +837,18 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { private final SingleDynamicMethod method; /*private*/ final ValidationType validationType; - AnnotatedDynamicMethod(SingleDynamicMethod method, ValidationType validationType) { + AnnotatedDynamicMethod(final SingleDynamicMethod method, final ValidationType validationType) { this.method = method; this.validationType = validationType; } - MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) { + MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { return method.getInvocation(callSiteDescriptor, linkerServices); } @SuppressWarnings("unused") - MethodHandle getTarget(MethodHandles.Lookup lookup) { - MethodHandle inv = method.getTarget(lookup); + MethodHandle getTarget(final MethodHandles.Lookup lookup) { + final MethodHandle inv = method.getTarget(lookup); assert inv != null; return inv; } diff --git a/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java index 72beadfe3b6..21789e45afe 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java +++ b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java @@ -104,7 +104,7 @@ import java.util.Set; class AccessibleMembersLookup { private final Map methods; private final Set> innerClasses; - private boolean instance; + private final boolean instance; /** * Creates a mapping for all accessible methods and inner classes on a class. @@ -112,7 +112,7 @@ class AccessibleMembersLookup { * @param clazz the inspected class * @param instance true to inspect instance methods, false to inspect static methods. */ - AccessibleMembersLookup(final Class clazz, boolean instance) { + AccessibleMembersLookup(final Class clazz, final boolean instance) { this.methods = new HashMap<>(); this.innerClasses = new LinkedHashSet<>(); this.instance = instance; @@ -153,7 +153,7 @@ class AccessibleMembersLookup { * @param name the name of the method this signature represents. * @param args the argument types of the method. */ - MethodSignature(String name, Class[] args) { + MethodSignature(final String name, final Class[] args) { this.name = name; this.args = args; } @@ -210,7 +210,7 @@ class AccessibleMembersLookup { if(!CheckRestrictedPackage.isRestrictedClass(clazz)) { searchSuperTypes = false; - for(Method method: clazz.getMethods()) { + for(final Method method: clazz.getMethods()) { final boolean isStatic = Modifier.isStatic(method.getModifiers()); if(instance != isStatic) { final MethodSignature sig = new MethodSignature(method); @@ -237,7 +237,7 @@ class AccessibleMembersLookup { } } } - for(Class innerClass: clazz.getClasses()) { + for(final Class innerClass: clazz.getClasses()) { // Add both static and non-static classes, regardless of instance flag. StaticClassLinker will just // expose non-static classes with explicit constructor outer class argument. // NOTE: getting inner class objects through getClasses() does not resolve them, so if those classes diff --git a/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java b/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java index 39a03a8ef96..e749c490dd4 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java +++ b/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java @@ -108,7 +108,7 @@ class ApplicableOverloadedMethods { ApplicableOverloadedMethods(final List methods, final MethodType callSiteType, final ApplicabilityTest test) { this.methods = new LinkedList<>(); - for(SingleDynamicMethod m: methods) { + for(final SingleDynamicMethod m: methods) { if(test.isApplicable(callSiteType, m)) { this.methods.add(m); } @@ -143,7 +143,7 @@ class ApplicableOverloadedMethods { */ static final ApplicabilityTest APPLICABLE_BY_SUBTYPING = new ApplicabilityTest() { @Override - boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) { + boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) { final MethodType methodType = method.getMethodType(); final int methodArity = methodType.parameterCount(); if(methodArity != callSiteType.parameterCount()) { @@ -165,7 +165,7 @@ class ApplicableOverloadedMethods { */ static final ApplicabilityTest APPLICABLE_BY_METHOD_INVOCATION_CONVERSION = new ApplicabilityTest() { @Override - boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) { + boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) { final MethodType methodType = method.getMethodType(); final int methodArity = methodType.parameterCount(); if(methodArity != callSiteType.parameterCount()) { @@ -188,7 +188,7 @@ class ApplicableOverloadedMethods { */ static final ApplicabilityTest APPLICABLE_BY_VARIABLE_ARITY = new ApplicabilityTest() { @Override - boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) { + boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) { if(!method.isVarArgs()) { return false; } diff --git a/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java index fc54e353a6e..754d88efb7b 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java @@ -88,7 +88,7 @@ import java.util.Collections; import java.util.Map; class BeanIntrospector extends FacetIntrospector { - BeanIntrospector(Class clazz) { + BeanIntrospector(final Class clazz) { super(clazz, true); } @@ -98,7 +98,7 @@ class BeanIntrospector extends FacetIntrospector { } @Override - MethodHandle editMethodHandle(MethodHandle mh) { + MethodHandle editMethodHandle(final MethodHandle mh) { return mh; } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java b/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java index d0ad96bad21..f7f0c94a847 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java @@ -106,7 +106,7 @@ import jdk.internal.dynalink.support.TypeUtilities; * @author Attila Szegedi */ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicLinker { - BeanLinker(Class clazz) { + BeanLinker(final Class clazz) { super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz)); if(clazz.isArray()) { // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an @@ -119,7 +119,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL } @Override - public boolean canLinkType(Class type) { + public boolean canLinkType(final Class type) { return type == clazz; } @@ -129,8 +129,8 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL } @Override - protected GuardedInvocationComponent getGuardedInvocationComponent(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, List operations) throws Exception { + protected GuardedInvocationComponent getGuardedInvocationComponent(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final List operations) throws Exception { final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations); if(superGic != null) { @@ -166,7 +166,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL private static MethodHandle MAP_GUARD = Guards.getInstanceOfGuard(Map.class); private GuardedInvocationComponent getElementGetter(final CallSiteDescriptor callSiteDescriptor, - final LinkerServices linkerServices, List operations) throws Exception { + final LinkerServices linkerServices, final List operations) throws Exception { final MethodType callSiteType = callSiteDescriptor.getMethodType(); final Class declaredType = callSiteType.parameterType(0); final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor, @@ -237,8 +237,9 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL } else { checkGuard = convertArgToInt(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor); } - return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard), - binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(), + final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation), + nextComponent.getGuardedInvocation().getInvocation()); + return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(), gic.getValidatorClass(), gic.getValidationType()); } @@ -247,7 +248,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL CallSiteDescriptor.NAME_OPERAND); } - private static Object convertKeyToInteger(String fixedKey, LinkerServices linkerServices) throws Exception { + private static Object convertKeyToInteger(final String fixedKey, final LinkerServices linkerServices) throws Exception { try { if(linkerServices.canConvert(String.class, Number.class)) { try { @@ -267,18 +268,18 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL return Integer.valueOf(intIndex); } catch(Exception|Error e) { throw e; - } catch(Throwable t) { + } catch(final Throwable t) { throw new RuntimeException(t); } } return Integer.valueOf(fixedKey); - } catch(NumberFormatException e) { + } catch(final NumberFormatException e) { // key is not a number return null; } } - private static MethodHandle convertArgToInt(MethodHandle mh, LinkerServices ls, CallSiteDescriptor desc) { + private static MethodHandle convertArgToInt(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) { final Class sourceType = desc.getMethodType().parameterType(1); if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) { return mh; @@ -301,21 +302,21 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL private final MethodType methodType; private final Object fixedKey; - Binder(LinkerServices linkerServices, MethodType methodType, Object fixedKey) { + Binder(final LinkerServices linkerServices, final MethodType methodType, final Object fixedKey) { this.linkerServices = linkerServices; this.methodType = fixedKey == null ? methodType : methodType.insertParameterTypes(1, fixedKey.getClass()); this.fixedKey = fixedKey; } - /*private*/ MethodHandle bind(MethodHandle handle) { - return bindToFixedKey(linkerServices.asType(handle, methodType)); + /*private*/ MethodHandle bind(final MethodHandle handle) { + return bindToFixedKey(linkerServices.asTypeLosslessReturn(handle, methodType)); } - /*private*/ MethodHandle bindTest(MethodHandle handle) { + /*private*/ MethodHandle bindTest(final MethodHandle handle) { return bindToFixedKey(Guards.asType(handle, methodType)); } - private MethodHandle bindToFixedKey(MethodHandle handle) { + private MethodHandle bindToFixedKey(final MethodHandle handle) { return fixedKey == null ? handle : MethodHandles.insertArguments(handle, 1, fixedKey); } } @@ -325,12 +326,12 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL private static MethodHandle CONTAINS_MAP = Lookup.PUBLIC.findVirtual(Map.class, "containsKey", MethodType.methodType(boolean.class, Object.class)); - private static MethodHandle findRangeCheck(Class collectionType) { + private static MethodHandle findRangeCheck(final Class collectionType) { return Lookup.findOwnStatic(MethodHandles.lookup(), "rangeCheck", boolean.class, collectionType, Object.class); } @SuppressWarnings("unused") - private static final boolean rangeCheck(Object array, Object index) { + private static final boolean rangeCheck(final Object array, final Object index) { if(!(index instanceof Number)) { return false; } @@ -347,7 +348,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL } @SuppressWarnings("unused") - private static final boolean rangeCheck(List list, Object index) { + private static final boolean rangeCheck(final List list, final Object index) { if(!(index instanceof Number)) { return false; } @@ -369,8 +370,8 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL private static MethodHandle PUT_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "put", MethodType.methodType(Object.class, Object.class, Object.class)); - private GuardedInvocationComponent getElementSetter(CallSiteDescriptor callSiteDescriptor, - LinkerServices linkerServices, List operations) throws Exception { + private GuardedInvocationComponent getElementSetter(final CallSiteDescriptor callSiteDescriptor, + final LinkerServices linkerServices, final List operations) throws Exception { final MethodType callSiteType = callSiteDescriptor.getMethodType(); final Class declaredType = callSiteType.parameterType(0); @@ -440,8 +441,9 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL final MethodHandle checkGuard = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST : RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor); - return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard), - binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(), + final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation), + nextComponent.getGuardedInvocation().getInvocation()); + return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(), gic.getValidatorClass(), gic.getValidationType()); } @@ -456,7 +458,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL private static MethodHandle COLLECTION_GUARD = Guards.getInstanceOfGuard(Collection.class); - private GuardedInvocationComponent getLengthGetter(CallSiteDescriptor callSiteDescriptor) { + private GuardedInvocationComponent getLengthGetter(final CallSiteDescriptor callSiteDescriptor) { assertParameterCount(callSiteDescriptor, 1); final MethodType callSiteType = callSiteDescriptor.getMethodType(); final Class declaredType = callSiteType.parameterType(0); @@ -486,7 +488,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL return null; } - private static void assertParameterCount(CallSiteDescriptor descriptor, int paramCount) { + private static void assertParameterCount(final CallSiteDescriptor descriptor, final int paramCount) { if(descriptor.getMethodType().parameterCount() != paramCount) { throw new BootstrapMethodError(descriptor.getName() + " must have exactly " + paramCount + " parameters."); } diff --git a/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java b/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java index e0c14b0d1d8..b1862de0f0c 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java @@ -131,7 +131,7 @@ import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; public class BeansLinker implements GuardingDynamicLinker { private static final ClassValue linkers = new ClassValue() { @Override - protected TypeBasedGuardingDynamicLinker computeValue(Class clazz) { + protected TypeBasedGuardingDynamicLinker computeValue(final Class clazz) { // If ClassValue.put() were public, we could just pre-populate with these known mappings... return clazz == Class.class ? new ClassLinker() : @@ -154,7 +154,7 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a bean linker for that class */ - public static TypeBasedGuardingDynamicLinker getLinkerForClass(Class clazz) { + public static TypeBasedGuardingDynamicLinker getLinkerForClass(final Class clazz) { return linkers.get(clazz); } @@ -173,8 +173,8 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a collection of names of all readable instance properties of a class. */ - public static Collection getReadableInstancePropertyNames(Class clazz) { - TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz); + public static Collection getReadableInstancePropertyNames(final Class clazz) { + final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz); if(linker instanceof BeanLinker) { return ((BeanLinker)linker).getReadablePropertyNames(); } @@ -186,8 +186,8 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a collection of names of all writable instance properties of a class. */ - public static Collection getWritableInstancePropertyNames(Class clazz) { - TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz); + public static Collection getWritableInstancePropertyNames(final Class clazz) { + final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz); if(linker instanceof BeanLinker) { return ((BeanLinker)linker).getWritablePropertyNames(); } @@ -199,8 +199,8 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a collection of names of all instance methods of a class. */ - public static Collection getInstanceMethodNames(Class clazz) { - TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz); + public static Collection getInstanceMethodNames(final Class clazz) { + final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz); if(linker instanceof BeanLinker) { return ((BeanLinker)linker).getMethodNames(); } @@ -212,7 +212,7 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a collection of names of all readable static properties of a class. */ - public static Collection getReadableStaticPropertyNames(Class clazz) { + public static Collection getReadableStaticPropertyNames(final Class clazz) { return StaticClassLinker.getReadableStaticPropertyNames(clazz); } @@ -221,7 +221,7 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a collection of names of all writable static properties of a class. */ - public static Collection getWritableStaticPropertyNames(Class clazz) { + public static Collection getWritableStaticPropertyNames(final Class clazz) { return StaticClassLinker.getWritableStaticPropertyNames(clazz); } @@ -230,12 +230,12 @@ public class BeansLinker implements GuardingDynamicLinker { * @param clazz the class * @return a collection of names of all static methods of a class. */ - public static Collection getStaticMethodNames(Class clazz) { + public static Collection getStaticMethodNames(final Class clazz) { return StaticClassLinker.getStaticMethodNames(clazz); } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices) + public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor(); final int l = callSiteDescriptor.getNameTokenCount(); diff --git a/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java index 466bafe65dc..e4ada355e53 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java @@ -107,14 +107,14 @@ public class CallerSensitiveDetector { private static final DetectionStrategy DETECTION_STRATEGY = getDetectionStrategy(); - static boolean isCallerSensitive(AccessibleObject ao) { + static boolean isCallerSensitive(final AccessibleObject ao) { return DETECTION_STRATEGY.isCallerSensitive(ao); } private static DetectionStrategy getDetectionStrategy() { try { return new PrivilegedDetectionStrategy(); - } catch(Throwable t) { + } catch(final Throwable t) { return new UnprivilegedDetectionStrategy(); } } @@ -127,7 +127,7 @@ public class CallerSensitiveDetector { private static final Class CALLER_SENSITIVE_ANNOTATION_CLASS = CallerSensitive.class; @Override - boolean isCallerSensitive(AccessibleObject ao) { + boolean isCallerSensitive(final AccessibleObject ao) { return ao.getAnnotation(CALLER_SENSITIVE_ANNOTATION_CLASS) != null; } } @@ -136,8 +136,8 @@ public class CallerSensitiveDetector { private static final String CALLER_SENSITIVE_ANNOTATION_STRING = "@sun.reflect.CallerSensitive()"; @Override - boolean isCallerSensitive(AccessibleObject o) { - for(Annotation a: o.getAnnotations()) { + boolean isCallerSensitive(final AccessibleObject o) { + for(final Annotation a: o.getAnnotations()) { if(String.valueOf(a).equals(CALLER_SENSITIVE_ANNOTATION_STRING)) { return true; } diff --git a/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java index 1e274d516e9..5fceb1a7af0 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java @@ -107,13 +107,13 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod { private final AccessibleObject target; private final MethodType type; - public CallerSensitiveDynamicMethod(AccessibleObject target) { + public CallerSensitiveDynamicMethod(final AccessibleObject target) { super(getName(target)); this.target = target; this.type = getMethodType(target); } - private static String getName(AccessibleObject target) { + private static String getName(final AccessibleObject target) { final Member m = (Member)target; return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(), m.getName())); @@ -124,7 +124,7 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod { return type; } - private static MethodType getMethodType(AccessibleObject ao) { + private static MethodType getMethodType(final AccessibleObject ao) { final boolean isMethod = ao instanceof Method; final Class rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor)ao).getDeclaringClass(); final Class[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor)ao).getParameterTypes(); @@ -144,7 +144,7 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod { } @Override - MethodHandle getTarget(MethodHandles.Lookup lookup) { + MethodHandle getTarget(final MethodHandles.Lookup lookup) { if(target instanceof Method) { final MethodHandle mh = Lookup.unreflect(lookup, (Method)target); if(Modifier.isStatic(((Member)target).getModifiers())) { diff --git a/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java b/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java index 360759f8674..49723a12d38 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java +++ b/nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java @@ -101,7 +101,7 @@ class CheckRestrictedPackage { * @param clazz the class to test * @return true if the class is either not public, or it resides in a package with restricted access. */ - static boolean isRestrictedClass(Class clazz) { + static boolean isRestrictedClass(final Class clazz) { if(!Modifier.isPublic(clazz.getModifiers())) { // Non-public classes are always restricted return true; @@ -126,7 +126,7 @@ class CheckRestrictedPackage { return null; } }, NO_PERMISSIONS_CONTEXT); - } catch(SecurityException e) { + } catch(final SecurityException e) { return true; } return false; diff --git a/nashorn/src/jdk/internal/dynalink/beans/ClassString.java b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java index 2afbdb4f76b..00729cd7ae0 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/ClassString.java +++ b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java @@ -104,16 +104,16 @@ final class ClassString { private final Class[] classes; private int hashCode; - ClassString(Class[] classes) { + ClassString(final Class[] classes) { this.classes = classes; } - ClassString(MethodType type) { + ClassString(final MethodType type) { this(type.parameterArray()); } @Override - public boolean equals(Object other) { + public boolean equals(final Object other) { if(!(other instanceof ClassString)) { return false; } @@ -150,7 +150,7 @@ final class ClassString { return true; } - List getMaximallySpecifics(List methods, LinkerServices linkerServices, boolean varArg) { + List getMaximallySpecifics(final List methods, final LinkerServices linkerServices, final boolean varArg) { return MaximallySpecific.getMaximallySpecificMethodHandles(getApplicables(methods, linkerServices, varArg), varArg, classes, linkerServices); } @@ -158,7 +158,7 @@ final class ClassString { /** * Returns all methods that are applicable to actual parameter classes represented by this ClassString object. */ - LinkedList getApplicables(List methods, LinkerServices linkerServices, boolean varArg) { + LinkedList getApplicables(final List methods, final LinkerServices linkerServices, final boolean varArg) { final LinkedList list = new LinkedList<>(); for(final MethodHandle member: methods) { if(isApplicable(member, linkerServices, varArg)) { @@ -173,7 +173,7 @@ final class ClassString { * object. * */ - private boolean isApplicable(MethodHandle method, LinkerServices linkerServices, boolean varArg) { + private boolean isApplicable(final MethodHandle method, final LinkerServices linkerServices, final boolean varArg) { final Class[] formalTypes = method.type().parameterArray(); final int cl = classes.length; final int fl = formalTypes.length - (varArg ? 1 : 0); @@ -203,7 +203,7 @@ final class ClassString { return true; } - private static boolean canConvert(LinkerServices ls, Class from, Class to) { + private static boolean canConvert(final LinkerServices ls, final Class from, final Class to) { if(from == NULL_CLASS) { return !to.isPrimitive(); } diff --git a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java index 6beb92b12f7..e72ca6dce54 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java @@ -99,7 +99,7 @@ import jdk.internal.dynalink.linker.LinkerServices; abstract class DynamicMethod { private final String name; - DynamicMethod(String name) { + DynamicMethod(final String name) { this.name = name; } @@ -138,7 +138,7 @@ abstract class DynamicMethod { */ abstract boolean contains(SingleDynamicMethod method); - static String getClassAndMethodName(Class clazz, String name) { + static String getClassAndMethodName(final Class clazz, final String name) { final String clazzName = clazz.getCanonicalName(); return (clazzName == null ? clazz.getName() : clazzName) + "." + name; } diff --git a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java index 32942b9a423..08f2a2581c1 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java @@ -99,12 +99,12 @@ import jdk.internal.dynalink.support.Guards; */ class DynamicMethodLinker implements TypeBasedGuardingDynamicLinker { @Override - public boolean canLinkType(Class type) { + public boolean canLinkType(final Class type) { return DynamicMethod.class.isAssignableFrom(type); } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) { + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) { final Object receiver = linkRequest.getReceiver(); if(!(receiver instanceof DynamicMethod)) { return null; diff --git a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java index 4ac5deaa9da..29c98d042ff 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java @@ -106,7 +106,7 @@ abstract class FacetIntrospector { protected final AccessibleMembersLookup membersLookup; - FacetIntrospector(Class clazz, boolean instance) { + FacetIntrospector(final Class clazz, final boolean instance) { this.clazz = clazz; this.instance = instance; isRestricted = CheckRestrictedPackage.isRestrictedClass(clazz); @@ -135,7 +135,7 @@ abstract class FacetIntrospector { final Field[] fields = clazz.getFields(); final Collection cfields = new ArrayList<>(fields.length); - for(Field field: fields) { + for(final Field field: fields) { final boolean isStatic = Modifier.isStatic(field.getModifiers()); if(isStatic && clazz != field.getDeclaringClass()) { // ignore inherited static fields @@ -149,7 +149,7 @@ abstract class FacetIntrospector { return cfields; } - boolean isAccessible(Member m) { + boolean isAccessible(final Member m) { final Class declaring = m.getDeclaringClass(); // (declaring == clazz) is just an optimization - we're calling this only from code that operates on a // non-restriced class, so if the declaring class is identical to the class being inspected, then forego @@ -166,11 +166,11 @@ abstract class FacetIntrospector { } - MethodHandle unreflectGetter(Field field) { + MethodHandle unreflectGetter(final Field field) { return editMethodHandle(Lookup.PUBLIC.unreflectGetter(field)); } - MethodHandle unreflectSetter(Field field) { + MethodHandle unreflectSetter(final Field field) { return editMethodHandle(Lookup.PUBLIC.unreflectSetter(field)); } diff --git a/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java b/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java index f2c76dba828..9bacd218c16 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java +++ b/nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java @@ -105,38 +105,38 @@ class GuardedInvocationComponent { private final GuardedInvocation guardedInvocation; private final Validator validator; - GuardedInvocationComponent(MethodHandle invocation) { + GuardedInvocationComponent(final MethodHandle invocation) { this(invocation, null, ValidationType.NONE); } - GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, ValidationType validationType) { + GuardedInvocationComponent(final MethodHandle invocation, final MethodHandle guard, final ValidationType validationType) { this(invocation, guard, null, validationType); } - GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, Class validatorClass, - ValidationType validationType) { + GuardedInvocationComponent(final MethodHandle invocation, final MethodHandle guard, final Class validatorClass, + final ValidationType validationType) { this(invocation, guard, new Validator(validatorClass, validationType)); } - GuardedInvocationComponent(GuardedInvocation guardedInvocation, Class validatorClass, - ValidationType validationType) { + GuardedInvocationComponent(final GuardedInvocation guardedInvocation, final Class validatorClass, + final ValidationType validationType) { this(guardedInvocation, new Validator(validatorClass, validationType)); } - GuardedInvocationComponent replaceInvocation(MethodHandle newInvocation) { + GuardedInvocationComponent replaceInvocation(final MethodHandle newInvocation) { return replaceInvocation(newInvocation, guardedInvocation.getGuard()); } - GuardedInvocationComponent replaceInvocation(MethodHandle newInvocation, MethodHandle newGuard) { + GuardedInvocationComponent replaceInvocation(final MethodHandle newInvocation, final MethodHandle newGuard) { return new GuardedInvocationComponent(guardedInvocation.replaceMethods(newInvocation, newGuard), validator); } - private GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, Validator validator) { + private GuardedInvocationComponent(final MethodHandle invocation, final MethodHandle guard, final Validator validator) { this(new GuardedInvocation(invocation, guard), validator); } - private GuardedInvocationComponent(GuardedInvocation guardedInvocation, Validator validator) { + private GuardedInvocationComponent(final GuardedInvocation guardedInvocation, final Validator validator) { this.guardedInvocation = guardedInvocation; this.validator = validator; } @@ -153,8 +153,8 @@ class GuardedInvocationComponent { return validator.validationType; } - GuardedInvocationComponent compose(MethodHandle compositeInvocation, MethodHandle otherGuard, - Class otherValidatorClass, ValidationType otherValidationType) { + GuardedInvocationComponent compose(final MethodHandle compositeInvocation, final MethodHandle otherGuard, + final Class otherValidatorClass, final ValidationType otherValidationType) { final Validator compositeValidator = validator.compose(new Validator(otherValidatorClass, otherValidationType)); final MethodHandle compositeGuard = compositeValidator == validator ? guardedInvocation.getGuard() : otherGuard; return new GuardedInvocationComponent(compositeInvocation, compositeGuard, compositeValidator); @@ -164,12 +164,12 @@ class GuardedInvocationComponent { /*private*/ final Class validatorClass; /*private*/ final ValidationType validationType; - Validator(Class validatorClass, ValidationType validationType) { + Validator(final Class validatorClass, final ValidationType validationType) { this.validatorClass = validatorClass; this.validationType = validationType; } - Validator compose(Validator other) { + Validator compose(final Validator other) { if(other.validationType == ValidationType.NONE) { return this; } @@ -240,7 +240,7 @@ class GuardedInvocationComponent { throw new AssertionError("Incompatible composition " + this + " vs " + other); } - private boolean isAssignableFrom(Validator other) { + private boolean isAssignableFrom(final Validator other) { return validatorClass.isAssignableFrom(other.validatorClass); } diff --git a/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java b/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java index 3ee8e41ab30..8b5e3214a30 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java +++ b/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java @@ -105,7 +105,7 @@ class MaximallySpecific { * @param varArgs whether to assume the methods are varargs * @return the list of maximally specific methods. */ - static List getMaximallySpecificMethods(List methods, boolean varArgs) { + static List getMaximallySpecificMethods(final List methods, final boolean varArgs) { return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null); } @@ -116,7 +116,7 @@ class MaximallySpecific { private static final MethodTypeGetter METHOD_HANDLE_TYPE_GETTER = new MethodTypeGetter() { @Override - MethodType getMethodType(MethodHandle t) { + MethodType getMethodType(final MethodHandle t) { return t.type(); } }; @@ -124,7 +124,7 @@ class MaximallySpecific { private static final MethodTypeGetter DYNAMIC_METHOD_TYPE_GETTER = new MethodTypeGetter() { @Override - MethodType getMethodType(SingleDynamicMethod t) { + MethodType getMethodType(final SingleDynamicMethod t) { return t.getMethodType(); } }; @@ -138,8 +138,8 @@ class MaximallySpecific { * @param argTypes concrete argument types for the invocation * @return the list of maximally specific method handles. */ - static List getMaximallySpecificMethodHandles(List methods, boolean varArgs, - Class[] argTypes, LinkerServices ls) { + static List getMaximallySpecificMethodHandles(final List methods, final boolean varArgs, + final Class[] argTypes, final LinkerServices ls) { return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER); } @@ -152,8 +152,8 @@ class MaximallySpecific { * @param argTypes concrete argument types for the invocation * @return the list of maximally specific methods. */ - static List getMaximallySpecificSingleDynamicMethods(List methods, - boolean varArgs, Class[] argTypes, LinkerServices ls) { + static List getMaximallySpecificSingleDynamicMethods(final List methods, + final boolean varArgs, final Class[] argTypes, final LinkerServices ls) { return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER); } @@ -166,16 +166,16 @@ class MaximallySpecific { * @param argTypes concrete argument types for the invocation * @return the list of maximally specific methods. */ - private static List getMaximallySpecificMethods(List methods, boolean varArgs, - Class[] argTypes, LinkerServices ls, MethodTypeGetter methodTypeGetter) { + private static List getMaximallySpecificMethods(final List methods, final boolean varArgs, + final Class[] argTypes, final LinkerServices ls, final MethodTypeGetter methodTypeGetter) { if(methods.size() < 2) { return methods; } final LinkedList maximals = new LinkedList<>(); - for(T m: methods) { + for(final T m: methods) { final MethodType methodType = methodTypeGetter.getMethodType(m); boolean lessSpecific = false; - for(Iterator maximal = maximals.iterator(); maximal.hasNext();) { + for(final Iterator maximal = maximals.iterator(); maximal.hasNext();) { final T max = maximal.next(); switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) { case TYPE_1_BETTER: { @@ -202,8 +202,8 @@ class MaximallySpecific { return maximals; } - private static Comparison isMoreSpecific(MethodType t1, MethodType t2, boolean varArgs, Class[] argTypes, - LinkerServices ls) { + private static Comparison isMoreSpecific(final MethodType t1, final MethodType t2, final boolean varArgs, final Class[] argTypes, + final LinkerServices ls) { final int pc1 = t1.parameterCount(); final int pc2 = t2.parameterCount(); assert varArgs || (pc1 == pc2) && (argTypes == null || argTypes.length == pc1); @@ -241,7 +241,7 @@ class MaximallySpecific { return Comparison.INDETERMINATE; } - private static Comparison compare(Class c1, Class c2, Class[] argTypes, int i, LinkerServices cmp) { + private static Comparison compare(final Class c1, final Class c2, final Class[] argTypes, final int i, final LinkerServices cmp) { if(cmp != null) { final Comparison c = cmp.compareConversion(argTypes[i], c1, c2); if(c != Comparison.INDETERMINATE) { @@ -256,7 +256,7 @@ class MaximallySpecific { return Comparison.INDETERMINATE; } - private static Class getParameterClass(MethodType t, int l, int i, boolean varArgs) { + private static Class getParameterClass(final MethodType t, final int l, final int i, final boolean varArgs) { return varArgs && i >= l - 1 ? t.parameterType(l - 1).getComponentType() : t.parameterType(i); } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java index 8ce41bc658c..7dc21a2978b 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java @@ -115,20 +115,20 @@ class OverloadedDynamicMethod extends DynamicMethod { * @param clazz the class this method belongs to * @param name the name of the method */ - OverloadedDynamicMethod(Class clazz, String name) { + OverloadedDynamicMethod(final Class clazz, final String name) { this(new LinkedList(), clazz.getClassLoader(), getClassAndMethodName(clazz, name)); } - private OverloadedDynamicMethod(LinkedList methods, ClassLoader classLoader, String name) { + private OverloadedDynamicMethod(final LinkedList methods, final ClassLoader classLoader, final String name) { super(name); this.methods = methods; this.classLoader = classLoader; } @Override - SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) { + SingleDynamicMethod getMethodForExactParamTypes(final String paramTypes) { final LinkedList matchingMethods = new LinkedList<>(); - for(SingleDynamicMethod method: methods) { + for(final SingleDynamicMethod method: methods) { final SingleDynamicMethod matchingMethod = method.getMethodForExactParamTypes(paramTypes); if(matchingMethod != null) { matchingMethods.add(matchingMethod); @@ -148,7 +148,6 @@ class OverloadedDynamicMethod extends DynamicMethod { } } - @SuppressWarnings("fallthrough") @Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); @@ -207,7 +206,7 @@ class OverloadedDynamicMethod extends DynamicMethod { case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. - invokables.iterator().next().getInvocation(callSiteDescriptor, linkerServices); + return invokables.iterator().next().getInvocation(callSiteDescriptor, linkerServices); } default: { // We have more than one candidate. We have no choice but to link to a method that resolves overloads on @@ -218,7 +217,7 @@ class OverloadedDynamicMethod extends DynamicMethod { // has an already determined Lookup. final List methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); - for(SingleDynamicMethod method: invokables) { + for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); @@ -228,8 +227,8 @@ class OverloadedDynamicMethod extends DynamicMethod { } @Override - public boolean contains(SingleDynamicMethod m) { - for(SingleDynamicMethod method: methods) { + public boolean contains(final SingleDynamicMethod m) { + for(final SingleDynamicMethod method: methods) { if(method.contains(m)) { return true; } @@ -241,8 +240,8 @@ class OverloadedDynamicMethod extends DynamicMethod { return classLoader; } - private static boolean isApplicableDynamically(LinkerServices linkerServices, MethodType callSiteType, - SingleDynamicMethod m) { + private static boolean isApplicableDynamically(final LinkerServices linkerServices, final MethodType callSiteType, + final SingleDynamicMethod m) { final MethodType methodType = m.getMethodType(); final boolean varArgs = m.isVarArgs(); final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0); @@ -288,13 +287,13 @@ class OverloadedDynamicMethod extends DynamicMethod { return true; } - private static boolean isApplicableDynamically(LinkerServices linkerServices, Class callSiteType, - Class methodType) { + private static boolean isApplicableDynamically(final LinkerServices linkerServices, final Class callSiteType, + final Class methodType) { return TypeUtilities.isPotentiallyConvertible(callSiteType, methodType) || linkerServices.canConvert(callSiteType, methodType); } - private ApplicableOverloadedMethods getApplicables(MethodType callSiteType, ApplicabilityTest test) { + private ApplicableOverloadedMethods getApplicables(final MethodType callSiteType, final ApplicabilityTest test) { return new ApplicableOverloadedMethods(methods, callSiteType, test); } @@ -303,7 +302,7 @@ class OverloadedDynamicMethod extends DynamicMethod { * * @param method a method to add */ - public void addMethod(SingleDynamicMethod method) { + public void addMethod(final SingleDynamicMethod method) { methods.add(method); } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java b/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java index f711489b037..75332859f17 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java @@ -93,6 +93,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.Lookup; +import jdk.internal.dynalink.support.TypeUtilities; /** * Represents a subset of overloaded methods for a certain method name on a certain class. It can be either a fixarg or @@ -111,16 +112,18 @@ class OverloadedMethod { private final ArrayList fixArgMethods; private final ArrayList varArgMethods; - OverloadedMethod(List methodHandles, OverloadedDynamicMethod parent, MethodType callSiteType, - LinkerServices linkerServices) { + OverloadedMethod(final List methodHandles, final OverloadedDynamicMethod parent, final MethodType callSiteType, + final LinkerServices linkerServices) { this.parent = parent; - this.callSiteType = callSiteType; + final Class commonRetType = getCommonReturnType(methodHandles); + this.callSiteType = callSiteType.changeReturnType(commonRetType); this.linkerServices = linkerServices; fixArgMethods = new ArrayList<>(methodHandles.size()); varArgMethods = new ArrayList<>(methodHandles.size()); final int argNum = callSiteType.parameterCount(); for(MethodHandle mh: methodHandles) { + mh = mh.asType(mh.type().changeReturnType(commonRetType)); if(mh.isVarargsCollector()) { final MethodHandle asFixed = mh.asFixedArity(); if(argNum == asFixed.type().parameterCount()) { @@ -137,7 +140,7 @@ class OverloadedMethod { final MethodHandle bound = SELECT_METHOD.bindTo(this); final MethodHandle collecting = SingleDynamicMethod.collectArguments(bound, argNum).asType( callSiteType.changeReturnType(MethodHandle.class)); - invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(callSiteType), collecting); + invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(this.callSiteType), collecting); } MethodHandle getInvoker() { @@ -148,7 +151,7 @@ class OverloadedMethod { MethodHandle.class, Object[].class); @SuppressWarnings("unused") - private MethodHandle selectMethod(Object[] args) throws NoSuchMethodException { + private MethodHandle selectMethod(final Object[] args) throws NoSuchMethodException { final Class[] argTypes = new Class[args.length]; for(int i = 0; i < argTypes.length; ++i) { final Object arg = args[i]; @@ -185,7 +188,7 @@ class OverloadedMethod { return method; } - private MethodHandle getNoSuchMethodThrower(Class[] argTypes) { + private MethodHandle getNoSuchMethodThrower(final Class[] argTypes) { return adaptThrower(MethodHandles.insertArguments(THROW_NO_SUCH_METHOD, 0, this, argTypes)); } @@ -193,7 +196,7 @@ class OverloadedMethod { "throwNoSuchMethod", void.class, Class[].class); @SuppressWarnings("unused") - private void throwNoSuchMethod(Class[] argTypes) throws NoSuchMethodException { + private void throwNoSuchMethod(final Class[] argTypes) throws NoSuchMethodException { if(varArgMethods.isEmpty()) { throw new NoSuchMethodException("None of the fixed arity signatures " + getSignatureList(fixArgMethods) + " of method " + parent.getName() + " match the argument types " + argTypesString(argTypes)); @@ -203,11 +206,11 @@ class OverloadedMethod { parent.getName() + " match the argument types " + argTypesString(argTypes)); } - private MethodHandle getAmbiguousMethodThrower(Class[] argTypes, List methods) { + private MethodHandle getAmbiguousMethodThrower(final Class[] argTypes, final List methods) { return adaptThrower(MethodHandles.insertArguments(THROW_AMBIGUOUS_METHOD, 0, this, argTypes, methods)); } - private MethodHandle adaptThrower(MethodHandle rawThrower) { + private MethodHandle adaptThrower(final MethodHandle rawThrower) { return MethodHandles.dropArguments(rawThrower, 0, callSiteType.parameterList()).asType(callSiteType); } @@ -215,20 +218,20 @@ class OverloadedMethod { "throwAmbiguousMethod", void.class, Class[].class, List.class); @SuppressWarnings("unused") - private void throwAmbiguousMethod(Class[] argTypes, List methods) throws NoSuchMethodException { + private void throwAmbiguousMethod(final Class[] argTypes, final List methods) throws NoSuchMethodException { final String arity = methods.get(0).isVarargsCollector() ? "variable" : "fixed"; throw new NoSuchMethodException("Can't unambiguously select between " + arity + " arity signatures " + getSignatureList(methods) + " of the method " + parent.getName() + " for argument types " + argTypesString(argTypes)); } - private static String argTypesString(Class[] classes) { + private static String argTypesString(final Class[] classes) { final StringBuilder b = new StringBuilder().append('['); appendTypes(b, classes, false); return b.append(']').toString(); } - private static String getSignatureList(List methods) { + private static String getSignatureList(final List methods) { final StringBuilder b = new StringBuilder().append('['); final Iterator it = methods.iterator(); if(it.hasNext()) { @@ -240,13 +243,13 @@ class OverloadedMethod { return b.append(']').toString(); } - private static void appendSig(StringBuilder b, MethodHandle m) { + private static void appendSig(final StringBuilder b, final MethodHandle m) { b.append('('); appendTypes(b, m.type().parameterArray(), m.isVarargsCollector()); b.append(')'); } - private static void appendTypes(StringBuilder b, Class[] classes, boolean varArg) { + private static void appendTypes(final StringBuilder b, final Class[] classes, final boolean varArg) { final int l = classes.length; if(!varArg) { if(l > 1) { @@ -262,4 +265,13 @@ class OverloadedMethod { b.append(classes[l - 1].getComponentType().getCanonicalName()).append("..."); } } + + private static Class getCommonReturnType(final List methodHandles) { + final Iterator it = methodHandles.iterator(); + Class retType = it.next().type().returnType(); + while(it.hasNext()) { + retType = TypeUtilities.getCommonLosslessConversionType(retType, it.next().type().returnType()); + } + return retType; + } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java index 9d4d6961081..2965cb4e401 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java @@ -107,12 +107,12 @@ class SimpleDynamicMethod extends SingleDynamicMethod { * @param clazz the class declaring the method * @param name the simple name of the method */ - SimpleDynamicMethod(MethodHandle target, Class clazz, String name) { + SimpleDynamicMethod(final MethodHandle target, final Class clazz, final String name) { super(getName(target, clazz, name)); this.target = target; } - private static String getName(MethodHandle target, Class clazz, String name) { + private static String getName(final MethodHandle target, final Class clazz, final String name) { return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name)); } @@ -127,7 +127,7 @@ class SimpleDynamicMethod extends SingleDynamicMethod { } @Override - MethodHandle getTarget(Lookup lookup) { + MethodHandle getTarget(final Lookup lookup) { return target; } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java index 6b55d81f15c..79dca9a3ce1 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java @@ -104,7 +104,7 @@ abstract class SingleDynamicMethod extends DynamicMethod { private static final MethodHandle CAN_CONVERT_TO = Lookup.findOwnStatic(MethodHandles.lookup(), "canConvertTo", boolean.class, LinkerServices.class, Class.class, Object.class); - SingleDynamicMethod(String name) { + SingleDynamicMethod(final String name) { super(name); } @@ -128,22 +128,22 @@ abstract class SingleDynamicMethod extends DynamicMethod { abstract MethodHandle getTarget(MethodHandles.Lookup lookup); @Override - MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) { + MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { return getInvocation(getTarget(callSiteDescriptor.getLookup()), callSiteDescriptor.getMethodType(), linkerServices); } @Override - SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) { + SingleDynamicMethod getMethodForExactParamTypes(final String paramTypes) { return typeMatchesDescription(paramTypes, getMethodType()) ? this : null; } @Override - boolean contains(SingleDynamicMethod method) { + boolean contains(final SingleDynamicMethod method) { return getMethodType().parameterList().equals(method.getMethodType().parameterList()); } - static String getMethodNameWithSignature(MethodType type, String methodName) { + static String getMethodNameWithSignature(final MethodType type, final String methodName) { final String typeStr = type.toString(); final int retTypeIndex = typeStr.lastIndexOf(')') + 1; int secondParamIndex = typeStr.indexOf(',') + 1; @@ -156,13 +156,15 @@ abstract class SingleDynamicMethod extends DynamicMethod { /** * Given a method handle and a call site type, adapts the method handle to the call site type. Performs type * conversions as needed using the specified linker services, and in case that the method handle is a vararg - * collector, matches it to the arity of the call site. + * collector, matches it to the arity of the call site. The type of the return value is only changed if it can be + * converted using a conversion that loses neither precision nor magnitude, see + * {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)}. * @param target the method handle to adapt * @param callSiteType the type of the call site * @param linkerServices the linker services used for type conversions * @return the adapted method handle. */ - static MethodHandle getInvocation(MethodHandle target, MethodType callSiteType, LinkerServices linkerServices) { + static MethodHandle getInvocation(final MethodHandle target, final MethodType callSiteType, final LinkerServices linkerServices) { final MethodType methodType = target.type(); final int paramsLen = methodType.parameterCount(); final boolean varArgs = target.isVarargsCollector(); @@ -264,7 +266,7 @@ abstract class SingleDynamicMethod extends DynamicMethod { } @SuppressWarnings("unused") - private static boolean canConvertTo(final LinkerServices linkerServices, Class to, Object obj) { + private static boolean canConvertTo(final LinkerServices linkerServices, final Class to, final Object obj) { return obj == null ? false : linkerServices.canConvert(obj.getClass(), to); } @@ -277,7 +279,7 @@ abstract class SingleDynamicMethod extends DynamicMethod { * @param parameterCount the total number of arguments in the new method handle * @return a collecting method handle */ - static MethodHandle collectArguments(MethodHandle target, final int parameterCount) { + static MethodHandle collectArguments(final MethodHandle target, final int parameterCount) { final MethodType methodType = target.type(); final int fixParamsLen = methodType.parameterCount() - 1; final Class arrayType = methodType.parameterType(fixParamsLen); @@ -286,10 +288,10 @@ abstract class SingleDynamicMethod extends DynamicMethod { private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod, final LinkerServices linkerServices, final MethodType callSiteType) { - return linkerServices.asType(sizedMethod, callSiteType); + return linkerServices.asTypeLosslessReturn(sizedMethod, callSiteType); } - private static boolean typeMatchesDescription(String paramTypes, MethodType type) { + private static boolean typeMatchesDescription(final String paramTypes, final MethodType type) { final StringTokenizer tok = new StringTokenizer(paramTypes, ", "); for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) { @@ -299,7 +301,7 @@ abstract class SingleDynamicMethod extends DynamicMethod { return !tok.hasMoreTokens(); } - private static boolean typeNameMatches(String typeName, Class type) { + private static boolean typeNameMatches(final String typeName, final Class type) { return typeName.equals(typeName.indexOf('.') == -1 ? type.getSimpleName() : type.getCanonicalName()); } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java index 5008c211432..f70f264709b 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java +++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClass.java @@ -96,7 +96,7 @@ import java.io.Serializable; public class StaticClass implements Serializable { private static final ClassValue staticClasses = new ClassValue() { @Override - protected StaticClass computeValue(Class type) { + protected StaticClass computeValue(final Class type) { return new StaticClass(type); } }; @@ -105,7 +105,7 @@ public class StaticClass implements Serializable { private final Class clazz; - /*private*/ StaticClass(Class clazz) { + /*private*/ StaticClass(final Class clazz) { clazz.getClass(); // NPE check this.clazz = clazz; } @@ -115,7 +115,7 @@ public class StaticClass implements Serializable { * @param clazz the class for which the static facet is requested. * @return the {@link StaticClass} instance representing the specified class. */ - public static StaticClass forClass(Class clazz) { + public static StaticClass forClass(final Class clazz) { return staticClasses.get(clazz); } diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java index 62ce41a95a6..8a07c1f12b1 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java @@ -90,14 +90,14 @@ import java.util.HashMap; import java.util.Map; class StaticClassIntrospector extends FacetIntrospector { - StaticClassIntrospector(Class clazz) { + StaticClassIntrospector(final Class clazz) { super(clazz, false); } @Override Map getInnerClassGetters() { final Map map = new HashMap<>(); - for(Class innerClass: membersLookup.getInnerClasses()) { + for(final Class innerClass: membersLookup.getInnerClasses()) { map.put(innerClass.getSimpleName(), editMethodHandle(MethodHandles.constant(StaticClass.class, StaticClass.forClass(innerClass)))); } @@ -105,15 +105,15 @@ class StaticClassIntrospector extends FacetIntrospector { } @Override - MethodHandle editMethodHandle(MethodHandle mh) { + MethodHandle editMethodHandle(final MethodHandle mh) { return editStaticMethodHandle(mh); } - static MethodHandle editStaticMethodHandle(MethodHandle mh) { + static MethodHandle editStaticMethodHandle(final MethodHandle mh) { return dropReceiver(mh, Object.class); } - static MethodHandle editConstructorMethodHandle(MethodHandle cmh) { + static MethodHandle editConstructorMethodHandle(final MethodHandle cmh) { return dropReceiver(cmh, StaticClass.class); } diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java index 5f80caea74f..41955bb9e39 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java @@ -104,7 +104,7 @@ import jdk.internal.dynalink.support.Lookup; class StaticClassLinker implements TypeBasedGuardingDynamicLinker { private static final ClassValue linkers = new ClassValue() { @Override - protected SingleClassStaticsLinker computeValue(Class clazz) { + protected SingleClassStaticsLinker computeValue(final Class clazz) { return new SingleClassStaticsLinker(clazz); } }; @@ -112,7 +112,7 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { private static class SingleClassStaticsLinker extends AbstractJavaLinker { private final DynamicMethod constructor; - SingleClassStaticsLinker(Class clazz) { + SingleClassStaticsLinker(final Class clazz) { super(clazz, IS_CLASS.bindTo(clazz)); // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS. @@ -126,7 +126,7 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { * @return a dynamic method containing all overloads of a class' public constructor. If the class has no public * constructors, returns null. */ - private static DynamicMethod createConstructorMethod(Class clazz) { + private static DynamicMethod createConstructorMethod(final Class clazz) { if(clazz.isArray()) { final MethodHandle boundArrayCtor = ARRAY_CTOR.bindTo(clazz.getComponentType()); return new SimpleDynamicMethod(StaticClassIntrospector.editConstructorMethodHandle( @@ -144,7 +144,7 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices) + public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { final GuardedInvocation gi = super.getGuardedInvocation(request, linkerServices); if(gi != null) { @@ -162,20 +162,20 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { } } - static Collection getReadableStaticPropertyNames(Class clazz) { + static Collection getReadableStaticPropertyNames(final Class clazz) { return linkers.get(clazz).getReadablePropertyNames(); } - static Collection getWritableStaticPropertyNames(Class clazz) { + static Collection getWritableStaticPropertyNames(final Class clazz) { return linkers.get(clazz).getWritablePropertyNames(); } - static Collection getStaticMethodNames(Class clazz) { + static Collection getStaticMethodNames(final Class clazz) { return linkers.get(clazz).getMethodNames(); } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices) throws Exception { + public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { final Object receiver = request.getReceiver(); if(receiver instanceof StaticClass) { return linkers.get(((StaticClass)receiver).getRepresentedClass()).getGuardedInvocation(request, @@ -185,7 +185,7 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { } @Override - public boolean canLinkType(Class type) { + public boolean canLinkType(final Class type) { return type == StaticClass.class; } @@ -201,7 +201,7 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { } @SuppressWarnings("unused") - private static boolean isClass(Class clazz, Object obj) { + private static boolean isClass(final Class clazz, final Object obj) { return obj instanceof StaticClass && ((StaticClass)obj).getRepresentedClass() == clazz; } } diff --git a/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java b/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java index 26a741e8288..34dcdc03d76 100644 --- a/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java +++ b/nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java @@ -83,6 +83,8 @@ package jdk.internal.dynalink.linker; +import static jdk.nashorn.internal.lookup.Lookup.MH; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -104,7 +106,18 @@ import jdk.internal.dynalink.support.Guards; public class GuardedInvocation { private final MethodHandle invocation; private final MethodHandle guard; - private final SwitchPoint switchPoint; + private final Class exception; + private final SwitchPoint[] switchPoints; + + /** + * Creates a new guarded invocation. This invocation is unconditional as it has no invalidations. + * + * @param invocation the method handle representing the invocation. Must not be null. + * @throws NullPointerException if invocation is null. + */ + public GuardedInvocation(final MethodHandle invocation) { + this(invocation, null, (SwitchPoint)null, null); + } /** * Creates a new guarded invocation. @@ -115,8 +128,19 @@ public class GuardedInvocation { * an unconditional invocation, although that is unusual. * @throws NullPointerException if invocation is null. */ - public GuardedInvocation(MethodHandle invocation, MethodHandle guard) { - this(invocation, guard, null); + public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard) { + this(invocation, guard, (SwitchPoint)null, null); + } + + /** + * Creates a new guarded invocation. + * + * @param invocation the method handle representing the invocation. Must not be null. + * @param switchPoint the optional switch point that can be used to invalidate this linkage. + * @throws NullPointerException if invocation is null. + */ + public GuardedInvocation(final MethodHandle invocation, final SwitchPoint switchPoint) { + this(invocation, null, switchPoint, null); } /** @@ -129,26 +153,50 @@ public class GuardedInvocation { * @param switchPoint the optional switch point that can be used to invalidate this linkage. * @throws NullPointerException if invocation is null. */ - public GuardedInvocation(MethodHandle invocation, MethodHandle guard, SwitchPoint switchPoint) { + public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint) { + this(invocation, guard, switchPoint, null); + } + + /** + * Creates a new guarded invocation. + * + * @param invocation the method handle representing the invocation. Must not be null. + * @param guard the method handle representing the guard. Must have the same method type as the invocation, except + * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it + * and the switch point are null, this represents an unconditional invocation, which is legal but unusual. + * @param switchPoint the optional switch point that can be used to invalidate this linkage. + * @param exception the optional exception type that is expected to be thrown by the invocation and that also + * invalidates the linkage. + * @throws NullPointerException if invocation is null. + */ + public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint, final Class exception) { invocation.getClass(); // NPE check this.invocation = invocation; this.guard = guard; - this.switchPoint = switchPoint; + this.switchPoints = switchPoint == null ? null : new SwitchPoint[] { switchPoint }; + this.exception = exception; } /** - * Creates a new guarded invocation. + * Creates a new guarded invocation * * @param invocation the method handle representing the invocation. Must not be null. - * @param switchPoint the optional switch point that can be used to invalidate this linkage. * @param guard the method handle representing the guard. Must have the same method type as the invocation, except * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it * and the switch point are null, this represents an unconditional invocation, which is legal but unusual. + * @param switchPoints the optional switch points that can be used to invalidate this linkage. + * @param exception the optional exception type that is expected to be thrown by the invocation and that also + * invalidates the linkage. * @throws NullPointerException if invocation is null. */ - public GuardedInvocation(MethodHandle invocation, SwitchPoint switchPoint, MethodHandle guard) { - this(invocation, guard, switchPoint); + public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint[] switchPoints, final Class exception) { + invocation.getClass(); // NPE check + this.invocation = invocation; + this.guard = guard; + this.switchPoints = switchPoints; + this.exception = exception; } + /** * Returns the invocation method handle. * @@ -172,8 +220,17 @@ public class GuardedInvocation { * * @return the switch point that can be used to invalidate the invocation handle. Can be null. */ - public SwitchPoint getSwitchPoint() { - return switchPoint; + public SwitchPoint[] getSwitchPoints() { + return switchPoints == null ? null : switchPoints.clone(); + } + + /** + * Returns the exception type that if thrown should be used to invalidate the linkage. + * + * @return the exception type that if thrown should be used to invalidate the linkage. Can be null. + */ + public Class getException() { + return exception; } /** @@ -181,7 +238,15 @@ public class GuardedInvocation { * @return true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated. */ public boolean hasBeenInvalidated() { - return switchPoint != null && switchPoint.hasBeenInvalidated(); + if (switchPoints == null) { + return false; + } + for (final SwitchPoint sp : switchPoints) { + if (sp.hasBeenInvalidated()) { + return true; + } + } + return false; } /** @@ -191,9 +256,9 @@ public class GuardedInvocation { * @param type the asserted type * @throws WrongMethodTypeException if the invocation and the guard are not of the expected method type. */ - public void assertType(MethodType type) { + public void assertType(final MethodType type) { assertType(invocation, type); - if(guard != null) { + if (guard != null) { assertType(guard, type.changeReturnType(Boolean.TYPE)); } } @@ -205,12 +270,34 @@ public class GuardedInvocation { * @param newGuard the new guard * @return a new guarded invocation with the replaced methods and the same switch point as this invocation. */ - public GuardedInvocation replaceMethods(MethodHandle newInvocation, MethodHandle newGuard) { - return new GuardedInvocation(newInvocation, newGuard, switchPoint); + public GuardedInvocation replaceMethods(final MethodHandle newInvocation, final MethodHandle newGuard) { + return new GuardedInvocation(newInvocation, newGuard, switchPoints, exception); } - private GuardedInvocation replaceMethodsOrThis(MethodHandle newInvocation, MethodHandle newGuard) { - if(newInvocation == invocation && newGuard == guard) { + /** + * Add a switchpoint to this guarded invocation + * @param newSwitchPoint new switchpoint, or null for nop + * @return new guarded invocation with the extra switchpoint + */ + public GuardedInvocation addSwitchPoint(final SwitchPoint newSwitchPoint) { + if (newSwitchPoint == null) { + return this; + } + + final SwitchPoint[] newSwitchPoints; + if (switchPoints != null) { + newSwitchPoints = new SwitchPoint[switchPoints.length + 1]; + System.arraycopy(switchPoints, 0, newSwitchPoints, 0, switchPoints.length); + newSwitchPoints[switchPoints.length] = newSwitchPoint; + } else { + newSwitchPoints = new SwitchPoint[] { newSwitchPoint }; + } + + return new GuardedInvocation(invocation, guard, newSwitchPoints, exception); + } + + private GuardedInvocation replaceMethodsOrThis(final MethodHandle newInvocation, final MethodHandle newGuard) { + if (newInvocation == invocation && newGuard == guard) { return this; } return replaceMethods(newInvocation, newGuard); @@ -223,7 +310,7 @@ public class GuardedInvocation { * @param newType the new type of the invocation. * @return a guarded invocation with the new type applied to it. */ - public GuardedInvocation asType(MethodType newType) { + public GuardedInvocation asType(final MethodType newType) { return replaceMethodsOrThis(invocation.asType(newType), guard == null ? null : Guards.asType(guard, newType)); } @@ -235,11 +322,25 @@ public class GuardedInvocation { * @param newType the new type of the invocation. * @return a guarded invocation with the new type applied to it. */ - public GuardedInvocation asType(LinkerServices linkerServices, MethodType newType) { + public GuardedInvocation asType(final LinkerServices linkerServices, final MethodType newType) { return replaceMethodsOrThis(linkerServices.asType(invocation, newType), guard == null ? null : Guards.asType(linkerServices, guard, newType)); } + /** + * Changes the type of the invocation, as if {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)} was + * applied to its invocation and {@link LinkerServices#asType(MethodHandle, MethodType)} applied to its guard, if it + * has one (with return type changed to boolean, and parameter count potentially truncated for the guard). If the + * invocation doesn't change its type, returns this object. + * @param linkerServices the linker services to use for the conversion + * @param newType the new type of the invocation. + * @return a guarded invocation with the new type applied to it. + */ + public GuardedInvocation asTypeSafeReturn(final LinkerServices linkerServices, final MethodType newType) { + return replaceMethodsOrThis(linkerServices.asTypeLosslessReturn(invocation, newType), guard == null ? null : + Guards.asType(linkerServices, guard, newType)); + } + /** * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation * and its guard, if it has one (with return type changed to boolean for guard). If the invocation already is of the @@ -247,7 +348,7 @@ public class GuardedInvocation { * @param desc a call descriptor whose method type is adapted. * @return a guarded invocation with the new type applied to it. */ - public GuardedInvocation asType(CallSiteDescriptor desc) { + public GuardedInvocation asType(final CallSiteDescriptor desc) { return asType(desc.getMethodType()); } @@ -257,7 +358,7 @@ public class GuardedInvocation { * @param filters the argument filters * @return a filtered invocation */ - public GuardedInvocation filterArguments(int pos, MethodHandle... filters) { + public GuardedInvocation filterArguments(final int pos, final MethodHandle... filters) { return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters), guard == null ? null : MethodHandles.filterArguments(guard, pos, filters)); } @@ -268,7 +369,7 @@ public class GuardedInvocation { * @param valueTypes the types of the values being dropped * @return an invocation that drops arguments */ - public GuardedInvocation dropArguments(int pos, List> valueTypes) { + public GuardedInvocation dropArguments(final int pos, final List> valueTypes) { return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null : MethodHandles.dropArguments(guard, pos, valueTypes)); } @@ -279,7 +380,7 @@ public class GuardedInvocation { * @param valueTypes the types of the values being dropped * @return an invocation that drops arguments */ - public GuardedInvocation dropArguments(int pos, Class... valueTypes) { + public GuardedInvocation dropArguments(final int pos, final Class... valueTypes) { return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null : MethodHandles.dropArguments(guard, pos, valueTypes)); } @@ -290,23 +391,50 @@ public class GuardedInvocation { * @param fallback the fallback method handle in case switchpoint is invalidated or guard returns false. * @return a composite method handle. */ - public MethodHandle compose(MethodHandle fallback) { - return compose(fallback, fallback); + public MethodHandle compose(final MethodHandle fallback) { + return compose(fallback, fallback, fallback); } /** * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back. * @param switchpointFallback the fallback method handle in case switchpoint is invalidated. * @param guardFallback the fallback method handle in case guard returns false. + * @param catchFallback the fallback method in case the exception handler triggers * @return a composite method handle. */ - public MethodHandle compose(MethodHandle switchpointFallback, MethodHandle guardFallback) { + public MethodHandle compose(final MethodHandle guardFallback, final MethodHandle switchpointFallback, final MethodHandle catchFallback) { final MethodHandle guarded = - guard == null ? invocation : MethodHandles.guardWithTest(guard, invocation, guardFallback); - return switchPoint == null ? guarded : switchPoint.guardWithTest(guarded, switchpointFallback); + guard == null ? + invocation : + MethodHandles.guardWithTest( + guard, + invocation, + guardFallback); + + final MethodHandle catchGuarded = + exception == null ? + guarded : + MH.catchException( + guarded, + exception, + MethodHandles.dropArguments( + catchFallback, + 0, + exception)); + + if (switchPoints == null) { + return catchGuarded; + } + + MethodHandle spGuarded = catchGuarded; + for (final SwitchPoint sp : switchPoints) { + spGuarded = sp.guardWithTest(spGuarded, switchpointFallback); + } + + return spGuarded; } - private static void assertType(MethodHandle mh, MethodType type) { + private static void assertType(final MethodHandle mh, final MethodType type) { if(!mh.type().equals(type)) { throw new WrongMethodTypeException("Expected type: " + type + " actual type: " + mh.type()); } diff --git a/nashorn/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java b/nashorn/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java index 9baed7c0ebd..88357ff0c98 100644 --- a/nashorn/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java +++ b/nashorn/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java @@ -83,19 +83,35 @@ package jdk.internal.dynalink.linker; +/** + * Guarded type conversion + */ public class GuardedTypeConversion { private final GuardedInvocation conversionInvocation; private final boolean cacheable; + /** + * Constructor + * @param conversionInvocation guarded invocation for this type conversion + * @param cacheable is this invocation cacheable + */ public GuardedTypeConversion(final GuardedInvocation conversionInvocation, final boolean cacheable) { this.conversionInvocation = conversionInvocation; this.cacheable = cacheable; } + /** + * Get the invocation + * @return invocation + */ public GuardedInvocation getConversionInvocation() { return conversionInvocation; } + /** + * Check if invocation is cacheable + * @return true if cachable, false otherwise + */ public boolean isCacheable() { return cacheable; } diff --git a/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java index 2cd0d0f04d1..82a361970ed 100644 --- a/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java +++ b/nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java @@ -101,10 +101,16 @@ public interface GuardingDynamicLinker { * @return a guarded invocation with a method handle suitable for the arguments, as well as a guard condition that * if fails should trigger relinking. Must return null if it can't resolve the invocation. If the returned * invocation is unconditional (which is actually quite rare), the guard in the return value can be null. The - * invocation can also have a switch point for asynchronous invalidation of the linkage. If the linker does not - * recognize any native language runtime contexts in arguments, or does recognize its own, but receives a call site - * descriptor without its recognized context in the arguments, it should invoke - * {@link LinkRequest#withoutRuntimeContext()} and link for that. + * invocation can also have a switch point for asynchronous invalidation of the linkage, as well as a + * {@link Throwable} subclass that describes an expected exception condition that also triggers relinking (often it + * is faster to rely on an infrequent but expected {@link ClassCastException} than on an always evaluated + * {@code instanceof} guard). If the linker does not recognize any native language runtime contexts in arguments, or + * does recognize its own, but receives a call site descriptor without its recognized context in the arguments, it + * should invoke {@link LinkRequest#withoutRuntimeContext()} and link for that. While the linker must produce an + * invocation with parameter types matching those in the call site descriptor of the link request, it should not try + * to match the return type expected at the call site except when it can do it with only the conversions that lose + * neither precision nor magnitude, see {@link LinkerServices#asTypeLosslessReturn(java.lang.invoke.MethodHandle, + * java.lang.invoke.MethodType)}. * @throws Exception if the operation fails for whatever reason */ public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) diff --git a/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java b/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java index 1a82a4fab7b..63501cdc12e 100644 --- a/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java +++ b/nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java @@ -100,6 +100,17 @@ public interface LinkRequest { */ public CallSiteDescriptor getCallSiteDescriptor(); + /** + * Returns the call site token for the call site being linked. This token is an opaque object that is guaranteed to + * have different identity for different call sites, and is also guaranteed to not become weakly reachable before + * the call site does and to become weakly reachable some time after the call site does. This makes it ideal as a + * candidate for a key in a weak hash map in which a linker might want to keep per-call site linking state (usually + * profiling information). + * + * @return the call site token for the call site being linked. + */ + public Object getCallSiteToken(); + /** * Returns the arguments for the invocation being linked. The returned array is a clone; modifications to it won't * affect the arguments in this request. @@ -115,6 +126,17 @@ public interface LinkRequest { */ public Object getReceiver(); + /** + * Returns the number of times this callsite has been linked/relinked. This can be useful if you want to + * change e.g. exception based relinking to guard based relinking. It's probably not a good idea to keep, + * for example, expensive exception throwing relinkage based on failed type checks/ClassCastException in + * a nested callsite tree where the exception is thrown repeatedly for the common case. There it would be + * much more performant to use exact type guards instead. + * + * @return link count for call site + */ + public int getLinkCount(); + /** * Returns true if the call site is considered unstable, that is, it has been relinked more times than was * specified in {@link DynamicLinkerFactory#setUnstableRelinkThreshold(int)}. Linkers should use this as a diff --git a/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java b/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java index deaf820f11b..9e35d7f6be5 100644 --- a/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java +++ b/nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java @@ -87,7 +87,9 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import jdk.internal.dynalink.DynamicLinker; +import jdk.internal.dynalink.DynamicLinkerFactory; import jdk.internal.dynalink.linker.ConversionComparator.Comparison; +import jdk.internal.dynalink.support.TypeUtilities; /** * Interface for services provided to {@link GuardingDynamicLinker} instances by the {@link DynamicLinker} that owns @@ -103,17 +105,33 @@ public interface LinkerServices { * parameters. It will apply {@link MethodHandle#asType(MethodType)} for all primitive-to-primitive, * wrapper-to-primitive, primitive-to-wrapper conversions as well as for all upcasts. For all other conversions, * it'll insert {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters - * provided by {@link GuardingTypeConverterFactory} implementations. It doesn't use language-specific conversions on - * the return type. + * provided by {@link GuardingTypeConverterFactory} implementations. * * @param handle target method handle * @param fromType the types of source arguments - * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)} and - * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with - * {@link GuardingTypeConverterFactory} produced type converters as filters. + * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)}, + * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}, and + * {@link MethodHandles#filterReturnValue(MethodHandle, MethodHandle)} with + * {@link GuardingTypeConverterFactory}-produced type converters as filters. */ public MethodHandle asType(MethodHandle handle, MethodType fromType); + /** + * Similar to {@link #asType(MethodHandle, MethodType)} except it only converts the return type of the method handle + * when it can be done using a conversion that loses neither precision nor magnitude, otherwise it leaves it + * unchanged. The idea is that other conversions should not be performed by individual linkers, but instead the + * {@link DynamicLinkerFactory#setPrelinkFilter(jdk.internal.dynalink.GuardedInvocationFilter) pre-link filter of + * the dynamic linker} should implement the strategy of dealing with potentially lossy return type conversions in a + * manner specific to the language runtime. + * + * @param handle target method handle + * @param fromType the types of source arguments + * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)}, and + * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with + * {@link GuardingTypeConverterFactory}-produced type converters as filters. + */ + public MethodHandle asTypeLosslessReturn(MethodHandle handle, MethodType fromType); + /** * Given a source and target type, returns a method handle that converts between them. Never returns null; in worst * case it will return an identity conversion (that might fail for some values at runtime). You rarely need to use @@ -161,4 +179,23 @@ public interface LinkerServices { * conversion. */ public Comparison compareConversion(Class sourceType, Class targetType1, Class targetType2); + + /** + * If we could just use Java 8 constructs, then {@code asTypeSafeReturn} would be a method with default + * implementation. Since we can't do that, we extract common default implementations into this static class. + */ + public static class Implementation { + /** + * Default implementation for {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)}. + * @param linkerServices the linker services that delegates to this implementation + * @param handle the passed handle + * @param fromType the passed type + * @return the converted method handle, as per the {@code asTypeSafeReturn} semantics. + */ + public static MethodHandle asTypeLosslessReturn(final LinkerServices linkerServices, final MethodHandle handle, final MethodType fromType) { + final Class handleReturnType = handle.type().returnType(); + return linkerServices.asType(handle, TypeUtilities.isConvertibleWithoutLoss(handleReturnType, fromType.returnType()) ? + fromType : fromType.changeReturnType(handleReturnType)); + } + } } diff --git a/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java index 3161cf50a76..6bcbbbb3444 100644 --- a/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java +++ b/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java @@ -106,7 +106,7 @@ public abstract class AbstractCallSiteDescriptor implements CallSiteDescriptor { } @Override - public boolean equals(Object obj) { + public boolean equals(final Object obj) { return obj instanceof CallSiteDescriptor && equals((CallSiteDescriptor)obj); } @@ -115,7 +115,7 @@ public abstract class AbstractCallSiteDescriptor implements CallSiteDescriptor { * @param csd the other call site descriptor. * @return true if they are equal. */ - public boolean equals(CallSiteDescriptor csd) { + public boolean equals(final CallSiteDescriptor csd) { if(csd == null) { return false; } @@ -165,7 +165,7 @@ public abstract class AbstractCallSiteDescriptor implements CallSiteDescriptor { return l + c - 1; } - private StringBuilder appendName(StringBuilder b) { + private StringBuilder appendName(final StringBuilder b) { b.append(getNameToken(0)); final int c = getNameTokenCount(); for(int i = 1; i < c; ++i) { @@ -174,7 +174,7 @@ public abstract class AbstractCallSiteDescriptor implements CallSiteDescriptor { return b; } - private static boolean lookupsEqual(Lookup l1, Lookup l2) { + private static boolean lookupsEqual(final Lookup l1, final Lookup l2) { if(l1 == l2) { return true; } diff --git a/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java b/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java index c05d35e0948..e01880e56ca 100644 --- a/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java +++ b/nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java @@ -100,7 +100,7 @@ public abstract class AbstractRelinkableCallSite extends MutableCallSite impleme * Creates a new relinkable call site. * @param descriptor the descriptor for this call site */ - protected AbstractRelinkableCallSite(CallSiteDescriptor descriptor) { + protected AbstractRelinkableCallSite(final CallSiteDescriptor descriptor) { super(descriptor.getMethodType()); this.descriptor = descriptor; } @@ -111,7 +111,7 @@ public abstract class AbstractRelinkableCallSite extends MutableCallSite impleme } @Override - public void initialize(MethodHandle relinkAndInvoke) { + public void initialize(final MethodHandle relinkAndInvoke) { setTarget(relinkAndInvoke); } } diff --git a/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java b/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java index 2909365935b..ba318610c08 100644 --- a/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java +++ b/nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java @@ -116,14 +116,14 @@ public class AutoDiscovery { * @return a list of guarding dynamic linkers available through the specified class loader. Can be zero-length list * but not null. */ - public static List loadLinkers(ClassLoader cl) { + public static List loadLinkers(final ClassLoader cl) { return getLinkers(ServiceLoader.load(GuardingDynamicLinker.class, cl)); } /** * I can't believe there's no Collections API for making a List given an Iterator... */ - private static List getLinkers(ServiceLoader loader) { + private static List getLinkers(final ServiceLoader loader) { final List list = new LinkedList<>(); for(final T linker: loader) { list.add(linker); diff --git a/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java index 7a2700e10ff..07abb6c398e 100644 --- a/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java +++ b/nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java @@ -105,12 +105,12 @@ public class BottomGuardingDynamicLinker implements TypeBasedGuardingDynamicLink } @Override - public boolean canLinkType(Class type) { + public boolean canLinkType(final Class type) { return false; } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) { + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) { return null; } } diff --git a/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java b/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java index b0039d21c2c..9cbd5f04f3f 100644 --- a/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java +++ b/nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java @@ -86,6 +86,7 @@ package jdk.internal.dynalink.support; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.Collections; @@ -103,7 +104,7 @@ import jdk.internal.dynalink.CallSiteDescriptor; * @author Attila Szegedi */ public class CallSiteDescriptorFactory { - private static final WeakHashMap> publicDescs = + private static final WeakHashMap> publicDescs = new WeakHashMap<>(); @@ -121,7 +122,7 @@ public class CallSiteDescriptorFactory { * @return a call site descriptor representing the input. Note that although the method name is "create", it will * in fact return a weakly-referenced canonical instance. */ - public static CallSiteDescriptor create(Lookup lookup, String name, MethodType methodType) { + public static CallSiteDescriptor create(final Lookup lookup, final String name, final MethodType methodType) { name.getClass(); // NPE check methodType.getClass(); // NPE check lookup.getClass(); // NPE check @@ -134,19 +135,28 @@ public class CallSiteDescriptorFactory { static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) { synchronized(publicDescs) { - final WeakReference ref = publicDescs.get(desc); + final Reference ref = publicDescs.get(desc); if(ref != null) { final CallSiteDescriptor canonical = ref.get(); if(canonical != null) { return canonical; } } - publicDescs.put(desc, new WeakReference<>(desc)); + publicDescs.put(desc, createReference(desc)); } return desc; } - private static CallSiteDescriptor createPublicCallSiteDescriptor(String[] tokenizedName, MethodType methodType) { + /** + * Override this to use a different kind of references for the cache + * @param desc desc + * @return reference + */ + protected static Reference createReference(final CallSiteDescriptor desc) { + return new WeakReference<>(desc); + } + + private static CallSiteDescriptor createPublicCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType) { final int l = tokenizedName.length; if(l > 0 && tokenizedName[0] == "dyn") { if(l == 2) { @@ -158,7 +168,7 @@ public class CallSiteDescriptorFactory { return new DefaultCallSiteDescriptor(tokenizedName, methodType); } - private static boolean isPublicLookup(Lookup lookup) { + private static boolean isPublicLookup(final Lookup lookup) { return lookup == MethodHandles.publicLookup(); } @@ -169,7 +179,7 @@ public class CallSiteDescriptorFactory { * @param name the composite name consisting of colon-separated, possibly mangled tokens. * @return an array of tokens */ - public static String[] tokenizeName(String name) { + public static String[] tokenizeName(final String name) { final StringTokenizer tok = new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER); final String[] tokens = new String[tok.countTokens()]; for(int i = 0; i < tokens.length; ++i) { @@ -188,7 +198,7 @@ public class CallSiteDescriptorFactory { * @param desc the call site descriptor with the operation * @return a list of tokens */ - public static List tokenizeOperators(CallSiteDescriptor desc) { + public static List tokenizeOperators(final CallSiteDescriptor desc) { final String ops = desc.getNameToken(CallSiteDescriptor.OPERATOR); final StringTokenizer tok = new StringTokenizer(ops, CallSiteDescriptor.OPERATOR_DELIMITER); final int count = tok.countTokens(); @@ -210,7 +220,7 @@ public class CallSiteDescriptorFactory { * @param end index of the first parameter to not remove * @return a new call site descriptor with modified method type */ - public static CallSiteDescriptor dropParameterTypes(CallSiteDescriptor desc, int start, int end) { + public static CallSiteDescriptor dropParameterTypes(final CallSiteDescriptor desc, final int start, final int end) { return desc.changeMethodType(desc.getMethodType().dropParameterTypes(start, end)); } @@ -222,7 +232,7 @@ public class CallSiteDescriptorFactory { * @param nptype the new parameter type * @return a new call site descriptor with modified method type */ - public static CallSiteDescriptor changeParameterType(CallSiteDescriptor desc, int num, Class nptype) { + public static CallSiteDescriptor changeParameterType(final CallSiteDescriptor desc, final int num, final Class nptype) { return desc.changeMethodType(desc.getMethodType().changeParameterType(num, nptype)); } @@ -233,7 +243,7 @@ public class CallSiteDescriptorFactory { * @param nrtype the new return type * @return a new call site descriptor with modified method type */ - public static CallSiteDescriptor changeReturnType(CallSiteDescriptor desc, Class nrtype) { + public static CallSiteDescriptor changeReturnType(final CallSiteDescriptor desc, final Class nrtype) { return desc.changeMethodType(desc.getMethodType().changeReturnType(nrtype)); } @@ -245,7 +255,7 @@ public class CallSiteDescriptorFactory { * @param ptypesToInsert the new types to insert * @return a new call site descriptor with modified method type */ - public static CallSiteDescriptor insertParameterTypes(CallSiteDescriptor desc, int num, Class... ptypesToInsert) { + public static CallSiteDescriptor insertParameterTypes(final CallSiteDescriptor desc, final int num, final Class... ptypesToInsert) { return desc.changeMethodType(desc.getMethodType().insertParameterTypes(num, ptypesToInsert)); } @@ -257,7 +267,7 @@ public class CallSiteDescriptorFactory { * @param ptypesToInsert the new types to insert * @return a new call site descriptor with modified method type */ - public static CallSiteDescriptor insertParameterTypes(CallSiteDescriptor desc, int num, List> ptypesToInsert) { + public static CallSiteDescriptor insertParameterTypes(final CallSiteDescriptor desc, final int num, final List> ptypesToInsert) { return desc.changeMethodType(desc.getMethodType().insertParameterTypes(num, ptypesToInsert)); } } diff --git a/nashorn/src/jdk/internal/dynalink/support/ClassMap.java b/nashorn/src/jdk/internal/dynalink/support/ClassMap.java index d85b21d0033..758349b857a 100644 --- a/nashorn/src/jdk/internal/dynalink/support/ClassMap.java +++ b/nashorn/src/jdk/internal/dynalink/support/ClassMap.java @@ -110,7 +110,7 @@ public abstract class ClassMap { * * @param classLoader the classloader that determines strong referenceability. */ - protected ClassMap(ClassLoader classLoader) { + protected ClassMap(final ClassLoader classLoader) { this.classLoader = classLoader; } diff --git a/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java index 44f5c4b3874..007ab98d1e8 100644 --- a/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java +++ b/nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java @@ -109,16 +109,16 @@ public class CompositeGuardingDynamicLinker implements GuardingDynamicLinker, Se * * @param linkers a list of component linkers. */ - public CompositeGuardingDynamicLinker(Iterable linkers) { + public CompositeGuardingDynamicLinker(final Iterable linkers) { final List l = new LinkedList<>(); - for(GuardingDynamicLinker linker: linkers) { + for(final GuardingDynamicLinker linker: linkers) { l.add(linker); } this.linkers = l.toArray(new GuardingDynamicLinker[l.size()]); } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, final LinkerServices linkerServices) + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { for(final GuardingDynamicLinker linker: linkers) { final GuardedInvocation invocation = linker.getGuardedInvocation(linkRequest, linkerServices); diff --git a/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java b/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java index 180ab0c6b1a..814fc6936bf 100644 --- a/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java +++ b/nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java @@ -112,7 +112,7 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin private final List[] singletonLinkers; @SuppressWarnings("unchecked") - ClassToLinker(TypeBasedGuardingDynamicLinker[] linkers) { + ClassToLinker(final TypeBasedGuardingDynamicLinker[] linkers) { this.linkers = linkers; singletonLinkers = new List[linkers.length]; for(int i = 0; i < linkers.length; ++i) { @@ -121,7 +121,7 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin } @Override - protected List computeValue(Class clazz) { + protected List computeValue(final Class clazz) { List list = NO_LINKER; for(int i = 0; i < linkers.length; ++i) { final TypeBasedGuardingDynamicLinker linker = linkers[i]; @@ -152,27 +152,27 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin * * @param linkers the component linkers */ - public CompositeTypeBasedGuardingDynamicLinker(Iterable linkers) { + public CompositeTypeBasedGuardingDynamicLinker(final Iterable linkers) { final List l = new LinkedList<>(); - for(TypeBasedGuardingDynamicLinker linker: linkers) { + for(final TypeBasedGuardingDynamicLinker linker: linkers) { l.add(linker); } this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()])); } @Override - public boolean canLinkType(Class type) { + public boolean canLinkType(final Class type) { return !classToLinker.get(type).isEmpty(); } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, final LinkerServices linkerServices) + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { final Object obj = linkRequest.getReceiver(); if(obj == null) { return null; } - for(TypeBasedGuardingDynamicLinker linker: classToLinker.get(obj.getClass())) { + for(final TypeBasedGuardingDynamicLinker linker: classToLinker.get(obj.getClass())) { final GuardedInvocation invocation = linker.getGuardedInvocation(linkRequest, linkerServices); if(invocation != null) { return invocation; @@ -189,10 +189,10 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin * @param linkers the list of linkers to optimize * @return the optimized list */ - public static List optimize(Iterable linkers) { + public static List optimize(final Iterable linkers) { final List llinkers = new LinkedList<>(); final List tblinkers = new LinkedList<>(); - for(GuardingDynamicLinker linker: linkers) { + for(final GuardingDynamicLinker linker: linkers) { if(linker instanceof TypeBasedGuardingDynamicLinker) { tblinkers.add((TypeBasedGuardingDynamicLinker)linker); } else { @@ -204,8 +204,8 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin return llinkers; } - private static void addTypeBased(List llinkers, - List tblinkers) { + private static void addTypeBased(final List llinkers, + final List tblinkers) { switch(tblinkers.size()) { case 0: { break; diff --git a/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java index 46d4fc8bba9..878d9aa00c2 100644 --- a/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java +++ b/nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java @@ -98,7 +98,7 @@ class DefaultCallSiteDescriptor extends AbstractCallSiteDescriptor { private final String[] tokenizedName; private final MethodType methodType; - DefaultCallSiteDescriptor(String[] tokenizedName, MethodType methodType) { + DefaultCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType) { this.tokenizedName = tokenizedName; this.methodType = methodType; } @@ -109,10 +109,10 @@ class DefaultCallSiteDescriptor extends AbstractCallSiteDescriptor { } @Override - public String getNameToken(int i) { + public String getNameToken(final int i) { try { return tokenizedName[i]; - } catch(ArrayIndexOutOfBoundsException e) { + } catch(final ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException(e.getMessage()); } } @@ -127,7 +127,7 @@ class DefaultCallSiteDescriptor extends AbstractCallSiteDescriptor { } @Override - public CallSiteDescriptor changeMethodType(MethodType newMethodType) { + public CallSiteDescriptor changeMethodType(final MethodType newMethodType) { return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new DefaultCallSiteDescriptor(tokenizedName, newMethodType)); } diff --git a/nashorn/src/jdk/internal/dynalink/support/DefaultPrelinkFilter.java b/nashorn/src/jdk/internal/dynalink/support/DefaultPrelinkFilter.java new file mode 100644 index 00000000000..ad9679f6643 --- /dev/null +++ b/nashorn/src/jdk/internal/dynalink/support/DefaultPrelinkFilter.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package jdk.internal.dynalink.support; + +import jdk.internal.dynalink.GuardedInvocationFilter; +import jdk.internal.dynalink.linker.GuardedInvocation; +import jdk.internal.dynalink.linker.LinkRequest; +import jdk.internal.dynalink.linker.LinkerServices; + +/** + * Default filter for guarded invocation pre link filtering + */ +public class DefaultPrelinkFilter implements GuardedInvocationFilter { + @Override + public GuardedInvocation filter(final GuardedInvocation inv, final LinkRequest request, final LinkerServices linkerServices) { + return inv.asType(linkerServices, request.getCallSiteDescriptor().getMethodType()); + } +} diff --git a/nashorn/src/jdk/internal/dynalink/support/Guards.java b/nashorn/src/jdk/internal/dynalink/support/Guards.java index 42aa675880a..02f3045daff 100644 --- a/nashorn/src/jdk/internal/dynalink/support/Guards.java +++ b/nashorn/src/jdk/internal/dynalink/support/Guards.java @@ -113,7 +113,7 @@ public class Guards { * @return a method handle testing whether its first argument is of the specified class. */ @SuppressWarnings("boxing") - public static MethodHandle isOfClass(Class clazz, MethodType type) { + public static MethodHandle isOfClass(final Class clazz, final MethodType type) { final Class declaredType = type.parameterType(0); if(clazz == declaredType) { LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type, DynamicLinker.getLinkedCallSiteLocation() }); @@ -135,7 +135,7 @@ public class Guards { * @param type the method type * @return a method handle testing whether its first argument is of the specified class or subclass. */ - public static MethodHandle isInstance(Class clazz, MethodType type) { + public static MethodHandle isInstance(final Class clazz, final MethodType type) { return isInstance(clazz, 0, type); } @@ -150,7 +150,7 @@ public class Guards { * @return a method handle testing whether its first argument is of the specified class or subclass. */ @SuppressWarnings("boxing") - public static MethodHandle isInstance(Class clazz, int pos, MethodType type) { + public static MethodHandle isInstance(final Class clazz, final int pos, final MethodType type) { final Class declaredType = type.parameterType(pos); if(clazz.isAssignableFrom(declaredType)) { LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type, DynamicLinker.getLinkedCallSiteLocation() }); @@ -172,7 +172,7 @@ public class Guards { * the arguments are ignored. */ @SuppressWarnings("boxing") - public static MethodHandle isArray(int pos, MethodType type) { + public static MethodHandle isArray(final int pos, final MethodType type) { final Class declaredType = type.parameterType(pos); if(declaredType.isArray()) { LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type, DynamicLinker.getLinkedCallSiteLocation() }); @@ -193,7 +193,7 @@ public class Guards { * @param referredLoader the referred class loader * @return true if it is safe to strongly reference the class */ - public static boolean canReferenceDirectly(ClassLoader referrerLoader, final ClassLoader referredLoader) { + public static boolean canReferenceDirectly(final ClassLoader referrerLoader, final ClassLoader referredLoader) { if(referredLoader == null) { // Can always refer directly to a system class return true; @@ -215,7 +215,7 @@ public class Guards { return false; } - private static MethodHandle getClassBoundArgumentTest(MethodHandle test, Class clazz, int pos, MethodType type) { + private static MethodHandle getClassBoundArgumentTest(final MethodHandle test, final Class clazz, final int pos, final MethodType type) { // Bind the class to the first argument of the test return asType(test.bindTo(clazz), pos, type); } @@ -227,7 +227,7 @@ public class Guards { * @param type the type to adapt the method handle to * @return the adapted method handle */ - public static MethodHandle asType(MethodHandle test, MethodType type) { + public static MethodHandle asType(final MethodHandle test, final MethodType type) { return test.asType(getTestType(test, type)); } @@ -239,16 +239,16 @@ public class Guards { * @param type the type to adapt the method handle to * @return the adapted method handle */ - public static MethodHandle asType(LinkerServices linkerServices, MethodHandle test, MethodType type) { + public static MethodHandle asType(final LinkerServices linkerServices, final MethodHandle test, final MethodType type) { return linkerServices.asType(test, getTestType(test, type)); } - private static MethodType getTestType(MethodHandle test, MethodType type) { + private static MethodType getTestType(final MethodHandle test, final MethodType type) { return type.dropParameterTypes(test.type().parameterCount(), type.parameterCount()).changeReturnType(boolean.class); } - private static MethodHandle asType(MethodHandle test, int pos, MethodType type) { + private static MethodHandle asType(final MethodHandle test, final int pos, final MethodType type) { assert test != null; assert type != null; assert type.parameterCount() > 0; @@ -283,7 +283,7 @@ public class Guards { * @param clazz the class to test for. * @return the desired guard method. */ - public static MethodHandle getClassGuard(Class clazz) { + public static MethodHandle getClassGuard(final Class clazz) { return IS_OF_CLASS.bindTo(clazz); } @@ -292,7 +292,7 @@ public class Guards { * @param clazz the class to test for. * @return the desired guard method. */ - public static MethodHandle getInstanceOfGuard(Class clazz) { + public static MethodHandle getInstanceOfGuard(final Class clazz) { return IS_INSTANCE.bindTo(clazz); } @@ -301,7 +301,7 @@ public class Guards { * @param obj the object used as referential identity test * @return the desired guard method. */ - public static MethodHandle getIdentityGuard(Object obj) { + public static MethodHandle getIdentityGuard(final Object obj) { return IS_IDENTICAL.bindTo(obj); } @@ -322,39 +322,39 @@ public class Guards { } @SuppressWarnings("unused") - private static boolean isNull(Object obj) { + private static boolean isNull(final Object obj) { return obj == null; } @SuppressWarnings("unused") - private static boolean isNotNull(Object obj) { + private static boolean isNotNull(final Object obj) { return obj != null; } @SuppressWarnings("unused") - private static boolean isArray(Object o) { + private static boolean isArray(final Object o) { return o != null && o.getClass().isArray(); } @SuppressWarnings("unused") - private static boolean isOfClass(Class c, Object o) { + private static boolean isOfClass(final Class c, final Object o) { return o != null && o.getClass() == c; } @SuppressWarnings("unused") - private static boolean isIdentical(Object o1, Object o2) { + private static boolean isIdentical(final Object o1, final Object o2) { return o1 == o2; } - private static MethodHandle constantTrue(MethodType type) { + private static MethodHandle constantTrue(final MethodType type) { return constantBoolean(Boolean.TRUE, type); } - private static MethodHandle constantFalse(MethodType type) { + private static MethodHandle constantFalse(final MethodType type) { return constantBoolean(Boolean.FALSE, type); } - private static MethodHandle constantBoolean(Boolean value, MethodType type) { + private static MethodHandle constantBoolean(final Boolean value, final MethodType type) { return MethodHandles.permuteArguments(MethodHandles.constant(Boolean.TYPE, value), type.changeReturnType(Boolean.TYPE)); } diff --git a/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java b/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java index c2b0092bf99..2d4c0b1822c 100644 --- a/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java +++ b/nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java @@ -95,18 +95,24 @@ import jdk.internal.dynalink.linker.LinkRequest; public class LinkRequestImpl implements LinkRequest { private final CallSiteDescriptor callSiteDescriptor; + private final Object callSiteToken; private final Object[] arguments; private final boolean callSiteUnstable; + private final int linkCount; /** * Creates a new link request. * * @param callSiteDescriptor the descriptor for the call site being linked + * @param callSiteToken the opaque token for the call site being linked. + * @param linkCount how many times this callsite has been linked/relinked * @param callSiteUnstable true if the call site being linked is considered unstable * @param arguments the arguments for the invocation */ - public LinkRequestImpl(CallSiteDescriptor callSiteDescriptor, boolean callSiteUnstable, Object... arguments) { + public LinkRequestImpl(final CallSiteDescriptor callSiteDescriptor, final Object callSiteToken, final int linkCount, final boolean callSiteUnstable, final Object... arguments) { this.callSiteDescriptor = callSiteDescriptor; + this.callSiteToken = callSiteToken; + this.linkCount = linkCount; this.callSiteUnstable = callSiteUnstable; this.arguments = arguments; } @@ -126,18 +132,28 @@ public class LinkRequestImpl implements LinkRequest { return callSiteDescriptor; } + @Override + public Object getCallSiteToken() { + return callSiteToken; + } + @Override public boolean isCallSiteUnstable() { return callSiteUnstable; } + @Override + public int getLinkCount() { + return linkCount; + } + @Override public LinkRequest withoutRuntimeContext() { return this; } @Override - public LinkRequest replaceArguments(CallSiteDescriptor newCallSiteDescriptor, Object[] newArguments) { - return new LinkRequestImpl(newCallSiteDescriptor, callSiteUnstable, newArguments); + public LinkRequest replaceArguments(final CallSiteDescriptor newCallSiteDescriptor, final Object[] newArguments) { + return new LinkRequestImpl(newCallSiteDescriptor, callSiteToken, linkCount, callSiteUnstable, newArguments); } } diff --git a/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java b/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java index 3b8e7b46abe..38d93c849c1 100644 --- a/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java +++ b/nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java @@ -117,27 +117,32 @@ public class LinkerServicesImpl implements LinkerServices { } @Override - public boolean canConvert(Class from, Class to) { + public boolean canConvert(final Class from, final Class to) { return typeConverterFactory.canConvert(from, to); } @Override - public MethodHandle asType(MethodHandle handle, MethodType fromType) { + public MethodHandle asType(final MethodHandle handle, final MethodType fromType) { return typeConverterFactory.asType(handle, fromType); } @Override - public MethodHandle getTypeConverter(Class sourceType, Class targetType) { + public MethodHandle asTypeLosslessReturn(final MethodHandle handle, final MethodType fromType) { + return Implementation.asTypeLosslessReturn(this, handle, fromType); + } + + @Override + public MethodHandle getTypeConverter(final Class sourceType, final Class targetType) { return typeConverterFactory.getTypeConverter(sourceType, targetType); } @Override - public Comparison compareConversion(Class sourceType, Class targetType1, Class targetType2) { + public Comparison compareConversion(final Class sourceType, final Class targetType1, final Class targetType2) { return typeConverterFactory.compareConversion(sourceType, targetType1, targetType2); } @Override - public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest) throws Exception { + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception { final LinkRequest prevLinkRequest = threadLinkRequest.get(); threadLinkRequest.set(linkRequest); try { @@ -154,7 +159,7 @@ public class LinkerServicesImpl implements LinkerServices { * permission. */ public static LinkRequest getCurrentLinkRequest() { - SecurityManager sm = System.getSecurityManager(); + final SecurityManager sm = System.getSecurityManager(); if(sm != null) { sm.checkPermission(GET_CURRENT_LINK_REQUEST); } diff --git a/nashorn/src/jdk/internal/dynalink/support/Lookup.java b/nashorn/src/jdk/internal/dynalink/support/Lookup.java index ba4ff77c6f3..ab64ebb1e5c 100644 --- a/nashorn/src/jdk/internal/dynalink/support/Lookup.java +++ b/nashorn/src/jdk/internal/dynalink/support/Lookup.java @@ -104,7 +104,7 @@ public class Lookup { * * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} it delegates to. */ - public Lookup(MethodHandles.Lookup lookup) { + public Lookup(final MethodHandles.Lookup lookup) { this.lookup = lookup; } @@ -120,7 +120,7 @@ public class Lookup { * @param m the method to unreflect * @return the unreflected method handle. */ - public MethodHandle unreflect(Method m) { + public MethodHandle unreflect(final Method m) { return unreflect(lookup, m); } @@ -132,10 +132,10 @@ public class Lookup { * @param m the method to unreflect * @return the unreflected method handle. */ - public static MethodHandle unreflect(MethodHandles.Lookup lookup, Method m) { + public static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) { try { return lookup.unreflect(m); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect method " + m); ee.initCause(e); throw ee; @@ -149,10 +149,10 @@ public class Lookup { * @param f the field for which a getter is unreflected * @return the unreflected field getter handle. */ - public MethodHandle unreflectGetter(Field f) { + public MethodHandle unreflectGetter(final Field f) { try { return lookup.unreflectGetter(f); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect getter for field " + f); ee.initCause(e); throw ee; @@ -171,15 +171,15 @@ public class Lookup { * @throws IllegalAccessError if the field is inaccessible. * @throws NoSuchFieldError if the field does not exist. */ - public MethodHandle findGetter(Classrefc, String name, Class type) { + public MethodHandle findGetter(final Classrefc, final String name, final Class type) { try { return lookup.findGetter(refc, name, type); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to access getter for field " + refc.getName() + "." + name + " of type " + type.getName()); ee.initCause(e); throw ee; - } catch(NoSuchFieldException e) { + } catch(final NoSuchFieldException e) { final NoSuchFieldError ee = new NoSuchFieldError("Failed to find getter for field " + refc.getName() + "." + name + " of type " + type.getName()); ee.initCause(e); @@ -194,10 +194,10 @@ public class Lookup { * @param f the field for which a setter is unreflected * @return the unreflected field setter handle. */ - public MethodHandle unreflectSetter(Field f) { + public MethodHandle unreflectSetter(final Field f) { try { return lookup.unreflectSetter(f); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect setter for field " + f); ee.initCause(e); throw ee; @@ -211,7 +211,7 @@ public class Lookup { * @param c the constructor to unreflect * @return the unreflected constructor handle. */ - public MethodHandle unreflectConstructor(Constructor c) { + public MethodHandle unreflectConstructor(final Constructor c) { return unreflectConstructor(lookup, c); } @@ -223,10 +223,10 @@ public class Lookup { * @param c the constructor to unreflect * @return the unreflected constructor handle. */ - public static MethodHandle unreflectConstructor(MethodHandles.Lookup lookup, Constructor c) { + public static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor c) { try { return lookup.unreflectConstructor(c); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect constructor " + c); ee.initCause(e); throw ee; @@ -244,15 +244,15 @@ public class Lookup { * @throws IllegalAccessError if the method is inaccessible. * @throws NoSuchMethodError if the method does not exist. */ - public MethodHandle findSpecial(Class declaringClass, String name, MethodType type) { + public MethodHandle findSpecial(final Class declaringClass, final String name, final MethodType type) { try { return lookup.findSpecial(declaringClass, name, type, declaringClass); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription( declaringClass, name, type)); ee.initCause(e); throw ee; - } catch(NoSuchMethodException e) { + } catch(final NoSuchMethodException e) { final NoSuchMethodError ee = new NoSuchMethodError("Failed to find special method " + methodDescription( declaringClass, name, type)); ee.initCause(e); @@ -260,7 +260,7 @@ public class Lookup { } } - private static String methodDescription(Class declaringClass, String name, MethodType type) { + private static String methodDescription(final Class declaringClass, final String name, final MethodType type) { return declaringClass.getName() + "#" + name + type; } @@ -275,15 +275,15 @@ public class Lookup { * @throws IllegalAccessError if the method is inaccessible. * @throws NoSuchMethodError if the method does not exist. */ - public MethodHandle findStatic(Class declaringClass, String name, MethodType type) { + public MethodHandle findStatic(final Class declaringClass, final String name, final MethodType type) { try { return lookup.findStatic(declaringClass, name, type); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to access static method " + methodDescription( declaringClass, name, type)); ee.initCause(e); throw ee; - } catch(NoSuchMethodException e) { + } catch(final NoSuchMethodException e) { final NoSuchMethodError ee = new NoSuchMethodError("Failed to find static method " + methodDescription( declaringClass, name, type)); ee.initCause(e); @@ -302,15 +302,15 @@ public class Lookup { * @throws IllegalAccessError if the method is inaccessible. * @throws NoSuchMethodError if the method does not exist. */ - public MethodHandle findVirtual(Class declaringClass, String name, MethodType type) { + public MethodHandle findVirtual(final Class declaringClass, final String name, final MethodType type) { try { return lookup.findVirtual(declaringClass, name, type); - } catch(IllegalAccessException e) { + } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to access virtual method " + methodDescription( declaringClass, name, type)); ee.initCause(e); throw ee; - } catch(NoSuchMethodException e) { + } catch(final NoSuchMethodException e) { final NoSuchMethodError ee = new NoSuchMethodError("Failed to find virtual method " + methodDescription( declaringClass, name, type)); ee.initCause(e); @@ -327,7 +327,7 @@ public class Lookup { * @param ptypes the parameter types of the method * @return the method handle for the method */ - public static MethodHandle findOwnSpecial(MethodHandles.Lookup lookup, String name, Class rtype, Class... ptypes) { + public static MethodHandle findOwnSpecial(final MethodHandles.Lookup lookup, final String name, final Class rtype, final Class... ptypes) { return new Lookup(lookup).findOwnSpecial(name, rtype, ptypes); } @@ -341,7 +341,7 @@ public class Lookup { * @param ptypes the parameter types of the method * @return the method handle for the method */ - public MethodHandle findOwnSpecial(String name, Class rtype, Class... ptypes) { + public MethodHandle findOwnSpecial(final String name, final Class rtype, final Class... ptypes) { return findSpecial(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes)); } @@ -355,7 +355,7 @@ public class Lookup { * @param ptypes the parameter types of the method * @return the method handle for the method */ - public static MethodHandle findOwnStatic(MethodHandles.Lookup lookup, String name, Class rtype, Class... ptypes) { + public static MethodHandle findOwnStatic(final MethodHandles.Lookup lookup, final String name, final Class rtype, final Class... ptypes) { return new Lookup(lookup).findOwnStatic(name, rtype, ptypes); } @@ -368,7 +368,7 @@ public class Lookup { * @param ptypes the parameter types of the method * @return the method handle for the method */ - public MethodHandle findOwnStatic(String name, Class rtype, Class... ptypes) { + public MethodHandle findOwnStatic(final String name, final Class rtype, final Class... ptypes) { return findStatic(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes)); } } diff --git a/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java index bc5521bbfc7..e04321e6da3 100644 --- a/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java +++ b/nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java @@ -92,7 +92,7 @@ import jdk.internal.dynalink.CallSiteDescriptor; * @author Attila Szegedi */ class LookupCallSiteDescriptor extends DefaultCallSiteDescriptor { - private Lookup lookup; + private final Lookup lookup; /** * Create a new call site descriptor from explicit information. @@ -100,7 +100,7 @@ class LookupCallSiteDescriptor extends DefaultCallSiteDescriptor { * @param methodType the method type * @param lookup the lookup */ - LookupCallSiteDescriptor(String[] tokenizedName, MethodType methodType, Lookup lookup) { + LookupCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType, final Lookup lookup) { super(tokenizedName, methodType); this.lookup = lookup; } @@ -111,7 +111,7 @@ class LookupCallSiteDescriptor extends DefaultCallSiteDescriptor { } @Override - public CallSiteDescriptor changeMethodType(MethodType newMethodType) { + public CallSiteDescriptor changeMethodType(final MethodType newMethodType) { return new LookupCallSiteDescriptor(getTokenizedName(), newMethodType, lookup); } } diff --git a/nashorn/src/jdk/internal/dynalink/support/NameCodec.java b/nashorn/src/jdk/internal/dynalink/support/NameCodec.java index 1c7cd29b95f..9a402a59825 100644 --- a/nashorn/src/jdk/internal/dynalink/support/NameCodec.java +++ b/nashorn/src/jdk/internal/dynalink/support/NameCodec.java @@ -137,7 +137,7 @@ public class NameCodec { * @param name the symbolic name to mangle * @return the mangled form of the symbolic name. */ - public static String encode(String name) { + public static String encode(final String name) { final int l = name.length(); if(l == 0) { return EMPTY_NAME; @@ -176,7 +176,7 @@ public class NameCodec { * @param name the symbolic name to demangle * @return the demangled form of the symbolic name. */ - public static String decode(String name) { + public static String decode(final String name) { if(name.charAt(0) != ESCAPE_CHAR) { return name; } @@ -184,11 +184,11 @@ public class NameCodec { if(l == 2 && name.charAt(1) == EMPTY_CHAR) { return ""; } - StringBuilder b = new StringBuilder(name.length()); + final StringBuilder b = new StringBuilder(name.length()); int lastEscape = -2; int lastBackslash = -1; for(;;) { - int nextBackslash = name.indexOf(ESCAPE_CHAR, lastBackslash + 1); + final int nextBackslash = name.indexOf(ESCAPE_CHAR, lastBackslash + 1); if(nextBackslash == -1 || nextBackslash == l - 1) { break; } @@ -211,7 +211,7 @@ public class NameCodec { return b.toString(); } - private static void addEncoding(char from, char to) { + private static void addEncoding(final char from, final char to) { ENCODING[from - MIN_ENCODING] = to; DECODING[to - MIN_DECODING] = from; } diff --git a/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java index 71cbb1d299e..817df52a899 100644 --- a/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java +++ b/nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java @@ -89,7 +89,7 @@ import jdk.internal.dynalink.CallSiteDescriptor; class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor { private final String name; - NamedDynCallSiteDescriptor(String op, String name, MethodType methodType) { + NamedDynCallSiteDescriptor(final String op, final String name, final MethodType methodType) { super(op, methodType); this.name = name; } @@ -100,7 +100,7 @@ class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor { } @Override - public String getNameToken(int i) { + public String getNameToken(final int i) { switch(i) { case 0: return "dyn"; case 1: return getOp(); @@ -110,7 +110,7 @@ class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor { } @Override - public CallSiteDescriptor changeMethodType(MethodType newMethodType) { + public CallSiteDescriptor changeMethodType(final MethodType newMethodType) { return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new NamedDynCallSiteDescriptor(getOp(), name, newMethodType)); } diff --git a/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java b/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java index 03309a7c26a..3f43621a13e 100644 --- a/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java +++ b/nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java @@ -101,15 +101,17 @@ public class RuntimeContextLinkRequestImpl extends LinkRequestImpl { * Creates a new link request. * * @param callSiteDescriptor the descriptor for the call site being linked + * @param callSiteToken the opaque token for the call site being linked. * @param arguments the arguments for the invocation + * @param linkCount number of times callsite has been linked/relinked * @param callSiteUnstable true if the call site being linked is considered unstable * @param runtimeContextArgCount the number of the leading arguments on the stack that represent the language * runtime specific context arguments. * @throws IllegalArgumentException if runtimeContextArgCount is less than 1. */ - public RuntimeContextLinkRequestImpl(CallSiteDescriptor callSiteDescriptor, boolean callSiteUnstable, - Object[] arguments, int runtimeContextArgCount) { - super(callSiteDescriptor, callSiteUnstable, arguments); + public RuntimeContextLinkRequestImpl(final CallSiteDescriptor callSiteDescriptor, final Object callSiteToken, + final int linkCount, final boolean callSiteUnstable, final Object[] arguments, final int runtimeContextArgCount) { + super(callSiteDescriptor, callSiteToken, linkCount, callSiteUnstable, arguments); if(runtimeContextArgCount < 1) { throw new IllegalArgumentException("runtimeContextArgCount < 1"); } @@ -121,14 +123,14 @@ public class RuntimeContextLinkRequestImpl extends LinkRequestImpl { if(contextStrippedRequest == null) { contextStrippedRequest = new LinkRequestImpl(CallSiteDescriptorFactory.dropParameterTypes(getCallSiteDescriptor(), 1, - runtimeContextArgCount + 1), isCallSiteUnstable(), getTruncatedArguments()); + runtimeContextArgCount + 1), getCallSiteToken(), getLinkCount(), isCallSiteUnstable(), getTruncatedArguments()); } return contextStrippedRequest; } @Override - public LinkRequest replaceArguments(CallSiteDescriptor callSiteDescriptor, Object[] arguments) { - return new RuntimeContextLinkRequestImpl(callSiteDescriptor, isCallSiteUnstable(), arguments, + public LinkRequest replaceArguments(final CallSiteDescriptor callSiteDescriptor, final Object[] arguments) { + return new RuntimeContextLinkRequestImpl(callSiteDescriptor, getCallSiteToken(), getLinkCount(), isCallSiteUnstable(), arguments, runtimeContextArgCount); } diff --git a/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java b/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java index 436acad7faf..79f6549b3b7 100644 --- a/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java +++ b/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java @@ -115,12 +115,12 @@ public class TypeConverterFactory { protected ClassMap computeValue(final Class sourceType) { return new ClassMap(getClassLoader(sourceType)) { @Override - protected MethodHandle computeValue(Class targetType) { + protected MethodHandle computeValue(final Class targetType) { try { return createConverter(sourceType, targetType); - } catch (RuntimeException e) { + } catch (final RuntimeException e) { throw e; - } catch (Exception e) { + } catch (final Exception e) { throw new RuntimeException(e); } } @@ -133,7 +133,7 @@ public class TypeConverterFactory { protected ClassMap computeValue(final Class sourceType) { return new ClassMap(getClassLoader(sourceType)) { @Override - protected MethodHandle computeValue(Class targetType) { + protected MethodHandle computeValue(final Class targetType) { if(!canAutoConvert(sourceType, targetType)) { final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType); if(converter != IDENTITY_CONVERSION) { @@ -151,12 +151,12 @@ public class TypeConverterFactory { protected ClassMap computeValue(final Class sourceType) { return new ClassMap(getClassLoader(sourceType)) { @Override - protected Boolean computeValue(Class targetType) { + protected Boolean computeValue(final Class targetType) { try { return getTypeConverterNull(sourceType, targetType) != null; - } catch (RuntimeException e) { + } catch (final RuntimeException e) { throw e; - } catch (Exception e) { + } catch (final Exception e) { throw new RuntimeException(e); } } @@ -178,10 +178,10 @@ public class TypeConverterFactory { * * @param factories the {@link GuardingTypeConverterFactory} instances to compose. */ - public TypeConverterFactory(Iterable factories) { + public TypeConverterFactory(final Iterable factories) { final List l = new LinkedList<>(); final List c = new LinkedList<>(); - for(GuardingTypeConverterFactory factory: factories) { + for(final GuardingTypeConverterFactory factory: factories) { l.add(factory); if(factory instanceof ConversionComparator) { c.add((ConversionComparator)factory); @@ -206,7 +206,7 @@ public class TypeConverterFactory { * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with * {@link GuardingTypeConverterFactory} produced type converters as filters. */ - public MethodHandle asType(MethodHandle handle, final MethodType fromType) { + public MethodHandle asType(final MethodHandle handle, final MethodType fromType) { MethodHandle newHandle = handle; final MethodType toType = newHandle.type(); final int l = toType.parameterCount(); @@ -250,7 +250,7 @@ public class TypeConverterFactory { return newHandle.asType(fromType); } - private static MethodHandle applyConverters(MethodHandle handle, int pos, List converters) { + private static MethodHandle applyConverters(final MethodHandle handle, final int pos, final List converters) { if(converters.isEmpty()) { return handle; } @@ -285,8 +285,8 @@ public class TypeConverterFactory { * @return one of Comparison constants that establish which - if any - of the target types is preferable for the * conversion. */ - public Comparison compareConversion(Class sourceType, Class targetType1, Class targetType2) { - for(ConversionComparator comparator: comparators) { + public Comparison compareConversion(final Class sourceType, final Class targetType1, final Class targetType2) { + for(final ConversionComparator comparator: comparators) { final Comparison result = comparator.compareConversion(sourceType, targetType1, targetType2); if(result != Comparison.INDETERMINATE) { return result; @@ -313,20 +313,20 @@ public class TypeConverterFactory { return TypeUtilities.isMethodInvocationConvertible(fromType, toType); } - /*private*/ MethodHandle getCacheableTypeConverterNull(Class sourceType, Class targetType) { + /*private*/ MethodHandle getCacheableTypeConverterNull(final Class sourceType, final Class targetType) { final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType); return converter == IDENTITY_CONVERSION ? null : converter; } - /*private*/ MethodHandle getTypeConverterNull(Class sourceType, Class targetType) { + /*private*/ MethodHandle getTypeConverterNull(final Class sourceType, final Class targetType) { try { return getCacheableTypeConverterNull(sourceType, targetType); - } catch(NotCacheableConverter e) { + } catch(final NotCacheableConverter e) { return e.converter; } } - /*private*/ MethodHandle getCacheableTypeConverter(Class sourceType, Class targetType) { + /*private*/ MethodHandle getCacheableTypeConverter(final Class sourceType, final Class targetType) { return converterMap.get(sourceType).get(targetType); } @@ -339,15 +339,15 @@ public class TypeConverterFactory { * @param targetType the type to convert to * @return a method handle performing the conversion. */ - public MethodHandle getTypeConverter(Class sourceType, Class targetType) { + public MethodHandle getTypeConverter(final Class sourceType, final Class targetType) { try { return converterIdentityMap.get(sourceType).get(targetType); - } catch(NotCacheableConverter e) { + } catch(final NotCacheableConverter e) { return e.converter; } } - /*private*/ MethodHandle createConverter(Class sourceType, Class targetType) throws Exception { + /*private*/ MethodHandle createConverter(final Class sourceType, final Class targetType) throws Exception { final MethodType type = MethodType.methodType(targetType, sourceType); final MethodHandle identity = IDENTITY_CONVERSION.asType(type); MethodHandle last = identity; @@ -372,6 +372,7 @@ public class TypeConverterFactory { /*private*/ static final MethodHandle IDENTITY_CONVERSION = MethodHandles.identity(Object.class); + @SuppressWarnings("serial") private static class NotCacheableConverter extends RuntimeException { final MethodHandle converter; diff --git a/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java b/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java index 57fea990efa..6403f3d5e40 100644 --- a/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java +++ b/nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java @@ -106,38 +106,49 @@ public class TypeUtilities { } /** - * Given two types represented by c1 and c2, returns a type that is their most specific common superclass or - * superinterface. + * Given two types represented by c1 and c2, returns a type that is their most specific common supertype for + * purposes of lossless conversions. * * @param c1 one type * @param c2 another type - * @return their most common superclass or superinterface. If they have several unrelated superinterfaces as their - * most specific common type, or the types themselves are completely unrelated interfaces, {@link java.lang.Object} - * is returned. + * @return their most common superclass or superinterface for purposes of lossless conversions. If they have several + * unrelated superinterfaces as their most specific common type, or the types themselves are completely + * unrelated interfaces, {@link java.lang.Object} is returned. */ - public static Class getMostSpecificCommonType(Class c1, Class c2) { + public static Class getCommonLosslessConversionType(final Class c1, final Class c2) { if(c1 == c2) { return c1; + } else if(isConvertibleWithoutLoss(c2, c1)) { + return c1; + } else if(isConvertibleWithoutLoss(c1, c2)) { + return c2; } - Class c3 = c2; - if(c3.isPrimitive()) { - if(c3 == Byte.TYPE) - c3 = Byte.class; - else if(c3 == Short.TYPE) - c3 = Short.class; - else if(c3 == Character.TYPE) - c3 = Character.class; - else if(c3 == Integer.TYPE) - c3 = Integer.class; - else if(c3 == Float.TYPE) - c3 = Float.class; - else if(c3 == Long.TYPE) - c3 = Long.class; - else if(c3 == Double.TYPE) - c3 = Double.class; + if(c1 == void.class) { + return c2; + } else if(c2 == void.class) { + return c1; } - Set> a1 = getAssignables(c1, c3); - Set> a2 = getAssignables(c3, c1); + if(c1.isPrimitive() && c2.isPrimitive()) { + if((c1 == byte.class && c2 == char.class) || (c1 == char.class && c2 == byte.class)) { + // byte + char = int + return int.class; + } else if((c1 == short.class && c2 == char.class) || (c1 == char.class && c2 == short.class)) { + // short + char = int + return int.class; + } else if((c1 == int.class && c2 == float.class) || (c1 == float.class && c2 == int.class)) { + // int + float = double + return double.class; + } + } + // For all other cases. This will handle long + (float|double) = Number case as well as boolean + anything = Object case too. + return getMostSpecificCommonTypeUnequalNonprimitives(c1, c2); + } + + private static Class getMostSpecificCommonTypeUnequalNonprimitives(final Class c1, final Class c2) { + final Class npc1 = c1.isPrimitive() ? getWrapperType(c1) : c1; + final Class npc2 = c2.isPrimitive() ? getWrapperType(c2) : c2; + final Set> a1 = getAssignables(npc1, npc2); + final Set> a2 = getAssignables(npc2, npc1); a1.retainAll(a2); if(a1.isEmpty()) { // Can happen when at least one of the arguments is an interface, @@ -148,10 +159,10 @@ public class TypeUtilities { // thank to interfaces. I.e., if you call this method for String.class // and Number.class, you'll have Comparable, Serializable, and Object // as maximal elements. - List> max = new ArrayList<>(); - outer: for(Class clazz: a1) { - for(Iterator> maxiter = max.iterator(); maxiter.hasNext();) { - Class maxClazz = maxiter.next(); + final List> max = new ArrayList<>(); + outer: for(final Class clazz: a1) { + for(final Iterator> maxiter = max.iterator(); maxiter.hasNext();) { + final Class maxClazz = maxiter.next(); if(isSubtype(maxClazz, clazz)) { // It can't be maximal, if there's already a more specific // maximal than it. @@ -168,26 +179,26 @@ public class TypeUtilities { max.add(clazz); } if(max.size() > 1) { - return OBJECT_CLASS; + return Object.class; } return max.get(0); } - private static Set> getAssignables(Class c1, Class c2) { - Set> s = new HashSet<>(); + private static Set> getAssignables(final Class c1, final Class c2) { + final Set> s = new HashSet<>(); collectAssignables(c1, c2, s); return s; } - private static void collectAssignables(Class c1, Class c2, Set> s) { + private static void collectAssignables(final Class c1, final Class c2, final Set> s) { if(c1.isAssignableFrom(c2)) { s.add(c1); } - Class sc = c1.getSuperclass(); + final Class sc = c1.getSuperclass(); if(sc != null) { collectAssignables(sc, c2, s); } - Class[] itf = c1.getInterfaces(); + final Class[] itf = c1.getInterfaces(); for(int i = 0; i < itf.length; ++i) { collectAssignables(itf[i], c2, s); } @@ -210,17 +221,17 @@ public class TypeUtilities { return Collections.unmodifiableMap(wrapperTypes); } - private static Map> createClassNameMapping(Collection> classes) { + private static Map> createClassNameMapping(final Collection> classes) { final Map> map = new HashMap<>(); - for(Class clazz: classes) { + for(final Class clazz: classes) { map.put(clazz.getName(), clazz); } return map; } - private static Map invertMap(Map map) { + private static Map invertMap(final Map map) { final Map inverted = new IdentityHashMap<>(map.size()); - for(Map.Entry entry: map.entrySet()) { + for(final Map.Entry entry: map.entrySet()) { inverted.put(entry.getValue(), entry.getKey()); } return Collections.unmodifiableMap(inverted); @@ -232,29 +243,58 @@ public class TypeUtilities { * {@link #isSubtype(Class, Class)}) as well as boxing conversion (JLS 5.1.7) optionally followed by widening * reference conversion and unboxing conversion (JLS 5.1.8) optionally followed by widening primitive conversion. * - * @param callSiteType the parameter type at the call site - * @param methodType the parameter type in the method declaration - * @return true if callSiteType is method invocation convertible to the methodType. + * @param sourceType the type being converted from (call site type for parameter types, method type for return types) + * @param targetType the parameter type being converted to (method type for parameter types, call site type for return types) + * @return true if source type is method invocation convertible to target type. */ - public static boolean isMethodInvocationConvertible(Class callSiteType, Class methodType) { - if(methodType.isAssignableFrom(callSiteType)) { + public static boolean isMethodInvocationConvertible(final Class sourceType, final Class targetType) { + if(targetType.isAssignableFrom(sourceType)) { return true; } - if(callSiteType.isPrimitive()) { - if(methodType.isPrimitive()) { - return isProperPrimitiveSubtype(callSiteType, methodType); + if(sourceType.isPrimitive()) { + if(targetType.isPrimitive()) { + return isProperPrimitiveSubtype(sourceType, targetType); } // Boxing + widening reference conversion - return methodType.isAssignableFrom(WRAPPER_TYPES.get(callSiteType)); + assert WRAPPER_TYPES.get(sourceType) != null : sourceType.getName(); + return targetType.isAssignableFrom(WRAPPER_TYPES.get(sourceType)); } - if(methodType.isPrimitive()) { - final Class unboxedCallSiteType = PRIMITIVE_TYPES.get(callSiteType); + if(targetType.isPrimitive()) { + final Class unboxedCallSiteType = PRIMITIVE_TYPES.get(sourceType); return unboxedCallSiteType != null - && (unboxedCallSiteType == methodType || isProperPrimitiveSubtype(unboxedCallSiteType, methodType)); + && (unboxedCallSiteType == targetType || isProperPrimitiveSubtype(unboxedCallSiteType, targetType)); } return false; } + /** + * Determines whether a type can be converted to another without losing any + * precision. + * + * @param sourceType the source type + * @param targetType the target type + * @return true if lossless conversion is possible + */ + public static boolean isConvertibleWithoutLoss(final Class sourceType, final Class targetType) { + if(targetType.isAssignableFrom(sourceType)) { + return true; + } + if(sourceType.isPrimitive()) { + if(sourceType == void.class) { + return false; // Void can't be losslessly represented by any type + } + if(targetType.isPrimitive()) { + return isProperPrimitiveLosslessSubtype(sourceType, targetType); + } + // Boxing + widening reference conversion + assert WRAPPER_TYPES.get(sourceType) != null : sourceType.getName(); + return targetType.isAssignableFrom(WRAPPER_TYPES.get(sourceType)); + } + // Can't convert from any non-primitive type to any primitive type without data loss because of null. + // Also, can't convert non-assignable reference types. + return false; + } + /** * Determines whether one type can be potentially converted to another type at runtime. Allows a conversion between * any subtype and supertype in either direction, and also allows a conversion between any two primitive types, as @@ -264,9 +304,9 @@ public class TypeUtilities { * @param methodType the parameter type in the method declaration * @return true if callSiteType is potentially convertible to the methodType. */ - public static boolean isPotentiallyConvertible(Class callSiteType, Class methodType) { + public static boolean isPotentiallyConvertible(final Class callSiteType, final Class methodType) { // Widening or narrowing reference conversion - if(methodType.isAssignableFrom(callSiteType) || callSiteType.isAssignableFrom(methodType)) { + if(areAssignable(callSiteType, methodType)) { return true; } if(callSiteType.isPrimitive()) { @@ -286,6 +326,16 @@ public class TypeUtilities { return false; } + /** + * Returns true if either of the types is assignable from the other. + * @param c1 one of the types + * @param c2 another one of the types + * @return true if either c1 is assignable from c2 or c2 is assignable from c1. + */ + public static boolean areAssignable(final Class c1, final Class c2) { + return c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1); + } + /** * Determines whether one type is a subtype of another type, as per JLS 4.10 "Subtyping". Note: this is not strict * or proper subtype, therefore true is also returned for identical types; to be completely precise, it allows @@ -297,7 +347,7 @@ public class TypeUtilities { * @return true if subType can be converted by identity conversion, widening primitive conversion, or widening * reference conversion to superType. */ - public static boolean isSubtype(Class subType, Class superType) { + public static boolean isSubtype(final Class subType, final Class superType) { // Covers both JLS 4.10.2 "Subtyping among Class and Interface Types" // and JLS 4.10.3 "Subtyping among Array Types", as well as primitive // type identity. @@ -328,7 +378,7 @@ public class TypeUtilities { * @param superType the supposed supertype * @return true if subType is a proper (not identical to) primitive subtype of the superType */ - private static boolean isProperPrimitiveSubtype(Class subType, Class superType) { + private static boolean isProperPrimitiveSubtype(final Class subType, final Class superType) { if(superType == boolean.class || subType == boolean.class) { return false; } @@ -353,6 +403,37 @@ public class TypeUtilities { return false; } + /** + * Similar to {@link #isProperPrimitiveSubtype(Class, Class)}, except it disallows conversions from int and long to + * float, and from long to double, as those can lose precision. It also disallows conversion from and to char and + * anything else (similar to boolean) as char is not meant to be an arithmetic type. + * @param subType the supposed subtype + * @param superType the supposed supertype + * @return true if subType is a proper (not identical to) primitive subtype of the superType that can be represented + * by the supertype without no precision loss. + */ + private static boolean isProperPrimitiveLosslessSubtype(final Class subType, final Class superType) { + if(superType == boolean.class || subType == boolean.class) { + return false; + } + if(superType == char.class || subType == char.class) { + return false; + } + if(subType == byte.class) { + return true; + } + if(subType == short.class) { + return superType != byte.class; + } + if(subType == int.class) { + return superType == long.class || superType == double.class; + } + if(subType == float.class) { + return superType == double.class; + } + return false; + } + private static final Map, Class> WRAPPER_TO_PRIMITIVE_TYPES = createWrapperToPrimitiveTypes(); private static Map, Class> createWrapperToPrimitiveTypes() { @@ -384,13 +465,13 @@ public class TypeUtilities { return classes.keySet(); } - private static void addClassHierarchy(Map, Class> map, Class clazz) { + private static void addClassHierarchy(final Map, Class> map, final Class clazz) { if(clazz == null) { return; } map.put(clazz, clazz); addClassHierarchy(map, clazz.getSuperclass()); - for(Class itf: clazz.getInterfaces()) { + for(final Class itf: clazz.getInterfaces()) { addClassHierarchy(map, itf); } } @@ -402,7 +483,7 @@ public class TypeUtilities { * @return true if the class can be assigned from any boxed primitive. Basically, it is true if the class is any * primitive wrapper class, or a superclass or superinterface of any primitive wrapper class. */ - private static boolean isAssignableFromBoxedPrimitive(Class clazz) { + private static boolean isAssignableFromBoxedPrimitive(final Class clazz) { return PRIMITIVE_WRAPPER_TYPES.contains(clazz); } @@ -413,7 +494,7 @@ public class TypeUtilities { * @return the class representing the primitive type, or null if the name does not correspond to a primitive type * or is "void". */ - public static Class getPrimitiveTypeByName(String name) { + public static Class getPrimitiveTypeByName(final String name) { return PRIMITIVE_TYPES_BY_NAME.get(name); } @@ -424,7 +505,7 @@ public class TypeUtilities { * @param wrapperType the class object representing a wrapper for a primitive type * @return the class object representing the primitive type, or null if the passed class is not a primitive wrapper. */ - public static Class getPrimitiveType(Class wrapperType) { + public static Class getPrimitiveType(final Class wrapperType) { return WRAPPER_TO_PRIMITIVE_TYPES.get(wrapperType); } @@ -436,7 +517,7 @@ public class TypeUtilities { * @param primitiveType the class object representing a primitive type * @return the class object representing the wrapper type, or null if the passed class is not a primitive. */ - public static Class getWrapperType(Class primitiveType) { + public static Class getWrapperType(final Class primitiveType) { return WRAPPER_TYPES.get(primitiveType); } } diff --git a/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java index da8c0096f49..89a0677e91f 100644 --- a/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java +++ b/nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java @@ -90,7 +90,7 @@ class UnnamedDynCallSiteDescriptor extends AbstractCallSiteDescriptor { private final MethodType methodType; private final String op; - UnnamedDynCallSiteDescriptor(String op, MethodType methodType) { + UnnamedDynCallSiteDescriptor(final String op, final MethodType methodType) { this.op = op; this.methodType = methodType; } @@ -105,7 +105,7 @@ class UnnamedDynCallSiteDescriptor extends AbstractCallSiteDescriptor { } @Override - public String getNameToken(int i) { + public String getNameToken(final int i) { switch(i) { case 0: return "dyn"; case 1: return op; @@ -119,7 +119,7 @@ class UnnamedDynCallSiteDescriptor extends AbstractCallSiteDescriptor { } @Override - public CallSiteDescriptor changeMethodType(MethodType newMethodType) { + public CallSiteDescriptor changeMethodType(final MethodType newMethodType) { return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new UnnamedDynCallSiteDescriptor(op, newMethodType)); } diff --git a/nashorn/src/jdk/internal/dynalink/support/messages.properties b/nashorn/src/jdk/internal/dynalink/support/messages.properties index 88d59908071..ed26299e0c4 100644 --- a/nashorn/src/jdk/internal/dynalink/support/messages.properties +++ b/nashorn/src/jdk/internal/dynalink/support/messages.properties @@ -83,4 +83,4 @@ isOfClassGuardAlwaysTrue=isOfClass guard for {0} in position {1} in method type isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} at {3} will always return false isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} at {2} will always return true -isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} at {2} will always return false \ No newline at end of file +isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} at {2} will always return false diff --git a/nashorn/src/jdk/nashorn/api/scripting/Formatter.java b/nashorn/src/jdk/nashorn/api/scripting/Formatter.java index a14a83e4ce3..544e70ce452 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/Formatter.java +++ b/nashorn/src/jdk/nashorn/api/scripting/Formatter.java @@ -65,8 +65,8 @@ final class Formatter { while (m.find()) { int index = index(m.group(1)); - boolean previous = isPreviousArgument(m.group(2)); - char conversion = m.group(6).charAt(0); + final boolean previous = isPreviousArgument(m.group(2)); + final char conversion = m.group(6).charAt(0); // skip over some formats if (index < 0 || previous @@ -85,7 +85,7 @@ final class Formatter { } // current argument - Object arg = args[index - 1]; + final Object arg = args[index - 1]; // for date we convert double to long if (m.group(5) != null) { diff --git a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java index bd6e820be3d..8d818642ef5 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java +++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java @@ -26,7 +26,6 @@ package jdk.nashorn.api.scripting; import java.util.Collection; -import java.util.Collections; import java.util.Set; /** diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java index a5f8c24a2e6..c48bf4b26aa 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java @@ -182,7 +182,7 @@ public abstract class NashornException extends RuntimeException { if (ECMAErrors.isScriptFrame(st)) { final String className = "<" + st.getFileName() + ">"; String methodName = st.getMethodName(); - if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) { + if (methodName.equals(CompilerConstants.PROGRAM.symbolName())) { methodName = ""; } @@ -224,10 +224,22 @@ public abstract class NashornException extends RuntimeException { return buf.toString(); } + /** + * Get the thrown object. Subclass responsibility + * @return thrown object + */ protected Object getThrown() { return null; } + /** + * Initialization function for ECMA errors. Stores the error + * in the ecmaError field of this class. It is only initialized + * once, and then reused + * + * @param global the global + * @return initialized exception + */ protected NashornException initEcmaError(final ScriptObject global) { if (ecmaError != null) { return this; // initialized already! diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 7ebe5c91656..514c6ab1bc1 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -123,7 +123,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } // load engine.js - @SuppressWarnings("resource") private static Source loadEngineJSSource() { final String script = "resources/engine.js"; try { @@ -281,7 +280,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException { try { return sourceFor(getScriptName(ctxt), reader); - } catch (IOException e) { + } catch (final IOException e) { throw new ScriptException(e); } } @@ -380,7 +379,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it! - Object scope = bindings.get(NASHORN_GLOBAL); + final Object scope = bindings.get(NASHORN_GLOBAL); if (scope instanceof ScriptObjectMirror) { final Global glob = globalFromMirror((ScriptObjectMirror)scope); if (glob != null) { @@ -397,7 +396,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Retrieve nashorn Global object from a given ScriptObjectMirror private Global globalFromMirror(final ScriptObjectMirror mirror) { - ScriptObject sobj = mirror.getScriptObject(); + final ScriptObject sobj = mirror.getScriptObject(); if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) { return (Global)sobj; } @@ -456,7 +455,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) { // set "context" global variable via contextProperty - because this // property is non-writable - contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false); + contextProperty.setValue(ctxtGlobal, ctxtGlobal, ctxt, false); Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal); if (args == null || args == UNDEFINED) { args = ScriptRuntime.EMPTY_ARRAY; @@ -671,7 +670,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C continue; } - Object obj = sobj.get(method.getName()); + final Object obj = sobj.get(method.getName()); if (! (obj instanceof ScriptFunction)) { return false; } diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java index beb0c2a0fef..777edc9dfe9 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java @@ -164,7 +164,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { * @param args arguments array passed to script engine. * @return newly created script engine. */ - public ScriptEngine getScriptEngine(final String[] args) { + public ScriptEngine getScriptEngine(final String... args) { checkConfigPermission(); return new NashornScriptEngine(this, args, getAppClassLoader()); } @@ -220,7 +220,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { // Revisit: script engine implementation needs the capability to // find the class loader of the context in which the script engine // is running so that classes will be found and loaded properly - ClassLoader ccl = Thread.currentThread().getContextClassLoader(); + final ClassLoader ccl = Thread.currentThread().getContextClassLoader(); return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl; } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index b12553369d4..8763c22f466 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -43,13 +43,13 @@ import java.util.Set; import java.util.concurrent.Callable; import javax.script.Bindings; import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.arrays.ArrayData; import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.arrays.ArrayData; /** * Mirror object that wraps a given Nashorn Script object. @@ -169,6 +169,12 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin }); } + /** + * Call member function + * @param functionName function name + * @param args arguments + * @return return value of function + */ public Object callMember(final String functionName, final Object... args) { functionName.getClass(); // null check final Global oldGlobal = Context.getGlobal(); @@ -496,7 +502,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin public void setProto(final Object proto) { inGlobal(new Callable() { @Override public Void call() { - sobj.setProtoCheck(unwrap(proto, global)); + sobj.setPrototypeOf(unwrap(proto, global)); return null; } }); @@ -621,6 +627,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin /** * Utilitity to convert this script object to the given type. * + * @param destination type to convert to * @param type destination type to convert to * @return converted object */ @@ -728,7 +735,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin return global; } - static Object translateUndefined(Object obj) { + static Object translateUndefined(final Object obj) { return (obj == ScriptRuntime.UNDEFINED)? null : obj; } diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java index 29d03db4f4b..da5b9bdb663 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java @@ -28,11 +28,11 @@ package jdk.nashorn.api.scripting; import java.lang.invoke.MethodHandle; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.linker.LinkerServices; -import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.linker.Bootstrap; /** * Utilities that are to be called from script code. diff --git a/nashorn/src/jdk/nashorn/api/scripting/URLReader.java b/nashorn/src/jdk/nashorn/api/scripting/URLReader.java index 13f69843d5a..53efeee7d0a 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/URLReader.java +++ b/nashorn/src/jdk/nashorn/api/scripting/URLReader.java @@ -81,7 +81,7 @@ public final class URLReader extends Reader { } @Override - public int read(char cbuf[], int off, int len) throws IOException { + public int read(final char cbuf[], final int off, final int len) throws IOException { return getReader().read(cbuf, off, len); } diff --git a/nashorn/src/jdk/nashorn/api/scripting/package-info.java b/nashorn/src/jdk/nashorn/api/scripting/package-info.java index 6876151e330..f017ba9ef4f 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/package-info.java +++ b/nashorn/src/jdk/nashorn/api/scripting/package-info.java @@ -32,7 +32,8 @@ * ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("Nashorn"); * *

Nashorn script engines implement the optional {@link javax.script.Invocable} and {@link javax.script.Compilable} - * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. See + * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. In addition, + * this package provides nashorn specific extension classes, interfaces and methods. See * {@link jdk.nashorn.api.scripting.NashornScriptEngineFactory} for further details. */ package jdk.nashorn.api.scripting; diff --git a/nashorn/src/jdk/nashorn/internal/IntDeque.java b/nashorn/src/jdk/nashorn/internal/IntDeque.java new file mode 100644 index 00000000000..477afcf94ae --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/IntDeque.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal; + +/** + * Small helper class for fast int deques + */ +public class IntDeque { + private int[] deque = new int[16]; + private int nextFree = 0; + + /** + * Push an int value + * @param value value + */ + public void push(final int value) { + if (nextFree == deque.length) { + final int[] newDeque = new int[nextFree * 2]; + System.arraycopy(deque, 0, newDeque, 0, nextFree); + deque = newDeque; + } + deque[nextFree++] = value; + } + + /** + * Pop an int value + * @return value + */ + public int pop() { + return deque[--nextFree]; + } + + /** + * Peek + * @return top value + */ + public int peek() { + return deque[nextFree - 1]; + } + + /** + * Get the value of the top element and increment it. + * @return top value + */ + public int getAndIncrement() { + return deque[nextFree - 1]++; + } + + /** + * Decrement the value of the top element and return it. + * @return decremented top value + */ + public int decrementAndGet() { + return --deque[nextFree - 1]; + } + + /** + * Check if deque is empty + * @return true if empty + */ + public boolean isEmpty() { + return nextFree == 0; + } +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java b/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java new file mode 100644 index 00000000000..a5fbfdf9134 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; +import static jdk.nashorn.internal.codegen.CompilerConstants.EXPLODED_ARGUMENT_PREFIX; + +import java.lang.invoke.MethodType; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import jdk.nashorn.internal.ir.AccessNode; +import jdk.nashorn.internal.ir.CallNode; +import jdk.nashorn.internal.ir.Expression; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.IdentNode; +import jdk.nashorn.internal.ir.LexicalContext; +import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.objects.Global; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.logging.DebugLogger; +import jdk.nashorn.internal.runtime.logging.Loggable; +import jdk.nashorn.internal.runtime.logging.Logger; +import jdk.nashorn.internal.runtime.options.Options; + +/** + * An optimization that attempts to turn applies into calls. This pattern + * is very common for fake class instance creation, and apply + * introduces expensive args collection and boxing + * + *

+ * var Class = {
+ *     create: function() {
+ *         return function() { //vararg
+ *             this.initialize.apply(this, arguments);
+ *         }
+ *     }
+ * };
+ *
+ * Color = Class.create();
+ *
+ * Color.prototype = {
+ *    red: 0, green: 0, blue: 0,
+ *    initialize: function(r,g,b) {
+ *        this.red = r;
+ *        this.green = g;
+ *        this.blue = b;
+ *    }
+ * }
+ *
+ * new Color(17, 47, 11);
+ * 
+ */ + +@Logger(name="apply2call") +public final class ApplySpecialization extends NodeVisitor implements Loggable { + + private static final boolean USE_APPLY2CALL = Options.getBooleanProperty("nashorn.apply2call", true); + + private final DebugLogger log; + + private final Compiler compiler; + + private final Set changed = new HashSet<>(); + + private final Deque> explodedArguments = new ArrayDeque<>(); + + private static final String ARGUMENTS = ARGUMENTS_VAR.symbolName(); + + /** + * Apply specialization optimization. Try to explode arguments and call + * applies as calls if they just pass on the "arguments" array and + * "arguments" doesn't escape. + * + * @param compiler compiler + */ + public ApplySpecialization(final Compiler compiler) { + super(new LexicalContext()); + this.compiler = compiler; + this.log = initLogger(compiler.getContext()); + } + + @Override + public DebugLogger getLogger() { + return log; + } + + @Override + public DebugLogger initLogger(final Context context) { + return context.getLogger(this.getClass()); + } + + /** + * Arguments may only be used as args to the apply. Everything else is disqualified + * We cannot control arguments if they escape from the method and go into an unknown + * scope, thus we are conservative and treat any access to arguments outside the + * apply call as a case of "we cannot apply the optimization". + * + * @return true if arguments escape + */ + private boolean argumentsEscape(final FunctionNode functionNode) { + + final Deque> stack = new ArrayDeque<>(); + //ensure that arguments is only passed as arg to apply + try { + functionNode.accept(new NodeVisitor(new LexicalContext()) { + private boolean isCurrentArg(final Expression expr) { + return !stack.isEmpty() && stack.peek().contains(expr); //args to current apply call + } + + private boolean isArguments(final Expression expr) { + return expr instanceof IdentNode && ARGUMENTS.equals(((IdentNode)expr).getName()); + } + + private boolean isParam(final String name) { + for (final IdentNode param : functionNode.getParameters()) { + if (param.getName().equals(name)) { + return true; + } + } + return false; + } + + @Override + public Node leaveIdentNode(final IdentNode identNode) { + if (isParam(identNode.getName()) || ARGUMENTS.equals(identNode.getName()) && !isCurrentArg(identNode)) { + throw new UnsupportedOperationException(); + } + return identNode; + } + + @Override + public boolean enterCallNode(final CallNode callNode) { + final Set callArgs = new HashSet<>(); + if (isApply(callNode)) { + final List argList = callNode.getArgs(); + if (argList.size() != 2 || !isArguments(argList.get(argList.size() - 1))) { + throw new UnsupportedOperationException(); + } + callArgs.addAll(callNode.getArgs()); + } + stack.push(callArgs); + return true; + } + + @Override + public Node leaveCallNode(final CallNode callNode) { + stack.pop(); + return callNode; + } + }); + } catch (final UnsupportedOperationException e) { + log.fine("'arguments' escapes, is not used in standard call dispatch, or is reassigned in '" + functionNode.getName() + "'. Aborting"); + return true; //bad + } + + return false; + } + + @Override + public boolean enterCallNode(final CallNode callNode) { + return !explodedArguments.isEmpty(); + } + + @Override + public Node leaveCallNode(final CallNode callNode) { + //apply needs to be a global symbol or we don't allow it + + final List newParams = explodedArguments.peek(); + if (isApply(callNode)) { + final List newArgs = new ArrayList<>(); + for (final Expression arg : callNode.getArgs()) { + if (arg instanceof IdentNode && ARGUMENTS.equals(((IdentNode)arg).getName())) { + newArgs.addAll(newParams); + } else { + newArgs.add(arg); + } + } + + changed.add(lc.getCurrentFunction().getId()); + + final CallNode newCallNode = callNode.setArgs(newArgs).setIsApplyToCall(); + + log.fine("Transformed ", + callNode, + " from apply to call => ", + newCallNode, + " in ", + DebugLogger.quote(lc.getCurrentFunction().getName())); + + return newCallNode; + } + + return callNode; + } + + private boolean pushExplodedArgs(final FunctionNode functionNode) { + int start = 0; + + final MethodType actualCallSiteType = compiler.getCallSiteType(functionNode); + if (actualCallSiteType == null) { + return false; + } + assert actualCallSiteType.parameterType(actualCallSiteType.parameterCount() - 1) != Object[].class : "error vararg callsite passed to apply2call " + functionNode.getName() + " " + actualCallSiteType; + + final TypeMap ptm = compiler.getTypeMap(); + if (ptm.needsCallee()) { + start++; + } + + start++; //we always uses this + + final List params = functionNode.getParameters(); + final List newParams = new ArrayList<>(); + final long to = Math.max(params.size(), actualCallSiteType.parameterCount() - start); + for (int i = 0; i < to; i++) { + if (i >= params.size()) { + newParams.add(new IdentNode(functionNode.getToken(), functionNode.getFinish(), EXPLODED_ARGUMENT_PREFIX.symbolName() + (i))); + } else { + newParams.add(params.get(i)); + } + } + + explodedArguments.push(newParams); + return true; + } + + @Override + public boolean enterFunctionNode(final FunctionNode functionNode) { + if (!USE_APPLY2CALL) { + return false; + } + + if (!Global.instance().isSpecialNameValid("apply")) { + log.fine("Apply transform disabled: apply/call overridden"); + assert !Global.instance().isSpecialNameValid("call") : "call and apply should have the same SwitchPoint"; + return false; + } + + if (!compiler.isOnDemandCompilation()) { + return false; + } + + if (functionNode.hasEval()) { + return false; + } + + if (argumentsEscape(functionNode)) { + return false; + } + + return pushExplodedArgs(functionNode); + } + + /** + * Try to do the apply to call transformation + * @return true if successful, false otherwise + */ + @Override + public Node leaveFunctionNode(final FunctionNode functionNode0) { + FunctionNode newFunctionNode = functionNode0; + final String functionName = newFunctionNode.getName(); + + if (changed.contains(newFunctionNode.getId())) { + newFunctionNode = newFunctionNode.clearFlag(lc, FunctionNode.USES_ARGUMENTS). + setFlag(lc, FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION). + setParameters(lc, explodedArguments.peek()); + + if (log.isEnabled()) { + log.info("Successfully specialized apply to call in '", + functionName, + " params=", + explodedArguments.peek(), + "' id=", + newFunctionNode.getId(), + " source=", + newFunctionNode.getSource().getURL()); + } + } + + explodedArguments.pop(); + + return newFunctionNode; + } + + private static boolean isApply(final CallNode callNode) { + final Expression f = callNode.getFunction(); + return f instanceof AccessNode && "apply".equals(((AccessNode)f).getProperty()); + } + +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java b/nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java new file mode 100644 index 00000000000..4a817fae3db --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java @@ -0,0 +1,946 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; +import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; +import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; +import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN; +import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; +import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; +import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS; +import static jdk.nashorn.internal.ir.Symbol.HAS_OBJECT_VALUE; +import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF; +import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL; +import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; +import static jdk.nashorn.internal.ir.Symbol.IS_LET; +import static jdk.nashorn.internal.ir.Symbol.IS_PARAM; +import static jdk.nashorn.internal.ir.Symbol.IS_PROGRAM_LEVEL; +import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE; +import static jdk.nashorn.internal.ir.Symbol.IS_THIS; +import static jdk.nashorn.internal.ir.Symbol.IS_VAR; +import static jdk.nashorn.internal.ir.Symbol.KINDMASK; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; +import jdk.nashorn.internal.ir.AccessNode; +import jdk.nashorn.internal.ir.BinaryNode; +import jdk.nashorn.internal.ir.Block; +import jdk.nashorn.internal.ir.CatchNode; +import jdk.nashorn.internal.ir.Expression; +import jdk.nashorn.internal.ir.ForNode; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; +import jdk.nashorn.internal.ir.IdentNode; +import jdk.nashorn.internal.ir.IndexNode; +import jdk.nashorn.internal.ir.LexicalContext; +import jdk.nashorn.internal.ir.LexicalContextNode; +import jdk.nashorn.internal.ir.LiteralNode; +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; +import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.RuntimeNode; +import jdk.nashorn.internal.ir.RuntimeNode.Request; +import jdk.nashorn.internal.ir.SplitNode; +import jdk.nashorn.internal.ir.Statement; +import jdk.nashorn.internal.ir.SwitchNode; +import jdk.nashorn.internal.ir.Symbol; +import jdk.nashorn.internal.ir.TryNode; +import jdk.nashorn.internal.ir.UnaryNode; +import jdk.nashorn.internal.ir.VarNode; +import jdk.nashorn.internal.ir.WithNode; +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.Property; +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.logging.DebugLogger; +import jdk.nashorn.internal.runtime.logging.Loggable; +import jdk.nashorn.internal.runtime.logging.Logger; + +/** + * This visitor assigns symbols to identifiers denoting variables. It does few more minor calculations that are only + * possible after symbols have been assigned; such is the transformation of "delete" and "typeof" operators into runtime + * nodes and counting of number of properties assigned to "this" in constructor functions. This visitor is also notable + * for what it doesn't do, most significantly it does no type calculations as in JavaScript variables can change types + * during runtime and as such symbols don't have types. Calculation of expression types is performed by a separate + * visitor. + */ +@Logger(name="symbols") +final class AssignSymbols extends NodeOperatorVisitor implements Loggable { + private final DebugLogger log; + private final boolean debug; + + private static boolean isParamOrVar(final IdentNode identNode) { + final Symbol symbol = identNode.getSymbol(); + return symbol.isParam() || symbol.isVar(); + } + + private static String name(final Node node) { + final String cn = node.getClass().getName(); + final int lastDot = cn.lastIndexOf('.'); + if (lastDot == -1) { + return cn; + } + return cn.substring(lastDot + 1); + } + + /** + * Checks if various symbols that were provisionally marked as needing a slot ended up unused, and marks them as not + * needing a slot after all. + * @param functionNode the function node + * @return the passed in node, for easy chaining + */ + private static FunctionNode removeUnusedSlots(final FunctionNode functionNode) { + if (!functionNode.needsCallee()) { + functionNode.compilerConstant(CALLEE).setNeedsSlot(false); + } + if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) { + functionNode.compilerConstant(SCOPE).setNeedsSlot(false); + } + if (!functionNode.usesReturnSymbol()) { + functionNode.compilerConstant(RETURN).setNeedsSlot(false); + } + // Named function expressions that end up not referencing themselves won't need a local slot for the self symbol. + if(!functionNode.isDeclared() && !functionNode.usesSelfSymbol() && !functionNode.isAnonymous()) { + final Symbol selfSymbol = functionNode.getBody().getExistingSymbol(functionNode.getIdent().getName()); + if(selfSymbol != null) { + if(selfSymbol.isFunctionSelf()) { + selfSymbol.setNeedsSlot(false); + selfSymbol.clearFlag(Symbol.IS_VAR); + } + } else { + assert functionNode.isProgram(); + } + } + return functionNode; + } + + private final Deque> thisProperties = new ArrayDeque<>(); + private final Map globalSymbols = new HashMap<>(); //reuse the same global symbol + private final Compiler compiler; + + public AssignSymbols(final Compiler compiler) { + super(new LexicalContext()); + this.compiler = compiler; + this.log = initLogger(compiler.getContext()); + this.debug = log.isEnabled(); + } + + @Override + public DebugLogger getLogger() { + return log; + } + + @Override + public DebugLogger initLogger(final Context context) { + return context.getLogger(this.getClass()); + } + + /** + * Define symbols for all variable declarations at the top of the function scope. This way we can get around + * problems like + * + * while (true) { + * break; + * if (true) { + * var s; + * } + * } + * + * to an arbitrary nesting depth. + * + * see NASHORN-73 + * + * @param functionNode the FunctionNode we are entering + * @param body the body of the FunctionNode we are entering + */ + private void acceptDeclarations(final FunctionNode functionNode, final Block body) { + // This visitor will assign symbol to all declared variables, except function declarations (which are taken care + // in a separate step above) and "var" declarations in for loop initializers. + // + body.accept(new NodeVisitor(new LexicalContext()) { + @Override + public boolean enterFunctionNode(final FunctionNode nestedFn) { + // Don't descend into nested functions + return false; + } + + @Override + public Node leaveVarNode(final VarNode varNode) { + if (varNode.isStatement()) { + final IdentNode ident = varNode.getName(); + final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR); + functionNode.addDeclaredSymbol(symbol); + if (varNode.isFunctionDeclaration()) { + symbol.setIsFunctionDeclaration(); + } + return varNode.setName((IdentNode)ident.setSymbol(symbol)); + } + return varNode; + } + }); + } + + private IdentNode compilerConstantIdentifier(final CompilerConstants cc) { + return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc.getCurrentFunction().compilerConstant(cc)); + } + + /** + * Creates an ident node for an implicit identifier within the function (one not declared in the script source + * code). These identifiers are defined with function's token and finish. + * @param name the name of the identifier + * @return an ident node representing the implicit identifier. + */ + private IdentNode createImplicitIdentifier(final String name) { + final FunctionNode fn = lc.getCurrentFunction(); + return new IdentNode(fn.getToken(), fn.getFinish(), name); + } + + private Symbol createSymbol(final String name, final int flags) { + if ((flags & Symbol.KINDMASK) == IS_GLOBAL) { + //reuse global symbols so they can be hashed + Symbol global = globalSymbols.get(name); + if (global == null) { + global = new Symbol(name, flags); + globalSymbols.put(name, global); + } + return global; + } + return new Symbol(name, flags); + } + + /** + * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically + * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function + * expressions as well as for assignment of {@code :arguments} to {@code arguments}. + * + * @param name the ident node identifying the variable to initialize + * @param initConstant the compiler constant it is initialized to + * @param fn the function node the assignment is for + * @return a var node with the appropriate assignment + */ + private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) { + final IdentNode init = compilerConstantIdentifier(initConstant); + assert init.getSymbol() != null && init.getSymbol().isBytecodeLocal(); + + final VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init); + + final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName()); + assert nameSymbol != null; + + return (VarNode)synthVar.setName((IdentNode)name.setSymbol(nameSymbol)).accept(this); + } + + private FunctionNode createSyntheticInitializers(final FunctionNode functionNode) { + final List syntheticInitializers = new ArrayList<>(2); + + // Must visit the new var nodes in the context of the body. We could also just set the new statements into the + // block and then revisit the entire block, but that seems to be too much double work. + final Block body = functionNode.getBody(); + lc.push(body); + try { + if (functionNode.usesSelfSymbol()) { + // "var fn = :callee" + syntheticInitializers.add(createSyntheticInitializer(functionNode.getIdent(), CALLEE, functionNode)); + } + + if (functionNode.needsArguments()) { + // "var arguments = :arguments" + syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()), + ARGUMENTS, functionNode)); + } + + if (syntheticInitializers.isEmpty()) { + return functionNode; + } + + for(final ListIterator it = syntheticInitializers.listIterator(); it.hasNext();) { + it.set((VarNode)it.next().accept(this)); + } + } finally { + lc.pop(body); + } + + final List stmts = body.getStatements(); + final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); + newStatements.addAll(syntheticInitializers); + newStatements.addAll(stmts); + return functionNode.setBody(lc, body.setStatements(lc, newStatements)); + } + + private Symbol defineGlobalSymbol(final Block block, final String name) { + return defineSymbol(block, name, IS_GLOBAL); + } + + /** + * Defines a new symbol in the given block. + * + * @param block the block in which to define the symbol + * @param name name of symbol. + * @param symbolFlags Symbol flags. + * + * @return Symbol for given name or null for redefinition. + */ + private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) { + int flags = symbolFlags; + Symbol symbol = findSymbol(block, name); // Locate symbol. + final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL; + + // Global variables are implicitly always scope variables too. + if (isGlobal) { + flags |= IS_SCOPE; + } + + if (lc.getCurrentFunction().isProgram()) { + flags |= IS_PROGRAM_LEVEL; + } + + final boolean isParam = (flags & KINDMASK) == IS_PARAM; + final boolean isVar = (flags & KINDMASK) == IS_VAR; + + final FunctionNode function = lc.getFunction(block); + if (symbol != null) { + // Symbol was already defined. Check if it needs to be redefined. + if (isParam) { + if (!isLocal(function, symbol)) { + // Not defined in this function. Create a new definition. + symbol = null; + } else if (symbol.isParam()) { + // Duplicate parameter. Null return will force an error. + throw new AssertionError("duplicate parameter"); + } + } else if (isVar) { + if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) { + // Always create a new definition. + symbol = null; + } else { + // Not defined in this function. Create a new definition. + if (!isLocal(function, symbol) || symbol.less(IS_VAR)) { + symbol = null; + } + } + } + } + + if (symbol == null) { + // If not found, then create a new one. + Block symbolBlock; + + // Determine where to create it. + if (isVar && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) { + symbolBlock = block; //internal vars are always defined in the block closest to them + } else if (isGlobal) { + symbolBlock = lc.getOutermostFunction().getBody(); + } else { + symbolBlock = lc.getFunctionBody(function); + } + + // Create and add to appropriate block. + symbol = createSymbol(name, flags); + symbolBlock.putSymbol(lc, symbol); + + if ((flags & IS_SCOPE) == 0) { + // Initial assumption; symbol can lose its slot later + symbol.setNeedsSlot(true); + } + } else if (symbol.less(flags)) { + symbol.setFlags(flags); + } + + if((isVar || isParam) && compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) { + compiler.declareLocalSymbol(name); + } + + return symbol; + } + + private T end(final T node) { + return end(node, true); + } + + private T end(final T node, final boolean printNode) { + if (debug) { + final StringBuilder sb = new StringBuilder(); + + sb.append("[LEAVE "). + append(name(node)). + append("] "). + append(printNode ? node.toString() : ""). + append(" in '"). + append(lc.getCurrentFunction().getName()). + append('\''); + + if (node instanceof IdentNode) { + final Symbol symbol = ((IdentNode)node).getSymbol(); + if (symbol == null) { + sb.append(" "); + } else { + sb.append(" '); + } + } + + log.unindent(); + log.info(sb); + } + + return node; + } + + @Override + public boolean enterBlock(final Block block) { + start(block); + block.clearSymbols(); + + if (lc.isFunctionBody()) { + enterFunctionBody(); + } + + return true; + } + + @Override + public boolean enterCatchNode(final CatchNode catchNode) { + final IdentNode exception = catchNode.getException(); + final Block block = lc.getCurrentBlock(); + + start(catchNode); + + // define block-local exception variable + final String exname = exception.getName(); + // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its + // symbol is naturally internal, and should be treated as such. + final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName()); + defineSymbol(block, exname, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE); + + return true; + } + + private void enterFunctionBody() { + final FunctionNode functionNode = lc.getCurrentFunction(); + final Block body = lc.getCurrentBlock(); + + initFunctionWideVariables(functionNode, body); + + if (functionNode.isProgram()) { + initGlobalSymbols(body); + } else if (!functionNode.isDeclared() && !functionNode.isAnonymous()) { + // It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's + // anonymous. + final String name = functionNode.getIdent().getName(); + assert name != null; + assert body.getExistingSymbol(name) == null; + defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE); + if(functionNode.allVarsInScope()) { // basically, has deep eval + lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL); + } + } + + acceptDeclarations(functionNode, body); + } + + @Override + public boolean enterFunctionNode(final FunctionNode functionNode) { + // TODO: once we have information on symbols used by nested functions, we can stop descending into nested + // functions with on-demand compilation, e.g. add + // if(!thisProperties.isEmpty() && env.isOnDemandCompilation()) { + // return false; + // } + start(functionNode, false); + + thisProperties.push(new HashSet()); + + //an outermost function in our lexical context that is not a program + //is possible - it is a function being compiled lazily + if (functionNode.isDeclared()) { + final Iterator blocks = lc.getBlocks(); + if (blocks.hasNext()) { + defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR); + } + } + + return true; + } + + @Override + public boolean enterVarNode(final VarNode varNode) { + start(varNode); + defineSymbol(lc.getCurrentBlock(), varNode.getName().getName(), IS_VAR | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0)); + return true; + } + + private Symbol exceptionSymbol() { + return newObjectInternal(EXCEPTION_PREFIX); + } + + /** + * This has to run before fix assignment types, store any type specializations for + * paramters, then turn then to objects for the generic version of this method + * + * @param functionNode functionNode + */ + private FunctionNode finalizeParameters(final FunctionNode functionNode) { + final List newParams = new ArrayList<>(); + final boolean isVarArg = functionNode.isVarArg(); + + final Block body = functionNode.getBody(); + for (final IdentNode param : functionNode.getParameters()) { + final Symbol paramSymbol = body.getExistingSymbol(param.getName()); + assert paramSymbol != null; + assert paramSymbol.isParam() : paramSymbol + " " + paramSymbol.getFlags(); + newParams.add((IdentNode)param.setSymbol(paramSymbol)); + + // parameters should not be slots for a function that uses variable arity signature + if (isVarArg) { + paramSymbol.setNeedsSlot(false); + } + } + + return functionNode.setParameters(lc, newParams); + } + + /** + * Search for symbol in the lexical context starting from the given block. + * @param name Symbol name. + * @return Found symbol or null if not found. + */ + private Symbol findSymbol(final Block block, final String name) { + for (final Iterator blocks = lc.getBlocks(block); blocks.hasNext();) { + final Symbol symbol = blocks.next().getExistingSymbol(name); + if (symbol != null) { + return symbol; + } + } + return null; + } + + /** + * Marks the current function as one using any global symbol. The function and all its parent functions will all be + * marked as needing parent scope. + * @see FunctionNode#needsParentScope() + */ + private void functionUsesGlobalSymbol() { + for (final Iterator fns = lc.getFunctions(); fns.hasNext();) { + lc.setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE); + } + } + + /** + * Marks the current function as one using a scoped symbol. The block defining the symbol will be marked as needing + * its own scope to hold the variable. If the symbol is defined outside of the current function, it and all + * functions up to (but not including) the function containing the defining block will be marked as needing parent + * function scope. + * @see FunctionNode#needsParentScope() + */ + private void functionUsesScopeSymbol(final Symbol symbol) { + final String name = symbol.getName(); + for (final Iterator contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) { + final LexicalContextNode node = contextNodeIter.next(); + if (node instanceof Block) { + final Block block = (Block)node; + if (block.getExistingSymbol(name) != null) { + assert lc.contains(block); + lc.setBlockNeedsScope(block); + break; + } + } else if (node instanceof FunctionNode) { + lc.setFlag(node, FunctionNode.USES_ANCESTOR_SCOPE); + } + } + } + + /** + * Declares that the current function is using the symbol. + * @param symbol the symbol used by the current function. + */ + private void functionUsesSymbol(final Symbol symbol) { + assert symbol != null; + if (symbol.isScope()) { + if (symbol.isGlobal()) { + functionUsesGlobalSymbol(); + } else { + functionUsesScopeSymbol(symbol); + } + } else { + assert !symbol.isGlobal(); // Every global is also scope + } + } + + private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) { + defineSymbol(block, cc.symbolName(), flags).setNeedsSlot(true); + } + + private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) { + initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE); + initCompileConstant(THIS, body, IS_PARAM | IS_THIS | HAS_OBJECT_VALUE); + + if (functionNode.isVarArg()) { + initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE); + if (functionNode.needsArguments()) { + initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE); + defineSymbol(body, ARGUMENTS_VAR.symbolName(), IS_VAR | HAS_OBJECT_VALUE); + } + } + + initParameters(functionNode, body); + initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE); + initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL); + } + + + /** + * Move any properties from the global map into the scope of this function (which must be a program function). + * @param block the function node body for which to init scope vars + */ + private void initGlobalSymbols(final Block block) { + final PropertyMap map = Context.getGlobalMap(); + + for (final Property property : map.getProperties()) { + final Symbol symbol = defineGlobalSymbol(block, property.getKey()); + log.info("Added global symbol from property map ", symbol); + } + } + + /** + * Initialize parameters for function node. + * @param functionNode the function node + */ + private void initParameters(final FunctionNode functionNode, final Block body) { + final boolean isVarArg = functionNode.isVarArg(); + final boolean scopeParams = functionNode.allVarsInScope() || isVarArg; + for (final IdentNode param : functionNode.getParameters()) { + final Symbol symbol = defineSymbol(body, param.getName(), IS_PARAM); + if(scopeParams) { + // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored. + // It will force creation of scopes where they would otherwise not necessarily be needed (functions + // using arguments object and other variable arity functions). Tracked by JDK-8038942. + symbol.setIsScope(); + assert symbol.hasSlot(); + if(isVarArg) { + symbol.setNeedsSlot(false); + } + } + } + } + + /** + * Is the symbol local to (that is, defined in) the specified function? + * @param function the function + * @param symbol the symbol + * @return true if the symbol is defined in the specified function + */ + private boolean isLocal(final FunctionNode function, final Symbol symbol) { + final FunctionNode definingFn = lc.getDefiningFunction(symbol); + assert definingFn != null; + return definingFn == function; + } + + @Override + public Node leaveASSIGN(final BinaryNode binaryNode) { + // If we're assigning a property of the this object ("this.foo = ..."), record it. + + final Expression lhs = binaryNode.lhs(); + if (lhs instanceof AccessNode) { + final AccessNode accessNode = (AccessNode) lhs; + final Expression base = accessNode.getBase(); + if (base instanceof IdentNode) { + final Symbol symbol = ((IdentNode)base).getSymbol(); + if(symbol.isThis()) { + thisProperties.peek().add(accessNode.getProperty()); + } + } + } + return binaryNode; + } + + @Override + public Node leaveDELETE(final UnaryNode unaryNode) { + final FunctionNode currentFunctionNode = lc.getCurrentFunction(); + final boolean strictMode = currentFunctionNode.isStrict(); + final Expression rhs = unaryNode.getExpression(); + final Expression strictFlagNode = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this); + + Request request = Request.DELETE; + final List args = new ArrayList<>(); + + if (rhs instanceof IdentNode) { + final IdentNode ident = (IdentNode)rhs; + // If this is a declared variable or a function parameter, delete always fails (except for globals). + final String name = ident.getName(); + final Symbol symbol = ident.getSymbol(); + final boolean failDelete = strictMode || symbol.isParam() || (symbol.isVar() && !symbol.isProgramLevel()); + + if (failDelete && symbol.isThis()) { + return LiteralNode.newInstance(unaryNode, true).accept(this); + } + final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this); + + if (!failDelete) { + args.add(compilerConstantIdentifier(SCOPE)); + } + args.add(literalNode); + args.add(strictFlagNode); + + if (failDelete) { + request = Request.FAIL_DELETE; + } + } else if (rhs instanceof AccessNode) { + final Expression base = ((AccessNode)rhs).getBase(); + final String property = ((AccessNode)rhs).getProperty(); + + args.add(base); + args.add((Expression)LiteralNode.newInstance(unaryNode, property).accept(this)); + args.add(strictFlagNode); + + } else if (rhs instanceof IndexNode) { + final IndexNode indexNode = (IndexNode)rhs; + final Expression base = indexNode.getBase(); + final Expression index = indexNode.getIndex(); + + args.add(base); + args.add(index); + args.add(strictFlagNode); + + } else { + return LiteralNode.newInstance(unaryNode, true).accept(this); + } + return new RuntimeNode(unaryNode, request, args).accept(this); + } + + @Override + public Node leaveForNode(final ForNode forNode) { + if (forNode.isForIn()) { + forNode.setIterator(newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73 + } + + return end(forNode); + } + + @Override + public Node leaveFunctionNode(final FunctionNode functionNode) { + + return markProgramBlock( + removeUnusedSlots( + createSyntheticInitializers( + finalizeParameters( + lc.applyTopFlags(functionNode)))) + .setThisProperties(lc, thisProperties.pop().size()) + .setState(lc, CompilationState.SYMBOLS_ASSIGNED)); + } + + @Override + public Node leaveIdentNode(final IdentNode identNode) { + final String name = identNode.getName(); + + if (identNode.isPropertyName()) { + return identNode; + } + + final Block block = lc.getCurrentBlock(); + + Symbol symbol = findSymbol(block, name); + + //If an existing symbol with the name is found, use that otherwise, declare a new one + if (symbol != null) { + log.info("Existing symbol = ", symbol); + if (symbol.isFunctionSelf()) { + final FunctionNode functionNode = lc.getDefiningFunction(symbol); + assert functionNode != null; + assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null; + lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL); + } + + // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already) + maybeForceScope(symbol); + } else { + log.info("No symbol exists. Declare as global: ", symbol); + symbol = defineGlobalSymbol(block, name); + Symbol.setSymbolIsScope(lc, symbol); + } + + functionUsesSymbol(symbol); + + if (!identNode.isInitializedHere()) { + symbol.increaseUseCount(); + } + + return end(identNode.setSymbol(symbol)); + } + + @Override + public Node leaveSwitchNode(final SwitchNode switchNode) { + // We only need a symbol for the tag if it's not an integer switch node + if(!switchNode.isInteger()) { + switchNode.setTag(newObjectInternal(SWITCH_TAG_PREFIX)); + } + return switchNode; + } + + @Override + public Node leaveTryNode(final TryNode tryNode) { + tryNode.setException(exceptionSymbol()); + if (tryNode.getFinallyBody() != null) { + tryNode.setFinallyCatchAll(exceptionSymbol()); + } + + end(tryNode); + + return tryNode; + } + + @Override + public Node leaveTYPEOF(final UnaryNode unaryNode) { + final Expression rhs = unaryNode.getExpression(); + + final List args = new ArrayList<>(); + if (rhs instanceof IdentNode && !isParamOrVar((IdentNode)rhs)) { + args.add(compilerConstantIdentifier(SCOPE)); + args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null + } else { + args.add(rhs); + args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this' + } + + final Node runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args).accept(this); + + end(unaryNode); + + return runtimeNode; + } + + private FunctionNode markProgramBlock(final FunctionNode functionNode) { + if (compiler.isOnDemandCompilation() || !functionNode.isProgram()) { + return functionNode; + } + + assert functionNode.getId() == 1; + return functionNode.setBody(lc, functionNode.getBody().setFlag(lc, Block.IS_GLOBAL_SCOPE)); + } + + /** + * If the symbol isn't already a scope symbol, but it needs to be (see {@link #symbolNeedsToBeScope(Symbol)}, it is + * promoted to a scope symbol and its block marked as needing a scope. + * @param symbol the symbol that might be scoped + */ + private void maybeForceScope(final Symbol symbol) { + if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) { + Symbol.setSymbolIsScope(lc, symbol); + } + } + + private Symbol newInternal(final CompilerConstants cc, final int flags) { + return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), IS_VAR | IS_INTERNAL | flags); //NASHORN-73 + } + + private Symbol newObjectInternal(final CompilerConstants cc) { + return newInternal(cc, HAS_OBJECT_VALUE); + } + + private boolean start(final Node node) { + return start(node, true); + } + + private boolean start(final Node node, final boolean printNode) { + if (debug) { + final StringBuilder sb = new StringBuilder(); + + sb.append("[ENTER "). + append(name(node)). + append("] "). + append(printNode ? node.toString() : ""). + append(" in '"). + append(lc.getCurrentFunction().getName()). + append("'"); + log.info(sb); + log.indent(); + } + + return true; + } + + /** + * Determines if the symbol has to be a scope symbol. In general terms, it has to be a scope symbol if it can only + * be reached from the current block by traversing a function node, a split node, or a with node. + * @param symbol the symbol checked for needing to be a scope symbol + * @return true if the symbol has to be a scope symbol. + */ + private boolean symbolNeedsToBeScope(final Symbol symbol) { + if (symbol.isThis() || symbol.isInternal()) { + return false; + } + + if (lc.getCurrentFunction().allVarsInScope()) { + return true; + } + + boolean previousWasBlock = false; + for (final Iterator it = lc.getAllNodes(); it.hasNext();) { + final LexicalContextNode node = it.next(); + if (node instanceof FunctionNode || node instanceof SplitNode || isSplitArray(node)) { + // We reached the function boundary or a splitting boundary without seeing a definition for the symbol. + // It needs to be in scope. + return true; + } else if (node instanceof WithNode) { + if (previousWasBlock) { + // We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately + // preceded by a block, this means we're currently processing its expression, not its body, + // therefore it doesn't count. + return true; + } + previousWasBlock = false; + } else if (node instanceof Block) { + if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) { + // We reached the block that defines the symbol without reaching either the function boundary, or a + // WithNode. The symbol need not be scoped. + return false; + } + previousWasBlock = true; + } else { + previousWasBlock = false; + } + } + throw new AssertionError(); + } + + private static boolean isSplitArray(final LexicalContextNode expr) { + if(!(expr instanceof ArrayLiteralNode)) { + return false; + } + final List units = ((ArrayLiteralNode)expr).getUnits(); + return !(units == null || units.isEmpty()); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java deleted file mode 100644 index 61ccb712772..00000000000 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ /dev/null @@ -1,1947 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; -import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; -import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.LITERAL_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN; -import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; -import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; -import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS; -import static jdk.nashorn.internal.ir.Symbol.IS_ALWAYS_DEFINED; -import static jdk.nashorn.internal.ir.Symbol.IS_CONSTANT; -import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF; -import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL; -import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; -import static jdk.nashorn.internal.ir.Symbol.IS_LET; -import static jdk.nashorn.internal.ir.Symbol.IS_PARAM; -import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE; -import static jdk.nashorn.internal.ir.Symbol.IS_THIS; -import static jdk.nashorn.internal.ir.Symbol.IS_VAR; -import static jdk.nashorn.internal.ir.Symbol.KINDMASK; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.CallNode; -import jdk.nashorn.internal.ir.CaseNode; -import jdk.nashorn.internal.ir.CatchNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.ForNode; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.FunctionNode.CompilationState; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.IndexNode; -import jdk.nashorn.internal.ir.LexicalContext; -import jdk.nashorn.internal.ir.LexicalContextNode; -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ObjectNode; -import jdk.nashorn.internal.ir.ReturnNode; -import jdk.nashorn.internal.ir.RuntimeNode; -import jdk.nashorn.internal.ir.RuntimeNode.Request; -import jdk.nashorn.internal.ir.Statement; -import jdk.nashorn.internal.ir.SwitchNode; -import jdk.nashorn.internal.ir.Symbol; -import jdk.nashorn.internal.ir.TemporarySymbols; -import jdk.nashorn.internal.ir.TernaryNode; -import jdk.nashorn.internal.ir.TryNode; -import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.ir.VarNode; -import jdk.nashorn.internal.ir.WithNode; -import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; -import jdk.nashorn.internal.ir.visitor.NodeVisitor; -import jdk.nashorn.internal.parser.TokenType; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.Debug; -import jdk.nashorn.internal.runtime.DebugLogger; -import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.Property; -import jdk.nashorn.internal.runtime.PropertyMap; - -/** - * This is the attribution pass of the code generator. Attr takes Lowered IR, - * that is, IR where control flow has been computed and high level to low level - * substitions for operations have been performed. - * - * After Attr, every symbol will have a conservative correct type. - * - * Any expression that requires temporary storage as part of computation will - * also be detected here and give a temporary symbol - * - * Types can be narrowed after Attr by Access Specialization in FinalizeTypes, - * but in general, this is where the main symbol type information is - * computed. - */ - -final class Attr extends NodeOperatorVisitor { - - /** - * Local definitions in current block (to discriminate from function - * declarations always defined in the function scope. This is for - * "can be undefined" analysis. - */ - private final Deque> localDefs; - - /** - * Local definitions in current block to guard against cases like - * NASHORN-467 when things can be undefined as they are used before - * their local var definition. *sigh* JavaScript... - */ - private final Deque> localUses; - - private final Deque returnTypes; - - private int catchNestingLevel; - - private static final DebugLogger LOG = new DebugLogger("attr"); - private static final boolean DEBUG = LOG.isEnabled(); - - private final TemporarySymbols temporarySymbols; - - /** - * Constructor. - */ - Attr(final TemporarySymbols temporarySymbols) { - super(new LexicalContext()); - this.temporarySymbols = temporarySymbols; - this.localDefs = new ArrayDeque<>(); - this.localUses = new ArrayDeque<>(); - this.returnTypes = new ArrayDeque<>(); - } - - @Override - protected boolean enterDefault(final Node node) { - return start(node); - } - - @Override - protected Node leaveDefault(final Node node) { - return end(node); - } - - @Override - public Node leaveAccessNode(final AccessNode accessNode) { - //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this, that - //is why we can't set the access node base to be an object here, that will ruin access specialization - //for example for a.x | 17. - return end(ensureSymbol(Type.OBJECT, accessNode)); - } - - private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) { - initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL); - initCompileConstant(THIS, body, IS_PARAM | IS_THIS, Type.OBJECT); - - if (functionNode.isVarArg()) { - initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL); - if (functionNode.needsArguments()) { - initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); - final String argumentsName = ARGUMENTS_VAR.symbolName(); - newType(defineSymbol(body, argumentsName, IS_VAR | IS_ALWAYS_DEFINED), Type.typeFor(ARGUMENTS_VAR.type())); - addLocalDef(argumentsName); - } - } - - initParameters(functionNode, body); - initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); - initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.OBJECT); - } - - - /** - * This pushes all declarations (except for non-statements, i.e. for - * node temporaries) to the top of the function scope. This way we can - * get around problems like - * - * while (true) { - * break; - * if (true) { - * var s; - * } - * } - * - * to an arbitrary nesting depth. - * - * see NASHORN-73 - * - * @param functionNode the FunctionNode we are entering - * @param body the body of the FunctionNode we are entering - */ - private void acceptDeclarations(final FunctionNode functionNode, final Block body) { - // This visitor will assign symbol to all declared variables, except function declarations (which are taken care - // in a separate step above) and "var" declarations in for loop initializers. - // - // It also handles the case that a variable can be undefined, e.g - // if (cond) { - // x = x.y; - // } - // var x = 17; - // - // by making sure that no identifier has been found earlier in the body than the - // declaration - if such is the case the identifier is flagged as caBeUndefined to - // be safe if it turns into a local var. Otherwise corrupt bytecode results - - body.accept(new NodeVisitor(new LexicalContext()) { - private final Set uses = new HashSet<>(); - private final Set canBeUndefined = new HashSet<>(); - - @Override - public boolean enterFunctionNode(final FunctionNode nestedFn) { - return false; - } - - @Override - public Node leaveIdentNode(final IdentNode identNode) { - uses.add(identNode.getName()); - return identNode; - } - - @Override - public boolean enterVarNode(final VarNode varNode) { - final String name = varNode.getName().getName(); - //if this is used before the var node, the var node symbol needs to be tagged as can be undefined - if (uses.contains(name)) { - canBeUndefined.add(name); - } - - // all uses of the declared varnode inside the var node are potentially undefined - // however this is a bit conservative as e.g. var x = 17; var x = 1 + x; does work - if (!varNode.isFunctionDeclaration() && varNode.getInit() != null) { - varNode.getInit().accept(new NodeVisitor(new LexicalContext()) { - @Override - public boolean enterIdentNode(final IdentNode identNode) { - if (name.equals(identNode.getName())) { - canBeUndefined.add(name); - } - return false; - } - }); - } - - return true; - } - - @Override - public Node leaveVarNode(final VarNode varNode) { - // any declared symbols that aren't visited need to be typed as well, hence the list - if (varNode.isStatement()) { - final IdentNode ident = varNode.getName(); - final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR); - if (canBeUndefined.contains(ident.getName())) { - symbol.setType(Type.OBJECT); - symbol.setCanBeUndefined(); - } - functionNode.addDeclaredSymbol(symbol); - if (varNode.isFunctionDeclaration()) { - newType(symbol, FunctionNode.FUNCTION_TYPE); - symbol.setIsFunctionDeclaration(); - } - return varNode.setName((IdentNode)ident.setSymbol(lc, symbol)); - } - - return varNode; - } - }); - } - - private void enterFunctionBody() { - - final FunctionNode functionNode = lc.getCurrentFunction(); - final Block body = lc.getCurrentBlock(); - - initFunctionWideVariables(functionNode, body); - - if (functionNode.isProgram()) { - initFromPropertyMap(body); - } else if (!functionNode.isDeclared()) { - // It's neither declared nor program - it's a function expression then; assign it a self-symbol. - assert functionNode.getSymbol() == null; - - final boolean anonymous = functionNode.isAnonymous(); - final String name = anonymous ? null : functionNode.getIdent().getName(); - if (!(anonymous || body.getExistingSymbol(name) != null)) { - assert !anonymous && name != null; - newType(defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF), Type.OBJECT); - } - } - - acceptDeclarations(functionNode, body); - } - - @Override - public boolean enterBlock(final Block block) { - start(block); - //ensure that we don't use information from a previous compile. This is very ugly TODO - //the symbols in the block should really be stateless - block.clearSymbols(); - - if (lc.isFunctionBody()) { - enterFunctionBody(); - } - pushLocalsBlock(); - - return true; - } - - @Override - public Node leaveBlock(final Block block) { - popLocals(); - return end(block); - } - - @Override - public boolean enterCallNode(final CallNode callNode) { - return start(callNode); - } - - @Override - public Node leaveCallNode(final CallNode callNode) { - return end(ensureSymbol(callNode.getType(), callNode)); - } - - @Override - public boolean enterCatchNode(final CatchNode catchNode) { - final IdentNode exception = catchNode.getException(); - final Block block = lc.getCurrentBlock(); - - start(catchNode); - catchNestingLevel++; - - // define block-local exception variable - final String exname = exception.getName(); - final Symbol def = defineSymbol(block, exname, IS_VAR | IS_LET | IS_ALWAYS_DEFINED); - newType(def, Type.OBJECT); //we can catch anything, not just ecma exceptions - - addLocalDef(exname); - - return true; - } - - @Override - public Node leaveCatchNode(final CatchNode catchNode) { - final IdentNode exception = catchNode.getException(); - final Block block = lc.getCurrentBlock(); - final Symbol symbol = findSymbol(block, exception.getName()); - - catchNestingLevel--; - - assert symbol != null; - return end(catchNode.setException((IdentNode)exception.setSymbol(lc, symbol))); - } - - /** - * Declare the definition of a new symbol. - * - * @param name Name of symbol. - * @param symbolFlags Symbol flags. - * - * @return Symbol for given name or null for redefinition. - */ - private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) { - int flags = symbolFlags; - Symbol symbol = findSymbol(block, name); // Locate symbol. - boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL; - - if (isGlobal) { - flags |= IS_SCOPE; - } - - final FunctionNode function = lc.getFunction(block); - if (symbol != null) { - // Symbol was already defined. Check if it needs to be redefined. - if ((flags & KINDMASK) == IS_PARAM) { - if (!isLocal(function, symbol)) { - // Not defined in this function. Create a new definition. - symbol = null; - } else if (symbol.isParam()) { - // Duplicate parameter. Null return will force an error. - assert false : "duplicate parameter"; - return null; - } - } else if ((flags & KINDMASK) == IS_VAR) { - if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) { - // Always create a new definition. - symbol = null; - } else { - // Not defined in this function. Create a new definition. - if (!isLocal(function, symbol) || symbol.less(IS_VAR)) { - symbol = null; - } - } - } - } - - if (symbol == null) { - // If not found, then create a new one. - Block symbolBlock; - - // Determine where to create it. - if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) { - symbolBlock = block; //internal vars are always defined in the block closest to them - } else if (isGlobal) { - symbolBlock = lc.getOutermostFunction().getBody(); - } else { - symbolBlock = lc.getFunctionBody(function); - } - - // Create and add to appropriate block. - symbol = new Symbol(name, flags); - symbolBlock.putSymbol(lc, symbol); - - if ((flags & Symbol.KINDMASK) != IS_GLOBAL) { - symbol.setNeedsSlot(true); - } - } else if (symbol.less(flags)) { - symbol.setFlags(flags); - } - - return symbol; - } - - @Override - public boolean enterFunctionNode(final FunctionNode functionNode) { - start(functionNode, false); - - if (functionNode.isLazy()) { - return false; - } - - //an outermost function in our lexical context that is not a program (runScript) - //is possible - it is a function being compiled lazily - if (functionNode.isDeclared()) { - final Iterator blocks = lc.getBlocks(); - if (blocks.hasNext()) { - defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR); - } - } - - returnTypes.push(functionNode.getReturnType()); - pushLocalsFunction(); - - return true; - } - - @Override - public Node leaveFunctionNode(final FunctionNode functionNode) { - FunctionNode newFunctionNode = functionNode; - - final Block body = newFunctionNode.getBody(); - - //look for this function in the parent block - if (functionNode.isDeclared()) { - final Iterator blocks = lc.getBlocks(); - if (blocks.hasNext()) { - newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, findSymbol(blocks.next(), functionNode.getIdent().getName())); - } - } else if (!functionNode.isProgram()) { - final boolean anonymous = functionNode.isAnonymous(); - final String name = anonymous ? null : functionNode.getIdent().getName(); - if (anonymous || body.getExistingSymbol(name) != null) { - newFunctionNode = (FunctionNode)ensureSymbol(FunctionNode.FUNCTION_TYPE, newFunctionNode); - } else { - assert name != null; - final Symbol self = body.getExistingSymbol(name); - assert self != null && self.isFunctionSelf(); - newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, body.getExistingSymbol(name)); - } - } - - //unknown parameters are promoted to object type. - if (newFunctionNode.hasLazyChildren()) { - //the final body has already been assigned as we have left the function node block body by now - objectifySymbols(body); - } - newFunctionNode = finalizeParameters(newFunctionNode); - newFunctionNode = finalizeTypes(newFunctionNode); - for (final Symbol symbol : newFunctionNode.getDeclaredSymbols()) { - if (symbol.getSymbolType().isUnknown()) { - symbol.setType(Type.OBJECT); - symbol.setCanBeUndefined(); - } - } - - List syntheticInitializers = null; - - if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) { - syntheticInitializers = new ArrayList<>(2); - LOG.info("Accepting self symbol init for ", newFunctionNode.getName()); - // "var fn = :callee" - syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode)); - } - - if (newFunctionNode.needsArguments()) { - if (syntheticInitializers == null) { - syntheticInitializers = new ArrayList<>(1); - } - // "var arguments = :arguments" - syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()), - ARGUMENTS, newFunctionNode)); - } - - if (syntheticInitializers != null) { - final List stmts = newFunctionNode.getBody().getStatements(); - final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); - newStatements.addAll(syntheticInitializers); - newStatements.addAll(stmts); - newFunctionNode = newFunctionNode.setBody(lc, newFunctionNode.getBody().setStatements(lc, newStatements)); - } - - if (returnTypes.peek().isUnknown()) { - LOG.info("Unknown return type promoted to object"); - newFunctionNode = newFunctionNode.setReturnType(lc, Type.OBJECT); - } - final Type returnType = returnTypes.pop(); - newFunctionNode = newFunctionNode.setReturnType(lc, returnType.isUnknown() ? Type.OBJECT : returnType); - newFunctionNode = newFunctionNode.setState(lc, CompilationState.ATTR); - - popLocals(); - - end(newFunctionNode, false); - - return newFunctionNode; - } - - /** - * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically - * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function - * expressions as well as for assignment of {@code :arguments} to {@code arguments}. - * - * @param name the ident node identifying the variable to initialize - * @param initConstant the compiler constant it is initialized to - * @param fn the function node the assignment is for - * @return a var node with the appropriate assignment - */ - private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) { - final IdentNode init = compilerConstant(initConstant); - assert init.getSymbol() != null && init.getSymbol().hasSlot(); - - VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init); - - final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName()); - assert nameSymbol != null; - - return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol)); - } - - @Override - public Node leaveIdentNode(final IdentNode identNode) { - final String name = identNode.getName(); - - if (identNode.isPropertyName()) { - // assign a pseudo symbol to property name - final Symbol pseudoSymbol = pseudoSymbol(name); - LOG.info("IdentNode is property name -> assigning pseudo symbol ", pseudoSymbol); - LOG.unindent(); - return end(identNode.setSymbol(lc, pseudoSymbol)); - } - - final Block block = lc.getCurrentBlock(); - - Symbol symbol = findSymbol(block, name); - - //If an existing symbol with the name is found, use that otherwise, declare a new one - if (symbol != null) { - LOG.info("Existing symbol = ", symbol); - if (symbol.isFunctionSelf()) { - final FunctionNode functionNode = lc.getDefiningFunction(symbol); - assert functionNode != null; - assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null; - lc.setFlag(functionNode.getBody(), Block.NEEDS_SELF_SYMBOL); - newType(symbol, FunctionNode.FUNCTION_TYPE); - } else if (!identNode.isInitializedHere()) { - /* - * See NASHORN-448, JDK-8016235 - * - * Here is a use outside the local def scope - * the inCatch check is a conservative approach to handle things that might have only been - * defined in the try block, but with variable declarations, which due to JavaScript rules - * have to be lifted up into the function scope outside the try block anyway, but as the - * flow can fault at almost any place in the try block and get us to the catch block, all we - * know is that we have a declaration, not a definition. This can be made better and less - * conservative once we superimpose a CFG onto the AST. - */ - if (!isLocalDef(name) || inCatch()) { - newType(symbol, Type.OBJECT); - symbol.setCanBeUndefined(); - } - } - - // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already) - maybeForceScope(symbol); - } else { - LOG.info("No symbol exists. Declare undefined: ", symbol); - symbol = defineSymbol(block, name, IS_GLOBAL); - // we have never seen this before, it can be undefined - newType(symbol, Type.OBJECT); // TODO unknown -we have explicit casts anyway? - symbol.setCanBeUndefined(); - Symbol.setSymbolIsScope(lc, symbol); - } - - setBlockScope(name, symbol); - - if (!identNode.isInitializedHere()) { - symbol.increaseUseCount(); - } - addLocalUse(identNode.getName()); - - return end(identNode.setSymbol(lc, symbol)); - } - - private boolean inCatch() { - return catchNestingLevel > 0; - } - - /** - * If the symbol isn't already a scope symbol, and it is either not local to the current function, or it is being - * referenced from within a with block, we force it to be a scope symbol. - * @param symbol the symbol that might be scoped - */ - private void maybeForceScope(final Symbol symbol) { - if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) { - Symbol.setSymbolIsScope(lc, symbol); - } - } - - private boolean symbolNeedsToBeScope(Symbol symbol) { - if (symbol.isThis() || symbol.isInternal()) { - return false; - } - boolean previousWasBlock = false; - for (final Iterator it = lc.getAllNodes(); it.hasNext();) { - final LexicalContextNode node = it.next(); - if (node instanceof FunctionNode) { - // We reached the function boundary without seeing a definition for the symbol - it needs to be in - // scope. - return true; - } else if (node instanceof WithNode) { - if (previousWasBlock) { - // We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately - // preceded by a block, this means we're currently processing its expression, not its body, - // therefore it doesn't count. - return true; - } - previousWasBlock = false; - } else if (node instanceof Block) { - if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) { - // We reached the block that defines the symbol without reaching either the function boundary, or a - // WithNode. The symbol need not be scoped. - return false; - } - previousWasBlock = true; - } else { - previousWasBlock = false; - } - } - throw new AssertionError(); - } - - private void setBlockScope(final String name, final Symbol symbol) { - assert symbol != null; - if (symbol.isGlobal()) { - setUsesGlobalSymbol(); - return; - } - - if (symbol.isScope()) { - Block scopeBlock = null; - for (final Iterator contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) { - final LexicalContextNode node = contextNodeIter.next(); - if (node instanceof Block) { - if (((Block)node).getExistingSymbol(name) != null) { - scopeBlock = (Block)node; - break; - } - } else if (node instanceof FunctionNode) { - lc.setFlag(node, FunctionNode.USES_ANCESTOR_SCOPE); - } - } - - if (scopeBlock != null) { - assert lc.contains(scopeBlock); - lc.setBlockNeedsScope(scopeBlock); - } - } - } - - /** - * Marks the current function as one using any global symbol. The function and all its parent functions will all be - * marked as needing parent scope. - * @see #needsParentScope() - */ - private void setUsesGlobalSymbol() { - for (final Iterator fns = lc.getFunctions(); fns.hasNext();) { - lc.setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE); - } - } - - /** - * Search for symbol in the lexical context starting from the given block. - * @param name Symbol name. - * @return Found symbol or null if not found. - */ - private Symbol findSymbol(final Block block, final String name) { - // Search up block chain to locate symbol. - - for (final Iterator blocks = lc.getBlocks(block); blocks.hasNext();) { - // Find name. - final Symbol symbol = blocks.next().getExistingSymbol(name); - // If found then we are good. - if (symbol != null) { - return symbol; - } - } - return null; - } - - @Override - public Node leaveIndexNode(final IndexNode indexNode) { - return end(ensureSymbol(Type.OBJECT, indexNode)); - } - - @SuppressWarnings("rawtypes") - @Override - public Node leaveLiteralNode(final LiteralNode literalNode) { - assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens - assert literalNode instanceof ArrayLiteralNode || !(literalNode.getValue() instanceof Node) : "literals with Node values not supported"; - final Symbol symbol = new Symbol(lc.getCurrentFunction().uniqueName(LITERAL_PREFIX.symbolName()), IS_CONSTANT, literalNode.getType()); - if (literalNode instanceof ArrayLiteralNode) { - ((ArrayLiteralNode)literalNode).analyze(); - } - return end(literalNode.setSymbol(lc, symbol)); - } - - @Override - public boolean enterObjectNode(final ObjectNode objectNode) { - return start(objectNode); - } - - @Override - public Node leaveObjectNode(final ObjectNode objectNode) { - return end(ensureSymbol(Type.OBJECT, objectNode)); - } - - @Override - public Node leaveReturnNode(final ReturnNode returnNode) { - final Expression expr = returnNode.getExpression(); - final Type returnType; - - if (expr != null) { - //we can't do parameter specialization if we return something that hasn't been typed yet - final Symbol symbol = expr.getSymbol(); - if (expr.getType().isUnknown() && symbol.isParam()) { - symbol.setType(Type.OBJECT); - } - - returnType = widestReturnType(returnTypes.pop(), symbol.getSymbolType()); - } else { - returnType = Type.OBJECT; //undefined - } - LOG.info("Returntype is now ", returnType); - returnTypes.push(returnType); - - end(returnNode); - - return returnNode; - } - - @Override - public Node leaveSwitchNode(final SwitchNode switchNode) { - Type type = Type.UNKNOWN; - - final List newCases = new ArrayList<>(); - for (final CaseNode caseNode : switchNode.getCases()) { - final Node test = caseNode.getTest(); - - CaseNode newCaseNode = caseNode; - if (test != null) { - if (test instanceof LiteralNode) { - //go down to integers if we can - final LiteralNode lit = (LiteralNode)test; - if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) { - if (JSType.isRepresentableAsInt(lit.getNumber())) { - newCaseNode = caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this)); - } - } - } else { - // the "all integer" case that CodeGenerator optimizes for currently assumes literals only - type = Type.OBJECT; - } - - final Type newCaseType = newCaseNode.getTest().getType(); - if (newCaseType.isBoolean()) { - type = Type.OBJECT; //booleans and integers aren't assignment compatible - } else { - type = Type.widest(type, newCaseType); - } - } - - newCases.add(newCaseNode); - } - - //only optimize for all integers - if (!type.isInteger()) { - type = Type.OBJECT; - } - - switchNode.setTag(newInternal(lc.getCurrentFunction().uniqueName(SWITCH_TAG_PREFIX.symbolName()), type)); - - end(switchNode); - - return switchNode.setCases(lc, newCases); - } - - @Override - public Node leaveTryNode(final TryNode tryNode) { - tryNode.setException(exceptionSymbol()); - - if (tryNode.getFinallyBody() != null) { - tryNode.setFinallyCatchAll(exceptionSymbol()); - } - - end(tryNode); - - return tryNode; - } - - @Override - public boolean enterVarNode(final VarNode varNode) { - start(varNode); - - final IdentNode ident = varNode.getName(); - final String name = ident.getName(); - - final Symbol symbol = defineSymbol(lc.getCurrentBlock(), name, IS_VAR); - assert symbol != null; - - // NASHORN-467 - use before definition of vars - conservative - if (isLocalUse(ident.getName())) { - newType(symbol, Type.OBJECT); - symbol.setCanBeUndefined(); - } - - return true; - } - - @Override - public Node leaveVarNode(final VarNode varNode) { - final Expression init = varNode.getInit(); - final IdentNode ident = varNode.getName(); - final String name = ident.getName(); - - final Symbol symbol = findSymbol(lc.getCurrentBlock(), name); - assert ident.getSymbol() == symbol; - - if (init == null) { - // var x; with no init will be treated like a use of x by - // leaveIdentNode unless we remove the name from the localdef list. - removeLocalDef(name); - return end(varNode); - } - - addLocalDef(name); - - assert symbol != null; - - final IdentNode newIdent = (IdentNode)ident.setSymbol(lc, symbol); - - final VarNode newVarNode = varNode.setName(newIdent); - - final boolean isScript = lc.getDefiningFunction(symbol).isProgram(); //see NASHORN-56 - if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) { - // Forbid integers as local vars for now as we have no way to treat them as undefined - newType(symbol, init.getType()); - } else { - newType(symbol, Type.OBJECT); - } - - assert newVarNode.getName().hasType() : newVarNode + " has no type"; - - return end(newVarNode); - } - - @Override - public Node leaveADD(final UnaryNode unaryNode) { - return end(ensureSymbol(arithType(), unaryNode)); - } - - @Override - public Node leaveBIT_NOT(final UnaryNode unaryNode) { - return end(ensureSymbol(Type.INT, unaryNode)); - } - - @Override - public Node leaveDECINC(final UnaryNode unaryNode) { - // @see assignOffset - final Type type = arithType(); - newType(unaryNode.rhs().getSymbol(), type); - return end(ensureSymbol(type, unaryNode)); - } - - @Override - public Node leaveDELETE(final UnaryNode unaryNode) { - final FunctionNode currentFunctionNode = lc.getCurrentFunction(); - final boolean strictMode = currentFunctionNode.isStrict(); - final Expression rhs = unaryNode.rhs(); - final Expression strictFlagNode = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this); - - Request request = Request.DELETE; - final List args = new ArrayList<>(); - - if (rhs instanceof IdentNode) { - // If this is a declared variable or a function parameter, delete always fails (except for globals). - final String name = ((IdentNode)rhs).getName(); - - final boolean failDelete = strictMode || rhs.getSymbol().isParam() || (rhs.getSymbol().isVar() && !isProgramLevelSymbol(name)); - - if (failDelete && rhs.getSymbol().isThis()) { - return LiteralNode.newInstance(unaryNode, true).accept(this); - } - final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this); - - if (!failDelete) { - args.add(compilerConstant(SCOPE)); - } - args.add(literalNode); - args.add(strictFlagNode); - - if (failDelete) { - request = Request.FAIL_DELETE; - } - } else if (rhs instanceof AccessNode) { - final Expression base = ((AccessNode)rhs).getBase(); - final IdentNode property = ((AccessNode)rhs).getProperty(); - - args.add(base); - args.add((Expression)LiteralNode.newInstance(unaryNode, property.getName()).accept(this)); - args.add(strictFlagNode); - - } else if (rhs instanceof IndexNode) { - final IndexNode indexNode = (IndexNode)rhs; - final Expression base = indexNode.getBase(); - final Expression index = indexNode.getIndex(); - - args.add(base); - args.add(index); - args.add(strictFlagNode); - - } else { - return LiteralNode.newInstance(unaryNode, true).accept(this); - } - - final RuntimeNode runtimeNode = new RuntimeNode(unaryNode, request, args); - assert runtimeNode.getSymbol() == unaryNode.getSymbol(); //unary parent constructor should do this - - return leaveRuntimeNode(runtimeNode); - } - - /** - * Is the symbol denoted by the specified name in the current lexical context defined in the program level - * @param name the name of the symbol - * @return true if the symbol denoted by the specified name in the current lexical context defined in the program level. - */ - private boolean isProgramLevelSymbol(final String name) { - for(final Iterator it = lc.getBlocks(); it.hasNext();) { - final Block next = it.next(); - if(next.getExistingSymbol(name) != null) { - return next == lc.getFunctionBody(lc.getOutermostFunction()); - } - } - throw new AssertionError("Couldn't find symbol " + name + " in the context"); - } - - @Override - public Node leaveNEW(final UnaryNode unaryNode) { - return end(ensureSymbol(Type.OBJECT, unaryNode.setRHS(((CallNode)unaryNode.rhs()).setIsNew()))); - } - - @Override - public Node leaveNOT(final UnaryNode unaryNode) { - return end(ensureSymbol(Type.BOOLEAN, unaryNode)); - } - - private IdentNode compilerConstant(CompilerConstants cc) { - return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc, lc.getCurrentFunction().compilerConstant(cc)); - } - - /** - * Creates an ident node for an implicit identifier within the function (one not declared in the script source - * code). These identifiers are defined with function's token and finish. - * @param name the name of the identifier - * @return an ident node representing the implicit identifier. - */ - private IdentNode createImplicitIdentifier(final String name) { - final FunctionNode fn = lc.getCurrentFunction(); - return new IdentNode(fn.getToken(), fn.getFinish(), name); - } - - @Override - public Node leaveTYPEOF(final UnaryNode unaryNode) { - final Expression rhs = unaryNode.rhs(); - - List args = new ArrayList<>(); - if (rhs instanceof IdentNode && !rhs.getSymbol().isParam() && !rhs.getSymbol().isVar()) { - args.add(compilerConstant(SCOPE)); - args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null - } else { - args.add(rhs); - args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this' - } - - RuntimeNode runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args); - assert runtimeNode.getSymbol() == unaryNode.getSymbol(); - - runtimeNode = (RuntimeNode)leaveRuntimeNode(runtimeNode); - - end(unaryNode); - - return runtimeNode; - } - - @Override - public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { - return end(ensureSymbol(runtimeNode.getRequest().getReturnType(), runtimeNode)); - } - - @Override - public Node leaveSUB(final UnaryNode unaryNode) { - return end(ensureSymbol(arithType(), unaryNode)); - } - - @Override - public Node leaveVOID(final UnaryNode unaryNode) { - return end(ensureSymbol(Type.OBJECT, unaryNode)); - } - - /** - * Add is a special binary, as it works not only on arithmetic, but for - * strings etc as well. - */ - @Override - public Node leaveADD(final BinaryNode binaryNode) { - final Expression lhs = binaryNode.lhs(); - final Expression rhs = binaryNode.rhs(); - - ensureTypeNotUnknown(lhs); - ensureTypeNotUnknown(rhs); - //even if we are adding two known types, this can overflow. i.e. - //int and number -> number. - //int and int are also number though. - //something and object is object - return end(ensureSymbol(Type.widest(arithType(), Type.widest(lhs.getType(), rhs.getType())), binaryNode)); - } - - @Override - public Node leaveAND(final BinaryNode binaryNode) { - return end(ensureSymbol(Type.OBJECT, binaryNode)); - } - - /** - * This is a helper called before an assignment. - * @param binaryNode assignment node - */ - private boolean enterAssignmentNode(final BinaryNode binaryNode) { - start(binaryNode); - - return true; - } - - - /** - * This assign helper is called after an assignment, when all children of - * the assign has been processed. It fixes the types and recursively makes - * sure that everyhing has slots that should have them in the chain. - * - * @param binaryNode assignment node - */ - private Node leaveAssignmentNode(final BinaryNode binaryNode) { - final Expression lhs = binaryNode.lhs(); - final Expression rhs = binaryNode.rhs(); - final Type type; - - if (lhs instanceof IdentNode) { - final Block block = lc.getCurrentBlock(); - final IdentNode ident = (IdentNode)lhs; - final String name = ident.getName(); - final Symbol symbol = findSymbol(block, name); - - if (symbol == null) { - defineSymbol(block, name, IS_GLOBAL); - } else { - maybeForceScope(symbol); - } - - addLocalDef(name); - } - - if (rhs.getType().isNumeric()) { - type = Type.widest(lhs.getType(), rhs.getType()); - } else { - type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too. - } - - newType(lhs.getSymbol(), type); - return end(ensureSymbol(type, binaryNode)); - } - - private boolean isLocal(FunctionNode function, Symbol symbol) { - final FunctionNode definingFn = lc.getDefiningFunction(symbol); - // Temp symbols are not assigned to a block, so their defining fn is null; those can be assumed local - return definingFn == null || definingFn == function; - } - - @Override - public boolean enterASSIGN(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN(final BinaryNode binaryNode) { - return leaveAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_ADD(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_ADD(final BinaryNode binaryNode) { - final Expression lhs = binaryNode.lhs(); - final Expression rhs = binaryNode.rhs(); - - final Type widest = Type.widest(lhs.getType(), rhs.getType()); - //Type.NUMBER if we can't prove that the add doesn't overflow. todo - return leaveSelfModifyingAssignmentNode(binaryNode, widest.isNumeric() ? Type.NUMBER : Type.OBJECT); - } - - @Override - public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_DIV(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_DIV(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_MOD(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_MOD(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_MUL(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_MUL(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_SAR(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_SAR(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_SHL(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_SHL(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_SHR(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_SHR(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public boolean enterASSIGN_SUB(final BinaryNode binaryNode) { - return enterAssignmentNode(binaryNode); - } - - @Override - public Node leaveASSIGN_SUB(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode); - } - - @Override - public Node leaveBIT_AND(final BinaryNode binaryNode) { - return end(coerce(binaryNode, Type.INT)); - } - - @Override - public Node leaveBIT_OR(final BinaryNode binaryNode) { - return end(coerce(binaryNode, Type.INT)); - } - - @Override - public Node leaveBIT_XOR(final BinaryNode binaryNode) { - return end(coerce(binaryNode, Type.INT)); - } - - @Override - public Node leaveCOMMARIGHT(final BinaryNode binaryNode) { - return leaveComma(binaryNode, binaryNode.rhs()); - } - - @Override - public Node leaveCOMMALEFT(final BinaryNode binaryNode) { - return leaveComma(binaryNode, binaryNode.lhs()); - } - - private Node leaveComma(final BinaryNode commaNode, final Expression effectiveExpr) { - ensureTypeNotUnknown(effectiveExpr); - return end(ensureSymbol(effectiveExpr.getType(), commaNode)); - } - - @Override - public Node leaveDIV(final BinaryNode binaryNode) { - return leaveBinaryArithmetic(binaryNode); - } - - private Node leaveCmp(final BinaryNode binaryNode) { - ensureTypeNotUnknown(binaryNode.lhs()); - ensureTypeNotUnknown(binaryNode.rhs()); - Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()); - ensureSymbol(widest, binaryNode.lhs()); - ensureSymbol(widest, binaryNode.rhs()); - return end(ensureSymbol(Type.BOOLEAN, binaryNode)); - } - - private Node coerce(final BinaryNode binaryNode, final Type operandType, final Type destType) { - // TODO we currently don't support changing inferred type based on uses, only on - // definitions. we would need some additional logic. We probably want to do that - // in the future, if e.g. a specialized method gets parameter that is only used - // as, say, an int : function(x) { return x & 4711 }, and x is not defined in - // the function. to make this work, uncomment the following two type inferences - // and debug. - //newType(binaryNode.lhs().getSymbol(), operandType); - //newType(binaryNode.rhs().getSymbol(), operandType); - return ensureSymbol(destType, binaryNode); - } - - private Node coerce(final BinaryNode binaryNode, final Type type) { - return coerce(binaryNode, type, type); - } - - //leave a binary node and inherit the widest type of lhs , rhs - private Node leaveBinaryArithmetic(final BinaryNode binaryNode) { - assert !Compiler.shouldUseIntegerArithmetic(); - return end(coerce(binaryNode, Type.NUMBER)); - } - - @Override - public Node leaveEQ(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveEQ_STRICT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveGE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveGT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveIN(final BinaryNode binaryNode) { - return leaveBinaryRuntimeOperator(binaryNode, Request.IN); - } - - @Override - public Node leaveINSTANCEOF(final BinaryNode binaryNode) { - return leaveBinaryRuntimeOperator(binaryNode, Request.INSTANCEOF); - } - - private Node leaveBinaryRuntimeOperator(final BinaryNode binaryNode, final Request request) { - try { - // Don't do a full RuntimeNode.accept, as we don't want to double-visit the binary node operands - return leaveRuntimeNode(new RuntimeNode(binaryNode, request)); - } finally { - end(binaryNode); - } - } - - @Override - public Node leaveLE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveLT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveMOD(final BinaryNode binaryNode) { - return leaveBinaryArithmetic(binaryNode); - } - - @Override - public Node leaveMUL(final BinaryNode binaryNode) { - return leaveBinaryArithmetic(binaryNode); - } - - @Override - public Node leaveNE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveNE_STRICT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode); - } - - @Override - public Node leaveOR(final BinaryNode binaryNode) { - return end(ensureSymbol(Type.OBJECT, binaryNode)); - } - - @Override - public Node leaveSAR(final BinaryNode binaryNode) { - return end(coerce(binaryNode, Type.INT)); - } - - @Override - public Node leaveSHL(final BinaryNode binaryNode) { - return end(coerce(binaryNode, Type.INT)); - } - - @Override - public Node leaveSHR(final BinaryNode binaryNode) { - return end(coerce(binaryNode, Type.LONG)); - } - - @Override - public Node leaveSUB(final BinaryNode binaryNode) { - return leaveBinaryArithmetic(binaryNode); - } - - @Override - public Node leaveForNode(final ForNode forNode) { - if (forNode.isForIn()) { - forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.typeFor(ITERATOR_PREFIX.type()))); //NASHORN-73 - /* - * Iterators return objects, so we need to widen the scope of the - * init variable if it, for example, has been assigned double type - * see NASHORN-50 - */ - newType(forNode.getInit().getSymbol(), Type.OBJECT); - } - - end(forNode); - - return forNode; - } - - @Override - public Node leaveTernaryNode(final TernaryNode ternaryNode) { - final Expression trueExpr = ternaryNode.getTrueExpression(); - final Expression falseExpr = ternaryNode.getFalseExpression(); - - ensureTypeNotUnknown(trueExpr); - ensureTypeNotUnknown(falseExpr); - - final Type type = widestReturnType(trueExpr.getType(), falseExpr.getType()); - return end(ensureSymbol(type, ternaryNode)); - } - - /** - * When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to - * anything other than Object. Also, widening a numeric type to an object type must widen to Object proper and not - * any more specific subclass (e.g. widest of int/long/double and String is Object). - * @param t1 type 1 - * @param t2 type 2 - * @return wider of t1 and t2, except if one is boolean and the other is neither boolean nor unknown, or if one is - * numeric and the other is neither numeric nor unknown in which case {@code Type.OBJECT} is returned. - */ - private static Type widestReturnType(final Type t1, final Type t2) { - if (t1.isUnknown()) { - return t2; - } else if (t2.isUnknown()) { - return t1; - } else if (t1.isBoolean() != t2.isBoolean() || t1.isNumeric() != t2.isNumeric()) { - return Type.OBJECT; - } - return Type.widest(t1, t2); - } - - private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) { - final Class type = cc.type(); - // Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead. - assert type != null; - initCompileConstant(cc, block, flags, Type.typeFor(type)); - } - - private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags, final Type type) { - final Symbol symbol = defineSymbol(block, cc.symbolName(), flags); - symbol.setTypeOverride(type); - symbol.setNeedsSlot(true); - } - - /** - * Initialize parameters for function node. This may require specializing - * types if a specialization profile is known - * - * @param functionNode the function node - */ - private void initParameters(final FunctionNode functionNode, final Block body) { - int pos = 0; - for (final IdentNode param : functionNode.getParameters()) { - addLocalDef(param.getName()); - - final Type callSiteParamType = functionNode.getHints().getParameterType(pos); - int flags = IS_PARAM; - if (callSiteParamType != null) { - LOG.info("Param ", param, " has a callsite type ", callSiteParamType, ". Using that."); - flags |= Symbol.IS_SPECIALIZED_PARAM; - } - - final Symbol paramSymbol = defineSymbol(body, param.getName(), flags); - assert paramSymbol != null; - - newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType); - - LOG.info("Initialized param ", pos, "=", paramSymbol); - pos++; - } - - } - - /** - * This has to run before fix assignment types, store any type specializations for - * paramters, then turn then to objects for the generic version of this method - * - * @param functionNode functionNode - */ - private FunctionNode finalizeParameters(final FunctionNode functionNode) { - final List newParams = new ArrayList<>(); - final boolean isVarArg = functionNode.isVarArg(); - final int nparams = functionNode.getParameters().size(); - - int specialize = 0; - int pos = 0; - for (final IdentNode param : functionNode.getParameters()) { - final Symbol paramSymbol = functionNode.getBody().getExistingSymbol(param.getName()); - assert paramSymbol != null; - assert paramSymbol.isParam(); - newParams.add((IdentNode)param.setSymbol(lc, paramSymbol)); - - assert paramSymbol != null; - Type type = functionNode.getHints().getParameterType(pos); - if (type == null) { - type = Type.OBJECT; - } - - // if we know that a parameter is only used as a certain type throughout - // this function, we can tell the runtime system that no matter what the - // call site is, use this information: - // we also need more than half of the parameters to be specializable - // for the heuristic to be worth it, and we need more than one use of - // the parameter to consider it, i.e. function(x) { call(x); } doens't count - if (paramSymbol.getUseCount() > 1 && !paramSymbol.getSymbolType().isObject()) { - LOG.finest("Parameter ", param, " could profit from specialization to ", paramSymbol.getSymbolType()); - specialize++; - } - - newType(paramSymbol, Type.widest(type, paramSymbol.getSymbolType())); - - // parameters should not be slots for a function that uses variable arity signature - if (isVarArg) { - paramSymbol.setNeedsSlot(false); - } - - pos++; - } - - FunctionNode newFunctionNode = functionNode; - - if (nparams == 0 || (specialize * 2) < nparams) { - newFunctionNode = newFunctionNode.clearSnapshot(lc); - } - - return newFunctionNode.setParameters(lc, newParams); - } - - /** - * Move any properties from a global map into the scope of this method - * @param block the function node body for which to init scope vars - */ - private void initFromPropertyMap(final Block block) { - // For a script, add scope symbols as defined in the property map - - final PropertyMap map = Context.getGlobalMap(); - - for (final Property property : map.getProperties()) { - final String key = property.getKey(); - final Symbol symbol = defineSymbol(block, key, IS_GLOBAL); - newType(symbol, Type.OBJECT); - LOG.info("Added global symbol from property map ", symbol); - } - } - - private static void ensureTypeNotUnknown(final Expression node) { - - final Symbol symbol = node.getSymbol(); - - LOG.info("Ensure type not unknown for: ", symbol); - - /* - * Note that not just unknowns, but params need to be blown - * up to objects, because we can have something like - * - * function f(a) { - * var b = ~a; //b and a are inferred to be int - * return b; - * } - * - * In this case, it would be correct to say that "if you have - * an int at the callsite, just pass it". - * - * However - * - * function f(a) { - * var b = ~a; //b and a are inferred to be int - * return b == 17; //b is still inferred to be int. - * } - * - * can be called with f("17") and if we assume that b is an - * int and don't blow it up to an object in the comparison, we - * are screwed. I hate JavaScript. - * - * This check has to be done for any operation that might take - * objects as parameters, for example +, but not *, which is known - * to coerce types into doubles - */ - if (node.getType().isUnknown() || (symbol.isParam() && !symbol.isSpecializedParam())) { - newType(symbol, Type.OBJECT); - symbol.setCanBeUndefined(); - } - } - - private static Symbol pseudoSymbol(final String name) { - return new Symbol(name, 0, Type.OBJECT); - } - - private Symbol exceptionSymbol() { - return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type())); - } - - /** - * Return the type that arithmetic ops should use. Until we have implemented better type - * analysis (range based) or overflow checks that are fast enough for int arithmetic, - * this is the number type - * @return the arithetic type - */ - private static Type arithType() { - return Compiler.shouldUseIntegerArithmetic() ? Type.INT : Type.NUMBER; - } - - /** - * If types have changed, we can have failed to update vars. For example - * - * var x = 17; //x is int - * x = "apa"; //x is object. This will be converted fine - * - * @param functionNode - */ - private FunctionNode finalizeTypes(final FunctionNode functionNode) { - final Set changed = new HashSet<>(); - FunctionNode currentFunctionNode = functionNode; - do { - changed.clear(); - final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor(new LexicalContext()) { - - private Expression widen(final Expression node, final Type to) { - if (node instanceof LiteralNode) { - return node; - } - Type from = node.getType(); - if (!Type.areEquivalent(from, to) && Type.widest(from, to) == to) { - LOG.fine("Had to post pass widen '", node, "' ", Debug.id(node), " from ", node.getType(), " to ", to); - Symbol symbol = node.getSymbol(); - if (symbol.isShared() && symbol.wouldChangeType(to)) { - symbol = temporarySymbols.getTypedTemporarySymbol(to); - } - newType(symbol, to); - final Expression newNode = node.setSymbol(lc, symbol); - changed.add(newNode); - return newNode; - } - return node; - } - - @Override - public boolean enterFunctionNode(final FunctionNode node) { - return !node.isLazy(); - } - - // - // Eg. - // - // var d = 17; - // var e; - // e = d; //initially typed as int for node type, should retype as double - // e = object; - // - // var d = 17; - // var e; - // e -= d; //initially type number, should number remain with a final conversion supplied by Store. ugly, but the computation result of the sub is numeric - // e = object; - // - @SuppressWarnings("fallthrough") - @Override - public Node leaveBinaryNode(final BinaryNode binaryNode) { - final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()); - BinaryNode newBinaryNode = binaryNode; - - if (isAdd(binaryNode)) { - newBinaryNode = (BinaryNode)widen(newBinaryNode, widest); - if (newBinaryNode.getType().isObject() && !isAddString(newBinaryNode)) { - return new RuntimeNode(newBinaryNode, Request.ADD); - } - } else if (binaryNode.isComparison()) { - final Expression lhs = newBinaryNode.lhs(); - final Expression rhs = newBinaryNode.rhs(); - - Type cmpWidest = Type.widest(lhs.getType(), rhs.getType()); - - boolean newRuntimeNode = false, finalized = false; - switch (newBinaryNode.tokenType()) { - case EQ_STRICT: - case NE_STRICT: - if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) { - newRuntimeNode = true; - cmpWidest = Type.OBJECT; - finalized = true; - } - //fallthru - default: - if (newRuntimeNode || cmpWidest.isObject()) { - return new RuntimeNode(newBinaryNode, Request.requestFor(binaryNode)).setIsFinal(finalized); - } - break; - } - - return newBinaryNode; - } else { - if (!binaryNode.isAssignment() || binaryNode.isSelfModifying()) { - return newBinaryNode; - } - checkThisAssignment(binaryNode); - newBinaryNode = newBinaryNode.setLHS(widen(newBinaryNode.lhs(), widest)); - newBinaryNode = (BinaryNode)widen(newBinaryNode, widest); - } - - return newBinaryNode; - - } - - private boolean isAdd(final Node node) { - return node.isTokenType(TokenType.ADD); - } - - /** - * Determine if the outcome of + operator is a string. - * - * @param node Node to test. - * @return true if a string result. - */ - private boolean isAddString(final Node node) { - if (node instanceof BinaryNode && isAdd(node)) { - final BinaryNode binaryNode = (BinaryNode)node; - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); - - return isAddString(lhs) || isAddString(rhs); - } - - return node instanceof LiteralNode && ((LiteralNode)node).isString(); - } - - private void checkThisAssignment(final BinaryNode binaryNode) { - if (binaryNode.isAssignment()) { - if (binaryNode.lhs() instanceof AccessNode) { - final AccessNode accessNode = (AccessNode) binaryNode.lhs(); - - if (accessNode.getBase().getSymbol().isThis()) { - lc.getCurrentFunction().addThisProperty(accessNode.getProperty().getName()); - } - } - } - } - }); - lc.replace(currentFunctionNode, newFunctionNode); - currentFunctionNode = newFunctionNode; - } while (!changed.isEmpty()); - - return currentFunctionNode; - } - - private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode) { - return leaveSelfModifyingAssignmentNode(binaryNode, binaryNode.getWidestOperationType()); - } - - private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode, final Type destType) { - //e.g. for -=, Number, no wider, destType (binaryNode.getWidestOperationType()) is the coerce type - final Expression lhs = binaryNode.lhs(); - - newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType - - return end(ensureSymbol(destType, binaryNode)); - } - - private Expression ensureSymbol(final Type type, final Expression expr) { - LOG.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type); - return temporarySymbols.ensureSymbol(lc, type, expr); - } - - private Symbol newInternal(final String name, final Type type) { - final Symbol iter = defineSymbol(lc.getCurrentBlock(), name, IS_VAR | IS_INTERNAL); - iter.setType(type); // NASHORN-73 - return iter; - } - - private static void newType(final Symbol symbol, final Type type) { - final Type oldType = symbol.getSymbolType(); - symbol.setType(type); - - if (symbol.getSymbolType() != oldType) { - LOG.info("New TYPE ", type, " for ", symbol," (was ", oldType, ")"); - } - - if (symbol.isParam()) { - symbol.setType(type); - LOG.info("Param type change ", symbol); - } - } - - private void pushLocalsFunction() { - localDefs.push(new HashSet()); - localUses.push(new HashSet()); - } - - private void pushLocalsBlock() { - localDefs.push(new HashSet<>(localDefs.peek())); - localUses.push(new HashSet<>(localUses.peek())); - } - - private void popLocals() { - localDefs.pop(); - localUses.pop(); - } - - private boolean isLocalDef(final String name) { - return localDefs.peek().contains(name); - } - - private void addLocalDef(final String name) { - LOG.info("Adding local def of symbol: '", name, "'"); - localDefs.peek().add(name); - } - - private void removeLocalDef(final String name) { - LOG.info("Removing local def of symbol: '", name, "'"); - localDefs.peek().remove(name); - } - - private boolean isLocalUse(final String name) { - return localUses.peek().contains(name); - } - - private void addLocalUse(final String name) { - LOG.info("Adding local use of symbol: '", name, "'"); - localUses.peek().add(name); - } - - /** - * Pessimistically promote all symbols in current function node to Object types - * This is done when the function contains unevaluated black boxes such as - * lazy sub-function nodes that have not been compiled. - * - * @param body body for the function node we are leaving - */ - private static void objectifySymbols(final Block body) { - body.accept(new NodeVisitor(new LexicalContext()) { - private void toObject(final Block block) { - for (final Symbol symbol : block.getSymbols()) { - if (!symbol.isTemp()) { - newType(symbol, Type.OBJECT); - } - } - } - - @Override - public boolean enterBlock(final Block block) { - toObject(block); - return true; - } - - @Override - public boolean enterFunctionNode(final FunctionNode node) { - return false; - } - }); - } - - private static String name(final Node node) { - final String cn = node.getClass().getName(); - int lastDot = cn.lastIndexOf('.'); - if (lastDot == -1) { - return cn; - } - return cn.substring(lastDot + 1); - } - - private boolean start(final Node node) { - return start(node, true); - } - - private boolean start(final Node node, final boolean printNode) { - if (DEBUG) { - final StringBuilder sb = new StringBuilder(); - - sb.append("[ENTER "). - append(name(node)). - append("] "). - append(printNode ? node.toString() : ""). - append(" in '"). - append(lc.getCurrentFunction().getName()). - append("'"); - LOG.info(sb); - LOG.indent(); - } - - return true; - } - - private T end(final T node) { - return end(node, true); - } - - private T end(final T node, final boolean printNode) { - if(node instanceof Statement) { - // If we're done with a statement, all temporaries can be reused. - temporarySymbols.reuse(); - } - if (DEBUG) { - final StringBuilder sb = new StringBuilder(); - - sb.append("[LEAVE "). - append(name(node)). - append("] "). - append(printNode ? node.toString() : ""). - append(" in '"). - append(lc.getCurrentFunction().getName()). - append('\''); - - if (node instanceof Expression) { - final Symbol symbol = ((Expression)node).getSymbol(); - if (symbol == null) { - sb.append(" "); - } else { - sb.append(" '); - } - } - - LOG.unindent(); - LOG.info(sb); - } - - return node; - } -} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java index ad9bdb07436..5c8f96454ef 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java @@ -32,10 +32,10 @@ import static jdk.nashorn.internal.codegen.Condition.LE; import static jdk.nashorn.internal.codegen.Condition.LT; import static jdk.nashorn.internal.codegen.Condition.NE; -import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.TernaryNode; +import jdk.nashorn.internal.ir.JoinPredecessorExpression; +import jdk.nashorn.internal.ir.LocalVariableConversion; import jdk.nashorn.internal.ir.UnaryNode; /** @@ -57,7 +57,7 @@ final class BranchOptimizer { } private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) { - final Expression rhs = unaryNode.rhs(); + final Expression rhs = unaryNode.getExpression(); switch (unaryNode.tokenType()) { case NOT: @@ -71,13 +71,7 @@ final class BranchOptimizer { break; } - // convert to boolean - codegen.load(unaryNode, Type.BOOLEAN); - if (state) { - method.ifne(label); - } else { - method.ifeq(label); - } + loadTestAndJump(unaryNode, label, state); } private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) { @@ -88,86 +82,97 @@ final class BranchOptimizer { case AND: if (state) { final Label skip = new Label("skip"); - branchOptimizer(lhs, skip, false); - branchOptimizer(rhs, label, true); + optimizeLogicalOperand(lhs, skip, false, false); + optimizeLogicalOperand(rhs, label, true, true); method.label(skip); } else { - branchOptimizer(lhs, label, false); - branchOptimizer(rhs, label, false); + optimizeLogicalOperand(lhs, label, false, false); + optimizeLogicalOperand(rhs, label, false, true); } return; case OR: if (state) { - branchOptimizer(lhs, label, true); - branchOptimizer(rhs, label, true); + optimizeLogicalOperand(lhs, label, true, false); + optimizeLogicalOperand(rhs, label, true, true); } else { final Label skip = new Label("skip"); - branchOptimizer(lhs, skip, true); - branchOptimizer(rhs, label, false); + optimizeLogicalOperand(lhs, skip, true, false); + optimizeLogicalOperand(rhs, label, false, true); method.label(skip); } return; case EQ: case EQ_STRICT: - codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); + codegen.loadBinaryOperands(binaryNode); method.conditionalJump(state ? EQ : NE, true, label); return; case NE: case NE_STRICT: - codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); + codegen.loadBinaryOperands(binaryNode); method.conditionalJump(state ? NE : EQ, true, label); return; case GE: - codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); - method.conditionalJump(state ? GE : LT, !state, label); + codegen.loadBinaryOperands(binaryNode); + method.conditionalJump(state ? GE : LT, false, label); return; case GT: - codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); - method.conditionalJump(state ? GT : LE, !state, label); + codegen.loadBinaryOperands(binaryNode); + method.conditionalJump(state ? GT : LE, false, label); return; case LE: - codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); - method.conditionalJump(state ? LE : GT, state, label); + codegen.loadBinaryOperands(binaryNode); + method.conditionalJump(state ? LE : GT, true, label); return; case LT: - codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType())); - method.conditionalJump(state ? LT : GE, state, label); + codegen.loadBinaryOperands(binaryNode); + method.conditionalJump(state ? LT : GE, true, label); return; default: break; } - codegen.load(binaryNode, Type.BOOLEAN); - if (state) { - method.ifne(label); - } else { - method.ifeq(label); - } + loadTestAndJump(binaryNode, label, state); } + private void optimizeLogicalOperand(final Expression expr, final Label label, final boolean state, final boolean isRhs) { + final JoinPredecessorExpression jpexpr = (JoinPredecessorExpression)expr; + if(LocalVariableConversion.hasLiveConversion(jpexpr)) { + final Label after = new Label("after"); + branchOptimizer(jpexpr.getExpression(), after, !state); + method.beforeJoinPoint(jpexpr); + method._goto(label); + method.label(after); + if(isRhs) { + method.beforeJoinPoint(jpexpr); + } + } else { + branchOptimizer(jpexpr.getExpression(), label, state); + } + } private void branchOptimizer(final Expression node, final Label label, final boolean state) { - if (!(node instanceof TernaryNode)) { - - if (node instanceof BinaryNode) { - branchOptimizer((BinaryNode)node, label, state); - return; - } - - if (node instanceof UnaryNode) { - branchOptimizer((UnaryNode)node, label, state); - return; - } + if (node instanceof BinaryNode) { + branchOptimizer((BinaryNode)node, label, state); + return; } - codegen.load(node, Type.BOOLEAN); + if (node instanceof UnaryNode) { + branchOptimizer((UnaryNode)node, label, state); + return; + } + + loadTestAndJump(node, label, state); + } + + private void loadTestAndJump(final Expression node, final Label label, final boolean state) { + codegen.loadExpressionAsBoolean(node); if (state) { method.ifne(label); } else { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java index 09c6a0651cb..386effdc120 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java @@ -49,25 +49,27 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE; import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; import static jdk.nashorn.internal.codegen.CompilerConstants.className; import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; -import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; +import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; -import java.util.Arrays; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.EnumSet; import java.util.HashSet; import java.util.Set; - -import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.util.TraceClassVisitor; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.SplitNode; +import jdk.nashorn.internal.ir.debug.NashornClassReader; +import jdk.nashorn.internal.ir.debug.NashornTextifier; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.PropertyMap; -import jdk.nashorn.internal.runtime.ScriptEnvironment; +import jdk.nashorn.internal.runtime.RewriteException; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.Source; @@ -106,6 +108,8 @@ import jdk.nashorn.internal.runtime.Source; * @see Compiler */ public class ClassEmitter implements Emitter { + /** Default flags for class generation - public class */ + private static final EnumSet DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC); /** Sanity check flag - have we started on a class? */ private boolean classStarted; @@ -123,10 +127,7 @@ public class ClassEmitter implements Emitter { protected final ClassWriter cw; /** The script environment */ - protected final ScriptEnvironment env; - - /** Default flags for class generation - oublic class */ - private static final EnumSet DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC); + protected final Context context; /** Compile unit class name. */ private String unitClassName; @@ -141,10 +142,8 @@ public class ClassEmitter implements Emitter { * @param env script environment * @param cw ASM classwriter */ - private ClassEmitter(final ScriptEnvironment env, final ClassWriter cw) { - assert env != null; - - this.env = env; + private ClassEmitter(final Context context, final ClassWriter cw) { + this.context = context; this.cw = cw; this.methodsStarted = new HashSet<>(); } @@ -157,8 +156,8 @@ public class ClassEmitter implements Emitter { * @param superClassName super class name for class * @param interfaceNames names of interfaces implemented by this class, or null if none */ - ClassEmitter(final ScriptEnvironment env, final String className, final String superClassName, final String... interfaceNames) { - this(env, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS)); + ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) { + this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS)); cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames); } @@ -170,8 +169,8 @@ public class ClassEmitter implements Emitter { * @param unitClassName Compile unit class name. * @param strictMode Should we generate this method in strict mode */ - ClassEmitter(final ScriptEnvironment env, final String sourceName, final String unitClassName, final boolean strictMode) { - this(env, + ClassEmitter(final Context context, final String sourceName, final String unitClassName, final boolean strictMode) { + this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { private static final String OBJECT_CLASS = "java/lang/Object"; @@ -197,6 +196,10 @@ public class ClassEmitter implements Emitter { defineCommonStatics(strictMode); } + Context getContext() { + return context; + } + /** * Returns the name of the compile unit class name. * @return the name of the compile unit class name. @@ -274,51 +277,51 @@ public class ClassEmitter implements Emitter { } // $getXXXX$array - get the ith entry from the constants table and cast to XXXX[]. - for (final Class cls : constantMethodNeeded) { - if (cls.isArray()) { - defineGetArrayMethod(cls); + for (final Class clazz : constantMethodNeeded) { + if (clazz.isArray()) { + defineGetArrayMethod(clazz); } } } /** - * Constructs a primitive specific method for getting the ith entry from the constants table and cast. - * @param cls Array class. + * Constructs a primitive specific method for getting the ith entry from the constants table as an array. + * @param clazz Array class. */ - private void defineGetArrayMethod(final Class cls) { + private void defineGetArrayMethod(final Class clazz) { assert unitClassName != null; - final String methodName = getArrayMethodName(cls); - final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, cls, int.class); + final String methodName = getArrayMethodName(clazz); + final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, clazz, int.class); getArrayMethod.begin(); getArrayMethod.getStatic(unitClassName, CONSTANTS.symbolName(), CONSTANTS.descriptor()) .load(Type.INT, 0) .arrayload() - .checkcast(cls) - .dup() - .arraylength() - .invoke(staticCallNoLookup(Arrays.class, "copyOf", cls, cls, int.class)) + .checkcast(clazz) + .invoke(virtualCallNoLookup(clazz, "clone", Object.class)) + .checkcast(clazz) ._return(); getArrayMethod.end(); } + /** * Generate the name of a get array from constant pool method. - * @param cls Name of array class. + * @param clazz Name of array class. * @return Method name. */ - static String getArrayMethodName(final Class cls) { - assert cls.isArray(); - return GET_ARRAY_PREFIX.symbolName() + cls.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.symbolName(); + static String getArrayMethodName(final Class clazz) { + assert clazz.isArray(); + return GET_ARRAY_PREFIX.symbolName() + clazz.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.symbolName(); } /** * Ensure a get constant method is issued for the class. - * @param cls Class of constant. + * @param clazz Class of constant. */ - void needGetConstantMethod(final Class cls) { - constantMethodNeeded.add(cls); + void needGetConstantMethod(final Class clazz) { + constantMethodNeeded.add(clazz); } /** @@ -376,16 +379,19 @@ public class ClassEmitter implements Emitter { static String disassemble(final byte[] bytecode) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (final PrintWriter pw = new PrintWriter(baos)) { - new ClassReader(bytecode).accept(new TraceClassVisitor(pw), 0); + final NashornClassReader cr = new NashornClassReader(bytecode); + final Context ctx = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Context run() { + return Context.getContext(); + } + }); + final TraceClassVisitor tcv = new TraceClassVisitor(null, new NashornTextifier(ctx.getEnv(), cr), pw); + cr.accept(tcv, 0); } - return new String(baos.toByteArray()); - } - /** - * @return env used for class emission - */ - ScriptEnvironment getEnv() { - return env; + final String str = new String(baos.toByteArray()); + return str; } /** @@ -475,16 +481,35 @@ public class ClassEmitter implements Emitter { * @return method emitter to use for weaving this method */ MethodEmitter method(final FunctionNode functionNode) { + final FunctionSignature signature = new FunctionSignature(functionNode); final MethodVisitor mv = cw.visitMethod( ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0), functionNode.getName(), - new FunctionSignature(functionNode).toString(), + signature.toString(), null, null); return new MethodEmitter(this, mv, functionNode); } + /** + * Add a new method to the class, representing a rest-of version of the function node + * + * @param functionNode the function node to generate a method for + * @return method emitter to use for weaving this method + */ + MethodEmitter restOfMethod(final FunctionNode functionNode) { + final MethodVisitor mv = cw.visitMethod( + ACC_PUBLIC | ACC_STATIC, + functionNode.getName(), + Type.getMethodDescriptor(functionNode.getReturnType().getTypeClass(), RewriteException.class), + null, + null); + + return new MethodEmitter(this, mv, functionNode); + } + + /** * Start generating the method in the class * @@ -636,7 +661,7 @@ public class ClassEmitter implements Emitter { } } - private MethodVisitor methodVisitor(EnumSet flags, final String methodName, final Class rtype, final Class... ptypes) { + private MethodVisitor methodVisitor(final EnumSet flags, final String methodName, final Class rtype, final Class... ptypes) { return cw.visitMethod(Flag.getValue(flags), methodName, methodDescriptor(rtype, ptypes), null, null); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 882846c6334..21b51b334c3 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -29,6 +29,7 @@ import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.PRIVATE; import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC; import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; +import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION; import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP; import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING; import static jdk.nashorn.internal.codegen.CompilerConstants.QUICK_PREFIX; @@ -45,25 +46,39 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; +import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; +import static jdk.nashorn.internal.ir.Symbol.HAS_SLOT; import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; -import static jdk.nashorn.internal.ir.Symbol.IS_TEMP; +import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; +import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_APPLY_TO_CALL; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE; import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT; import java.io.PrintWriter; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.function.Supplier; +import jdk.nashorn.internal.IntDeque; import jdk.nashorn.internal.codegen.ClassEmitter.Flag; import jdk.nashorn.internal.codegen.CompilerConstants.Call; -import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode; import jdk.nashorn.internal.codegen.types.ArrayType; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.AccessNode; @@ -86,14 +101,20 @@ import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.IndexNode; +import jdk.nashorn.internal.ir.JoinPredecessor; +import jdk.nashorn.internal.ir.JoinPredecessorExpression; +import jdk.nashorn.internal.ir.LabelNode; import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LexicalContextNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; +import jdk.nashorn.internal.ir.LiteralNode.PrimitiveLiteralNode; +import jdk.nashorn.internal.ir.LocalVariableConversion; import jdk.nashorn.internal.ir.LoopNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; +import jdk.nashorn.internal.ir.Optimistic; import jdk.nashorn.internal.ir.PropertyNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; @@ -117,20 +138,25 @@ import jdk.nashorn.internal.parser.Lexer.RegexToken; import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Debug; -import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.Property; +import jdk.nashorn.internal.runtime.OptimisticReturnFilters; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; +import jdk.nashorn.internal.runtime.RewriteException; import jdk.nashorn.internal.runtime.Scope; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.Undefined; +import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; import jdk.nashorn.internal.runtime.arrays.ArrayData; import jdk.nashorn.internal.runtime.linker.LinkerCallSite; +import jdk.nashorn.internal.runtime.logging.DebugLogger; +import jdk.nashorn.internal.runtime.logging.Loggable; +import jdk.nashorn.internal.runtime.logging.Logger; +import jdk.nashorn.internal.runtime.options.Options; /** * This is the lowest tier of the code generator. It takes lowered ASTs emitted @@ -151,11 +177,34 @@ import jdk.nashorn.internal.runtime.linker.LinkerCallSite; * The CodeGenerator visits nodes only once, tags them as resolved and emits * bytecode for them. */ -final class CodeGenerator extends NodeOperatorVisitor { +@Logger(name="codegen") +final class CodeGenerator extends NodeOperatorVisitor implements Loggable { + + private static final Type SCOPE_TYPE = Type.typeFor(ScriptObject.class); private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class); - private static final String SCRIPTFUNCTION_IMPL_OBJECT = Type.getInternalName(ScriptFunctionImpl.class); + private static final String SCRIPTFUNCTION_IMPL_NAME = Type.getInternalName(ScriptFunctionImpl.class); + private static final Type SCRIPTFUNCTION_IMPL_TYPE = Type.typeFor(ScriptFunction.class); + + private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class, + "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class); + private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class, + "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class, int[].class); + + private static final Call ENSURE_INT = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class, + "ensureInt", int.class, Object.class, int.class); + private static final Call ENSURE_LONG = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class, + "ensureLong", long.class, Object.class, int.class); + private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class, + "ensureNumber", double.class, Object.class, int.class); + + private static final Class ITERATOR_CLASS = Iterator.class; + static { + assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type(); + } + private static final Type ITERATOR_TYPE = Type.typeFor(ITERATOR_CLASS); + private static final Type EXCEPTION_TYPE = Type.typeFor(CompilerConstants.EXCEPTION_PREFIX.type()); /** Constant data & installation. The only reason the compiler keeps this is because it is assigned * by reflection in class installation */ @@ -180,22 +229,54 @@ final class CodeGenerator extends NodeOperatorVisitor emittedMethods = new HashSet<>(); + // Function Id -> ContinuationInfo. Used by compilation of rest-of function only. + private final Map fnIdToContinuationInfo = new HashMap<>(); + + private final Deque