# HG changeset patch # User asaha # Date 1418423980 28800 # Node ID 41c3c456e326185053f0654be838f4b0bfb38078 # Parent d6a05415f1f47faf4c58d14e316dfca6d83cd14d# Parent 4b41145051ab9f070be7f58851371bda9db7ade2 Merge diff -r d6a05415f1f4 -r 41c3c456e326 .hgtags --- a/.hgtags Mon Dec 01 19:09:54 2014 -0800 +++ b/.hgtags Fri Dec 12 14:39:40 2014 -0800 @@ -571,4 +571,8 @@ 3a8a0fd171c5876023112941b1c7254262f9adfc hs25.40-b19 aa2442f89230dc46147c721812f3b3bd4c612e83 hs25.40-b20 5ea68fb91139081304357f9b937f32c5fdfeca6d jdk8u40-b16 +6bf89bfe8185747a57193efb6cec1f17ccc80414 hs25.40-b21 +fc1f9b67fd8c5d5cd94ecc03569d93e7ce7fb574 jdk8u40-b17 +bc5a90a4db47f1c497d7894434c42325f595cd02 hs25.40-b22 +31d3306aad29e39929418ed43f28212a5f5306a3 jdk8u40-b18 b95f13f05f553309cd74d6ccf8fcedb259c6716c jdk8u45-b00 diff -r d6a05415f1f4 -r 41c3c456e326 make/aix/makefiles/adjust-mflags.sh --- a/make/aix/makefiles/adjust-mflags.sh Mon Dec 01 19:09:54 2014 -0800 +++ b/make/aix/makefiles/adjust-mflags.sh Fri Dec 12 14:39:40 2014 -0800 @@ -1,6 +1,6 @@ #! /bin/sh # -# 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 @@ -64,7 +64,7 @@ echo "$MFLAGS" \ | sed ' s/^-/ -/ - s/ -\([^ ][^ ]*\)j/ -\1 -j/ + s/ -\([^ I][^ I]*\)j/ -\1 -j/ s/ -j[0-9][0-9]*/ -j/ s/ -j\([^ ]\)/ -j -\1/ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/ diff -r d6a05415f1f4 -r 41c3c456e326 make/bsd/makefiles/adjust-mflags.sh --- a/make/bsd/makefiles/adjust-mflags.sh Mon Dec 01 19:09:54 2014 -0800 +++ b/make/bsd/makefiles/adjust-mflags.sh Fri Dec 12 14:39:40 2014 -0800 @@ -64,7 +64,7 @@ echo "$MFLAGS" \ | sed ' s/^-/ -/ - s/ -\([^ ][^ ]*\)j/ -\1 -j/ + s/ -\([^ I][^ I]*\)j/ -\1 -j/ s/ -j[0-9][0-9]*/ -j/ s/ -j\([^ ]\)/ -j -\1/ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/ diff -r d6a05415f1f4 -r 41c3c456e326 make/hotspot_version diff -r d6a05415f1f4 -r 41c3c456e326 make/jprt.properties --- a/make/jprt.properties Mon Dec 01 19:09:54 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,407 +0,0 @@ -# -# Copyright (c) 2006, 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. -# -# - -# Properties for jprt - -# All build result bundles are full jdks. -jprt.need.sibling.build=false - -# At submit time, the release supplied will be in jprt.submit.release -# and will be one of the official release names defined in jprt. -# jprt supports property value expansion using ${property.name} syntax. - -# This tells jprt what default release we want to build - -jprt.hotspot.default.release=jdk8u40 - -jprt.tools.default.release=${jprt.submit.option.release?${jprt.submit.option.release}:${jprt.hotspot.default.release}} - -# Disable syncing the source after builds and tests are done. - -jprt.sync.push=false - -# Note: we want both embedded releases and regular releases to build and test -# all platforms so that regressions are not introduced (eg. change to -# common code by SE breaks PPC/ARM; change to common code by SE-E breaks -# sparc etc. - -# Define the Solaris platforms we want for the various releases -jprt.my.solaris.sparcv9.jdk8u40=solaris_sparcv9_5.10 -jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10 -jprt.my.solaris.sparcv9.jdk7u8=${jprt.my.solaris.sparcv9.jdk7} -jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}} - -jprt.my.solaris.x64.jdk8u40=solaris_x64_5.10 -jprt.my.solaris.x64.jdk7=solaris_x64_5.10 -jprt.my.solaris.x64.jdk7u8=${jprt.my.solaris.x64.jdk7} -jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}} - -jprt.my.linux.i586.jdk8u40=linux_i586_2.6 -jprt.my.linux.i586.jdk7=linux_i586_2.6 -jprt.my.linux.i586.jdk7u8=${jprt.my.linux.i586.jdk7} -jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}} - -jprt.my.linux.x64.jdk8u40=linux_x64_2.6 -jprt.my.linux.x64.jdk7=linux_x64_2.6 -jprt.my.linux.x64.jdk7u8=${jprt.my.linux.x64.jdk7} -jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}} - -jprt.my.linux.ppc.jdk8u40=linux_ppc_2.6 -jprt.my.linux.ppc.jdk7=linux_ppc_2.6 -jprt.my.linux.ppc.jdk7u8=${jprt.my.linux.ppc.jdk7} -jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}} - -jprt.my.linux.ppcv2.jdk8u40=linux_ppcv2_2.6 -jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6 -jprt.my.linux.ppcv2.jdk7u8=${jprt.my.linux.ppcv2.jdk7} -jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}} - -jprt.my.linux.armvfpsflt.jdk8u40=linux_armvfpsflt_2.6 -jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}} - -jprt.my.linux.armvfphflt.jdk8u40=linux_armvfphflt_2.6 -jprt.my.linux.armvfphflt=${jprt.my.linux.armvfphflt.${jprt.tools.default.release}} - -# The ARM GP vfp-sflt build is not currently supported -#jprt.my.linux.armvs.jdk8u40=linux_armvs_2.6 -#jprt.my.linux.armvs=${jprt.my.linux.armvs.${jprt.tools.default.release}} - -jprt.my.linux.armvh.jdk8u40=linux_armvh_2.6 -jprt.my.linux.armvh=${jprt.my.linux.armvh.${jprt.tools.default.release}} - -jprt.my.linux.armsflt.jdk8u40=linux_armsflt_2.6 -jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6 -jprt.my.linux.armsflt.jdk7u8=${jprt.my.linux.armsflt.jdk7} -jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}} - -jprt.my.macosx.x64.jdk8u40=macosx_x64_10.7 -jprt.my.macosx.x64.jdk7=macosx_x64_10.7 -jprt.my.macosx.x64.jdk7u8=${jprt.my.macosx.x64.jdk7} -jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}} - -jprt.my.windows.i586.jdk8u40=windows_i586_6.1 -jprt.my.windows.i586.jdk7=windows_i586_6.1 -jprt.my.windows.i586.jdk7u8=${jprt.my.windows.i586.jdk7} -jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} - -jprt.my.windows.x64.jdk8u40=windows_x64_6.1 -jprt.my.windows.x64.jdk7=windows_x64_6.1 -jprt.my.windows.x64.jdk7u8=${jprt.my.windows.x64.jdk7} -jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}} - -# Standard list of jprt build targets for this source tree - -jprt.build.targets.standard= \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}, \ - ${jprt.my.solaris.x64}-{product|fastdebug}, \ - ${jprt.my.linux.i586}-{product|fastdebug}, \ - ${jprt.my.linux.x64}-{product|fastdebug}, \ - ${jprt.my.macosx.x64}-{product|fastdebug}, \ - ${jprt.my.windows.i586}-{product|fastdebug}, \ - ${jprt.my.windows.x64}-{product|fastdebug}, \ - ${jprt.my.linux.armvh}-{product|fastdebug} - -jprt.build.targets.open= \ - ${jprt.my.solaris.x64}-{debugOpen}, \ - ${jprt.my.linux.x64}-{productOpen} - -jprt.build.targets.embedded= \ - ${jprt.my.linux.i586}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.armvfphflt}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb} - -jprt.build.targets.all=${jprt.build.targets.standard}, \ - ${jprt.build.targets.embedded}, ${jprt.build.targets.open} - -jprt.build.targets.jdk8u40=${jprt.build.targets.all} -jprt.build.targets.jdk7=${jprt.build.targets.all} -jprt.build.targets.jdk7u8=${jprt.build.targets.all} -jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}} - -# Subset lists of test targets for this source tree - -jprt.my.solaris.sparcv9.test.targets= \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \ - ${jprt.my.solaris.sparcv9}-product-c2-runThese, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_G1, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_SerialGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParallelGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParNewGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_CMS, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_G1, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParOldGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_G1, \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParOldGC - -jprt.my.solaris.x64.test.targets= \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \ - ${jprt.my.solaris.x64}-product-c2-runThese, \ - ${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_G1, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC - -jprt.my.linux.i586.test.targets = \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \ - ${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \ - ${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \ - ${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \ - ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \ - ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_SerialGC, \ - ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParallelGC, \ - ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParNewGC, \ - ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_CMS, \ - ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_G1, \ - ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParOldGC, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_SerialGC, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_G1, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParOldGC - -jprt.my.linux.x64.test.targets = \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_CMS, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_G1, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_CMS, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_G1, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParOldGC - -jprt.my.macosx.x64.test.targets = \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jvm98, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-scimark, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_CMS, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_G1, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_CMS, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_G1, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_G1, \ - ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParOldGC - -jprt.my.windows.i586.test.targets = \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \ - ${jprt.my.windows.i586}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-scimark, \ - ${jprt.my.windows.i586}-product-{c1|c2}-runThese, \ - ${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \ - ${jprt.my.windows.i586}-fastdebug-c1-runThese_Xshare, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \ - ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_SerialGC, \ - ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParallelGC, \ - ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParNewGC, \ - ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_CMS, \ - ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_G1, \ - ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParOldGC, \ - ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \ - ${jprt.my.windows.i586}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \ - ${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \ - ${jprt.my.windows.i586}-product-{c1|c2}-jbb_G1, \ - ${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParOldGC - -jprt.my.windows.x64.test.targets = \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98_nontiered, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \ - ${jprt.my.windows.x64}-product-c2-runThese, \ - ${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_G1, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_CMS, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_G1, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \ - ${jprt.my.windows.x64}-product-c2-jbb_CMS, \ - ${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \ - ${jprt.my.windows.x64}-product-c2-jbb_G1, \ - ${jprt.my.windows.x64}-product-c2-jbb_ParOldGC - -# Some basic "smoke" tests for OpenJDK builds -jprt.test.targets.open = \ - ${jprt.my.solaris.x64}-{productOpen|fastdebugOpen}-c2-jvm98, \ - ${jprt.my.linux.x64}-{productOpen|fastdebugOpen}-c2-jvm98 - -# Testing for actual embedded builds is different to standard -jprt.my.linux.i586.test.targets.embedded = \ - linux_i586_2.6-product-c1-scimark - -# The complete list of test targets for jprt -# Note: no PPC or ARM tests at this stage - -jprt.test.targets.standard = \ - ${jprt.my.linux.i586.test.targets.embedded}, \ - ${jprt.my.solaris.sparcv9.test.targets}, \ - ${jprt.my.solaris.x64.test.targets}, \ - ${jprt.my.linux.i586.test.targets}, \ - ${jprt.my.linux.x64.test.targets}, \ - ${jprt.my.macosx.x64.test.targets}, \ - ${jprt.my.windows.i586.test.targets}, \ - ${jprt.my.windows.x64.test.targets}, \ - ${jprt.test.targets.open} - -jprt.test.targets.embedded= \ - ${jprt.my.linux.i586.test.targets.embedded}, \ - ${jprt.my.solaris.sparcv9.test.targets}, \ - ${jprt.my.solaris.x64.test.targets}, \ - ${jprt.my.linux.x64.test.targets}, \ - ${jprt.my.windows.i586.test.targets}, \ - ${jprt.my.windows.x64.test.targets} - -jprt.test.targets.jdk8u40=${jprt.test.targets.standard} -jprt.test.targets.jdk7=${jprt.test.targets.standard} -jprt.test.targets.jdk7u8=${jprt.test.targets.jdk7} -jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}} - -# The default test/Makefile targets that should be run - -#jprt.make.rule.test.targets=*-product-*-packtest - -jprt.make.rule.test.targets.standard.client = \ - ${jprt.my.linux.i586}-*-c1-clienttest, \ - ${jprt.my.windows.i586}-*-c1-clienttest - -jprt.make.rule.test.targets.standard.server = \ - ${jprt.my.solaris.sparcv9}-*-c2-servertest, \ - ${jprt.my.solaris.x64}-*-c2-servertest, \ - ${jprt.my.linux.i586}-*-c2-servertest, \ - ${jprt.my.linux.x64}-*-c2-servertest, \ - ${jprt.my.macosx.x64}-*-c2-servertest, \ - ${jprt.my.windows.i586}-*-c2-servertest, \ - ${jprt.my.windows.x64}-*-c2-servertest - -jprt.make.rule.test.targets.standard.internalvmtests = \ - ${jprt.my.solaris.sparcv9}-fastdebug-c2-internalvmtests, \ - ${jprt.my.solaris.x64}-fastdebug-c2-internalvmtests, \ - ${jprt.my.linux.i586}-fastdebug-c2-internalvmtests, \ - ${jprt.my.linux.x64}-fastdebug-c2-internalvmtests, \ - ${jprt.my.macosx.x64}-fastdebug-c2-internalvmtests, \ - ${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \ - ${jprt.my.windows.x64}-fastdebug-c2-internalvmtests - -jprt.make.rule.test.targets.standard.reg.group = \ - ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GROUP, \ - ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GROUP, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c2-GROUP, \ - ${jprt.my.linux.x64}-{product|fastdebug}-c2-GROUP, \ - ${jprt.my.windows.i586}-{product|fastdebug}-c2-GROUP, \ - ${jprt.my.windows.x64}-{product|fastdebug}-c2-GROUP, \ - ${jprt.my.linux.i586}-{product|fastdebug}-c1-GROUP, \ - ${jprt.my.windows.i586}-{product|fastdebug}-c1-GROUP - -jprt.make.rule.test.targets.standard = \ - ${jprt.make.rule.test.targets.standard.client}, \ - ${jprt.make.rule.test.targets.standard.server}, \ - ${jprt.make.rule.test.targets.standard.internalvmtests}, \ - ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_wbapitest}, \ - ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_compiler}, \ - ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_gc}, \ - ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_runtime}, \ - ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_serviceability} - -jprt.make.rule.test.targets.embedded = \ - ${jprt.make.rule.test.targets.standard.client} - -jprt.make.rule.test.targets.jdk8u40=${jprt.make.rule.test.targets.standard} -jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard} -jprt.make.rule.test.targets.jdk7u8=${jprt.make.rule.test.targets.jdk7} -jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}} - -# 7155453: Work-around to prevent popups on OSX from blocking test completion -# but the work-around is added to all platforms to be consistent -jprt.jbb.options=-Djava.awt.headless=true diff -r d6a05415f1f4 -r 41c3c456e326 make/linux/makefiles/adjust-mflags.sh --- a/make/linux/makefiles/adjust-mflags.sh Mon Dec 01 19:09:54 2014 -0800 +++ b/make/linux/makefiles/adjust-mflags.sh Fri Dec 12 14:39:40 2014 -0800 @@ -64,7 +64,7 @@ echo "$MFLAGS" \ | sed ' s/^-/ -/ - s/ -\([^ ][^ ]*\)j/ -\1 -j/ + s/ -\([^ I][^ I]*\)j/ -\1 -j/ s/ -j[0-9][0-9]*/ -j/ s/ -j\([^ ]\)/ -j -\1/ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/ diff -r d6a05415f1f4 -r 41c3c456e326 make/solaris/makefiles/adjust-mflags.sh --- a/make/solaris/makefiles/adjust-mflags.sh Mon Dec 01 19:09:54 2014 -0800 +++ b/make/solaris/makefiles/adjust-mflags.sh Fri Dec 12 14:39:40 2014 -0800 @@ -64,7 +64,7 @@ echo "$MFLAGS" \ | sed ' s/^-/ -/ - s/ -\([^ ][^ ]*\)j/ -\1 -j/ + s/ -\([^ I][^ I]*\)j/ -\1 -j/ s/ -j[0-9][0-9]*/ -j/ s/ -j\([^ ]\)/ -j -\1/ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/ diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/ci/ciMethod.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -68,7 +68,10 @@ // ciMethod::ciMethod // // Loaded method. -ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { +ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) : + ciMetadata(h_m()), + _holder(holder) +{ assert(h_m() != NULL, "no null method"); // These fields are always filled in in loaded methods. @@ -124,7 +127,6 @@ // generating _signature may allow GC and therefore move m. // These fields are always filled in. _name = env->get_symbol(h_m()->name()); - _holder = env->get_instance_klass(h_m()->method_holder()); ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); constantPoolHandle cpool = h_m()->constants(); _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/ci/ciMethod.hpp --- a/src/share/vm/ci/ciMethod.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/ci/ciMethod.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -90,7 +90,7 @@ BCEscapeAnalyzer* _bcea; #endif - ciMethod(methodHandle h_m); + ciMethod(methodHandle h_m, ciInstanceKlass* holder); ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor); Method* get_Method() const { diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/ci/ciObjectFactory.cpp --- a/src/share/vm/ci/ciObjectFactory.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/ci/ciObjectFactory.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -239,7 +239,7 @@ ciObject* ciObjectFactory::get(oop key) { ASSERT_IN_VM; - assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); + assert(Universe::heap()->is_in_reserved(key), "must be"); NonPermObject* &bucket = find_non_perm(key); if (bucket != NULL) { @@ -260,10 +260,10 @@ } // ------------------------------------------------------------------ -// ciObjectFactory::get +// ciObjectFactory::get_metadata // -// Get the ciObject corresponding to some oop. If the ciObject has -// already been created, it is returned. Otherwise, a new ciObject +// Get the ciMetadata corresponding to some Metadata. If the ciMetadata has +// already been created, it is returned. Otherwise, a new ciMetadata // is created. ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { ASSERT_IN_VM; @@ -290,9 +290,9 @@ } #endif if (!is_found_at(index, key, _ci_metadata)) { - // The ciObject does not yet exist. Create it and insert it + // The ciMetadata does not yet exist. Create it and insert it // into the cache. - ciMetadata* new_object = create_new_object(key); + ciMetadata* new_object = create_new_metadata(key); init_ident_of(new_object); assert(new_object->is_metadata(), "must be"); @@ -344,15 +344,28 @@ } // ------------------------------------------------------------------ -// ciObjectFactory::create_new_object +// ciObjectFactory::create_new_metadata // -// Create a new ciObject from a Metadata*. +// Create a new ciMetadata from a Metadata*. // -// Implementation note: this functionality could be virtual behavior -// of the oop itself. For now, we explicitly marshal the object. -ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { +// Implementation note: in order to keep Metadata live, an auxiliary ciObject +// is used, which points to it's holder. +ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) { EXCEPTION_CONTEXT; + // Hold metadata from unloading by keeping it's holder alive. + if (_initialized && o->is_klass()) { + Klass* holder = ((Klass*)o); + if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) { + // Though ciInstanceKlass records class loader oop, it's not enough to keep + // VM anonymous classes alive (loader == NULL). Klass holder should be used instead. + // It is enough to record a ciObject, since cached elements are never removed + // during ciObjectFactory lifetime. ciObjectFactory itself is created for + // every compilation and lives for the whole duration of the compilation. + ciObject* h = get(holder->klass_holder()); + } + } + if (o->is_klass()) { KlassHandle h_k(THREAD, (Klass*)o); Klass* k = (Klass*)o; @@ -365,14 +378,16 @@ } } else if (o->is_method()) { methodHandle h_m(THREAD, (Method*)o); - return new (arena()) ciMethod(h_m); + ciEnv *env = CURRENT_THREAD_ENV; + ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder()); + return new (arena()) ciMethod(h_m, holder); } else if (o->is_methodData()) { // Hold methodHandle alive - might not be necessary ??? methodHandle h_m(THREAD, ((MethodData*)o)->method()); return new (arena()) ciMethodData((MethodData*)o); } - // The oop is of some type not supported by the compiler interface. + // The Metadata* is of some type not supported by the compiler interface. ShouldNotReachHere(); return NULL; } @@ -701,7 +716,7 @@ // If there is no entry in the cache corresponding to this oop, return // the null tail of the bucket into which the oop should be inserted. ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { - assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); + assert(Universe::heap()->is_in_reserved(key), "must be"); ciMetadata* klass = get_metadata(key->klass()); NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/ci/ciObjectFactory.hpp --- a/src/share/vm/ci/ciObjectFactory.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/ci/ciObjectFactory.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -73,7 +73,7 @@ void insert(int index, ciMetadata* obj, GrowableArray* objects); ciObject* create_new_object(oop o); - ciMetadata* create_new_object(Metadata* o); + ciMetadata* create_new_metadata(Metadata* o); void ensure_metadata_alive(ciMetadata* m); diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/ci/ciTypeFlow.cpp --- a/src/share/vm/ci/ciTypeFlow.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/ci/ciTypeFlow.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -35,6 +35,7 @@ #include "interpreter/bytecode.hpp" #include "interpreter/bytecodes.hpp" #include "memory/allocation.inline.hpp" +#include "opto/compile.hpp" #include "runtime/deoptimization.hpp" #include "utilities/growableArray.hpp" @@ -2646,7 +2647,7 @@ assert (!blk->has_pre_order(), ""); blk->set_next_pre_order(); - if (_next_pre_order >= MaxNodeLimit / 2) { + if (_next_pre_order >= (int)Compile::current()->max_node_limit() / 2) { // Too many basic blocks. Bail out. // This can happen when try/finally constructs are nested to depth N, // and there is O(2**N) cloning of jsr bodies. See bug 4697245! diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/classfile/classLoaderExt.hpp --- a/src/share/vm/classfile/classLoaderExt.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/classfile/classLoaderExt.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -63,6 +63,9 @@ ClassPathEntry* new_entry) { ClassLoader::add_to_list(new_entry); } + static void append_boot_classpath(ClassPathEntry* new_entry) { + ClassLoader::add_to_list(new_entry); + } static void setup_search_paths() {} static void init_lookup_cache(TRAPS) {} diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -41,6 +41,7 @@ #include "oops/method.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayOop.hpp" +#include "prims/jvmtiRedefineClassesTrace.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" @@ -2775,12 +2776,35 @@ return (Metadata*)mname->address_field(_vmtarget_offset); } +bool java_lang_invoke_MemberName::is_method(oop mname) { + assert(is_instance(mname), "must be MemberName"); + return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0; +} + #if INCLUDE_JVMTI // Can be executed on VM thread only -void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) { - assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type"); +void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Method* old_method, + Method* new_method, bool* trace_name_printed) { + assert(is_method(mname), "wrong type"); assert(Thread::current()->is_VM_thread(), "not VM thread"); - mname->address_field_put(_vmtarget_offset, (address)ref); + + Method* target = (Method*)mname->address_field(_vmtarget_offset); + if (target == old_method) { + mname->address_field_put(_vmtarget_offset, (address)new_method); + + if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { + if (!(*trace_name_printed)) { + // RC_TRACE_MESG macro has an embedded ResourceMark + RC_TRACE_MESG(("adjust: name=%s", + old_method->method_holder()->external_name())); + *trace_name_printed = true; + } + // RC_TRACE macro has an embedded ResourceMark + RC_TRACE(0x00400000, ("MemberName method update: %s(%s)", + new_method->name()->as_C_string(), + new_method->signature()->as_C_string())); + } + } } #endif // INCLUDE_JVMTI diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -1096,7 +1096,8 @@ static Metadata* vmtarget(oop mname); static void set_vmtarget(oop mname, Metadata* target); #if INCLUDE_JVMTI - static void adjust_vmtarget(oop mname, Metadata* target); + static void adjust_vmtarget(oop mname, Method* old_method, Method* new_method, + bool* trace_name_printed); #endif // INCLUDE_JVMTI static intptr_t vmindex(oop mname); @@ -1110,6 +1111,8 @@ return obj != NULL && is_subclass(obj->klass()); } + static bool is_method(oop obj); + // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants): enum { MN_IS_METHOD = 0x00010000, // method (not constructor) diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/code/dependencies.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -879,6 +879,8 @@ bool is_witness(Klass* k) { if (doing_subtype_search()) { return Dependencies::is_concrete_klass(k); + } else if (!k->oop_is_instance()) { + return false; // no methods to find in an array type } else { // Search class hierarchy first. Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature); @@ -1094,7 +1096,7 @@ Klass* chain; // scratch variable #define ADD_SUBCLASS_CHAIN(k) { \ assert(chaini < CHAINMAX, "oob"); \ - chain = InstanceKlass::cast(k)->subklass(); \ + chain = k->subklass(); \ if (chain != NULL) chains[chaini++] = chain; } // Look for non-abstract subclasses. @@ -1105,35 +1107,37 @@ // (Their subclasses are additional indirect implementors. // See InstanceKlass::add_implementor.) // (Note: nof_implementors is always zero for non-interfaces.) - int nof_impls = InstanceKlass::cast(context_type)->nof_implementors(); - if (nof_impls > 1) { - // Avoid this case: *I.m > { A.m, C }; B.m > C - // Here, I.m has 2 concrete implementations, but m appears unique - // as A.m, because the search misses B.m when checking C. - // The inherited method B.m was getting missed by the walker - // when interface 'I' was the starting point. - // %%% Until this is fixed more systematically, bail out. - // (Old CHA had the same limitation.) - return context_type; - } - if (nof_impls > 0) { - Klass* impl = InstanceKlass::cast(context_type)->implementor(); - assert(impl != NULL, "just checking"); - // If impl is the same as the context_type, then more than one - // implementor has seen. No exact info in this case. - if (impl == context_type) { - return context_type; // report an inexact witness to this sad affair + if (top_level_call) { + int nof_impls = InstanceKlass::cast(context_type)->nof_implementors(); + if (nof_impls > 1) { + // Avoid this case: *I.m > { A.m, C }; B.m > C + // Here, I.m has 2 concrete implementations, but m appears unique + // as A.m, because the search misses B.m when checking C. + // The inherited method B.m was getting missed by the walker + // when interface 'I' was the starting point. + // %%% Until this is fixed more systematically, bail out. + // (Old CHA had the same limitation.) + return context_type; } - if (do_counts) - { NOT_PRODUCT(deps_find_witness_steps++); } - if (is_participant(impl)) { - if (!participants_hide_witnesses) { + if (nof_impls > 0) { + Klass* impl = InstanceKlass::cast(context_type)->implementor(); + assert(impl != NULL, "just checking"); + // If impl is the same as the context_type, then more than one + // implementor has seen. No exact info in this case. + if (impl == context_type) { + return context_type; // report an inexact witness to this sad affair + } + if (do_counts) + { NOT_PRODUCT(deps_find_witness_steps++); } + if (is_participant(impl)) { + if (!participants_hide_witnesses) { + ADD_SUBCLASS_CHAIN(impl); + } + } else if (is_witness(impl) && !ignore_witness(impl)) { + return impl; + } else { ADD_SUBCLASS_CHAIN(impl); } - } else if (is_witness(impl) && !ignore_witness(impl)) { - return impl; - } else { - ADD_SUBCLASS_CHAIN(impl); } } diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -1845,7 +1845,7 @@ os::file_separator(), thread_id, os::current_process_id()); } - fp = fopen(file_name, "at"); + fp = fopen(file_name, "wt"); if (fp != NULL) { if (LogCompilation && Verbose) { tty->print_cr("Opening compilation log %s", file_name); diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/compiler/compileLog.cpp --- a/src/share/vm/compiler/compileLog.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/compiler/compileLog.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -55,8 +55,10 @@ } CompileLog::~CompileLog() { - delete _out; + delete _out; // Close fd in fileStream::~fileStream() _out = NULL; + // Remove partial file after merging in CompileLog::finish_log_on_error + unlink(_file); FREE_C_HEAP_ARRAY(char, _identities, mtCompiler); FREE_C_HEAP_ARRAY(char, _file, mtCompiler); } @@ -268,10 +270,9 @@ } file->print_raw_cr(""); close(partial_fd); - unlink(partial_file); } CompileLog* next_log = log->_next; - delete log; + delete log; // Removes partial file log = next_log; } _first = NULL; diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -2957,28 +2957,27 @@ return NULL; } -void InstanceKlass::add_member_name(int index, Handle mem_name) { +bool InstanceKlass::add_member_name(Handle mem_name) { jweak mem_name_wref = JNIHandles::make_weak_global(mem_name); MutexLocker ml(MemberNameTable_lock); - assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds"); DEBUG_ONLY(No_Safepoint_Verifier nsv); + // Check if method has been redefined while taking out MemberNameTable_lock, if so + // return false. We cannot cache obsolete methods. They will crash when the function + // is called! + Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name()); + if (method->is_obsolete()) { + return false; + } else if (method->is_old()) { + // Replace method with redefined version + java_lang_invoke_MemberName::set_vmtarget(mem_name(), method_with_idnum(method->method_idnum())); + } + if (_member_names == NULL) { _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count()); } - _member_names->add_member_name(index, mem_name_wref); -} - -oop InstanceKlass::get_member_name(int index) { - MutexLocker ml(MemberNameTable_lock); - assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds"); - DEBUG_ONLY(No_Safepoint_Verifier nsv); - - if (_member_names == NULL) { - return NULL; - } - oop mem_name =_member_names->get_member_name(index); - return mem_name; + _member_names->add_member_name(mem_name_wref); + return true; } // ----------------------------------------------------------------------------------------------------- diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -1097,8 +1097,7 @@ // JSR-292 support MemberNameTable* member_names() { return _member_names; } void set_member_names(MemberNameTable* member_names) { _member_names = member_names; } - void add_member_name(int index, Handle member_name); - oop get_member_name(int index); + bool add_member_name(Handle member_name); public: // JVMTI support diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/c2_globals.hpp --- a/src/share/vm/opto/c2_globals.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/c2_globals.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -647,7 +647,7 @@ develop(bool, AlwaysIncrementalInline, false, \ "do all inlining incrementally") \ \ - product(intx, LiveNodeCountInliningCutoff, 20000, \ + product(intx, LiveNodeCountInliningCutoff, 40000, \ "max number of live nodes in a method") \ \ diagnostic(bool, OptimizeExpensiveOps, true, \ diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/compile.cpp --- a/src/share/vm/opto/compile.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/compile.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -679,7 +679,8 @@ _inlining_incrementally(false), _print_inlining_list(NULL), _print_inlining_idx(0), - _interpreter_frame_size(0) { + _interpreter_frame_size(0), + _max_node_limit(MaxNodeLimit) { C = this; CompileWrapper cw(this); @@ -990,7 +991,8 @@ _print_inlining_list(NULL), _print_inlining_idx(0), _allowed_reasons(0), - _interpreter_frame_size(0) { + _interpreter_frame_size(0), + _max_node_limit(MaxNodeLimit) { C = this; #ifndef PRODUCT @@ -1100,6 +1102,7 @@ set_do_count_invocations(false); set_do_method_data_update(false); set_rtm_state(NoRTM); // No RTM lock eliding by default + method_has_option_value("MaxNodeLimit", _max_node_limit); #if INCLUDE_RTM_OPT if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) { int rtm_state = method()->method_data()->rtm_state(); diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/compile.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -290,6 +290,7 @@ int _freq_inline_size; // Max hot method inline size for this compilation int _fixed_slots; // count of frame slots not allocated by the register // allocator i.e. locks, original deopt pc, etc. + uintx _max_node_limit; // Max unique node count during a single compilation. // For deopt int _orig_pc_slot; int _orig_pc_slot_offset_in_bytes; @@ -594,6 +595,9 @@ void set_rtm_state(RTMState s) { _rtm_state = s; } bool use_rtm() const { return (_rtm_state & NoRTM) == 0; } bool profile_rtm() const { return _rtm_state == ProfileRTM; } + uint max_node_limit() const { return (uint)_max_node_limit; } + void set_max_node_limit(uint n) { _max_node_limit = n; } + // check the CompilerOracle for special behaviours for this compile bool method_has_option(const char * option) { return method() != NULL && method()->has_option(option); @@ -723,7 +727,7 @@ record_method_not_compilable(reason, true); } bool check_node_count(uint margin, const char* reason) { - if (live_nodes() + margin > (uint)MaxNodeLimit) { + if (live_nodes() + margin > max_node_limit()) { record_method_not_compilable(reason); return true; } else { diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/connode.cpp --- a/src/share/vm/opto/connode.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/connode.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -441,6 +441,101 @@ return this; } +uint CastIINode::size_of() const { + return sizeof(*this); +} + +uint CastIINode::cmp(const Node &n) const { + return TypeNode::cmp(n) && ((CastIINode&)n)._carry_dependency == _carry_dependency; +} + +Node *CastIINode::Identity(PhaseTransform *phase) { + if (_carry_dependency) { + return this; + } + return ConstraintCastNode::Identity(phase); +} + +const Type *CastIINode::Value(PhaseTransform *phase) const { + const Type *res = ConstraintCastNode::Value(phase); + + // Try to improve the type of the CastII if we recognize a CmpI/If + // pattern. + if (_carry_dependency) { + if (in(0) != NULL && (in(0)->is_IfFalse() || in(0)->is_IfTrue())) { + Node* proj = in(0); + if (proj->in(0)->in(1)->is_Bool()) { + Node* b = proj->in(0)->in(1); + if (b->in(1)->Opcode() == Op_CmpI) { + Node* cmp = b->in(1); + if (cmp->in(1) == in(1) && phase->type(cmp->in(2))->isa_int()) { + const TypeInt* in2_t = phase->type(cmp->in(2))->is_int(); + const Type* t = TypeInt::INT; + BoolTest test = b->as_Bool()->_test; + if (proj->is_IfFalse()) { + test = test.negate(); + } + BoolTest::mask m = test._test; + jlong lo_long = min_jint; + jlong hi_long = max_jint; + if (m == BoolTest::le || m == BoolTest::lt) { + hi_long = in2_t->_hi; + if (m == BoolTest::lt) { + hi_long -= 1; + } + } else if (m == BoolTest::ge || m == BoolTest::gt) { + lo_long = in2_t->_lo; + if (m == BoolTest::gt) { + lo_long += 1; + } + } else if (m == BoolTest::eq) { + lo_long = in2_t->_lo; + hi_long = in2_t->_hi; + } else if (m == BoolTest::ne) { + // can't do any better + } else { + stringStream ss; + test.dump_on(&ss); + fatal(err_msg_res("unexpected comparison %s", ss.as_string())); + } + int lo_int = (int)lo_long; + int hi_int = (int)hi_long; + + if (lo_long != (jlong)lo_int) { + lo_int = min_jint; + } + if (hi_long != (jlong)hi_int) { + hi_int = max_jint; + } + + t = TypeInt::make(lo_int, hi_int, Type::WidenMax); + + res = res->filter_speculative(t); + + return res; + } + } + } + } + } + return res; +} + +Node *CastIINode::Ideal_DU_postCCP(PhaseCCP *ccp) { + if (_carry_dependency) { + return NULL; + } + return ConstraintCastNode::Ideal_DU_postCCP(ccp); +} + +#ifndef PRODUCT +void CastIINode::dump_spec(outputStream *st) const { + TypeNode::dump_spec(st); + if (_carry_dependency) { + st->print(" carry dependency"); + } +} +#endif //============================================================================= diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/connode.hpp --- a/src/share/vm/opto/connode.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/connode.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -241,10 +241,25 @@ //------------------------------CastIINode------------------------------------- // cast integer to integer (different range) class CastIINode: public ConstraintCastNode { + private: + // Can this node be removed post CCP or does it carry a required dependency? + const bool _carry_dependency; + + protected: + virtual uint cmp( const Node &n ) const; + virtual uint size_of() const; + public: - CastIINode (Node *n, const Type *t ): ConstraintCastNode(n,t) {} + CastIINode(Node *n, const Type *t, bool carry_dependency = false) + : ConstraintCastNode(n,t), _carry_dependency(carry_dependency) {} virtual int Opcode() const; virtual uint ideal_reg() const { return Op_RegI; } + virtual Node *Identity( PhaseTransform *phase ); + virtual const Type *Value( PhaseTransform *phase ) const; + virtual Node *Ideal_DU_postCCP( PhaseCCP * ); +#ifndef PRODUCT + virtual void dump_spec(outputStream *st) const; +#endif }; //------------------------------CastPPNode------------------------------------- diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/doCall.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -410,6 +410,11 @@ ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder); assert(declared_signature != NULL, "cannot be null"); + // Bump max node limit for JSR292 users + if (bc() == Bytecodes::_invokedynamic || orig_callee->is_method_handle_intrinsic()) { + C->set_max_node_limit(3*MaxNodeLimit); + } + // uncommon-trap when callee is unloaded, uninitialized or will not link // bailout when too many arguments for register representation if (!will_link || can_not_compile_call_site(orig_callee, klass)) { diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/escape.cpp --- a/src/share/vm/opto/escape.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/escape.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -1106,6 +1106,9 @@ // Each 4 iterations calculate how much time it will take // to complete graph construction. time.stop(); + // Poll for requests from shutdown mechanism to quiesce compiler + // because Connection graph construction may take long time. + CompileBroker::maybe_block(); double stop_time = time.seconds(); double time_per_iter = (stop_time - start_time) / (double)SAMPLE_SIZE; double time_until_end = time_per_iter * (double)(java_objects_length - next); @@ -2409,7 +2412,7 @@ } } } - if ((int) (C->live_nodes() + 2*NodeLimitFudgeFactor) > MaxNodeLimit) { + if (C->live_nodes() + 2*NodeLimitFudgeFactor > C->max_node_limit()) { if (C->do_escape_analysis() == true && !C->failing()) { // Retry compilation without escape analysis. // If this is the first failure, the sentinel string will "stick" diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/ifg.cpp --- a/src/share/vm/opto/ifg.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/ifg.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -541,17 +541,37 @@ if( !n->is_Proj() || // Could also be a flags-projection of a dead ADD or such. (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) { - block->remove_node(j - 1); - if (lrgs(r)._def == n) { - lrgs(r)._def = 0; + bool remove = true; + if (n->is_MachProj()) { + // Don't remove KILL projections if their "defining" nodes have + // memory effects (have SCMemProj projection node) - + // they are not dead even when their result is not used. + // For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes. + // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list) + // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed + // in block in such order that KILL MachProj nodes are processed first. + uint cnt = def->outcnt(); + for (uint i = 0; i < cnt; i++) { + Node* proj = def->raw_out(i); + if (proj->Opcode() == Op_SCMemProj) { + remove = false; + break; + } + } } - n->disconnect_inputs(NULL, C); - _cfg.unmap_node_from_block(n); - n->replace_by(C->top()); - // Since yanking a Node from block, high pressure moves up one - hrp_index[0]--; - hrp_index[1]--; - continue; + if (remove) { + block->remove_node(j - 1); + if (lrgs(r)._def == n) { + lrgs(r)._def = 0; + } + n->disconnect_inputs(NULL, C); + _cfg.unmap_node_from_block(n); + n->replace_by(C->top()); + // Since yanking a Node from block, high pressure moves up one + hrp_index[0]--; + hrp_index[1]--; + continue; + } } // Fat-projections kill many registers which cannot be used to diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/loopTransform.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -269,10 +269,9 @@ bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const { Node *test = ((IdealLoopTree*)this)->tail(); int body_size = ((IdealLoopTree*)this)->_body.size(); - int live_node_count = phase->C->live_nodes(); // Peeling does loop cloning which can result in O(N^2) node construction if( body_size > 255 /* Prevent overflow for large body_size */ - || (body_size * body_size + live_node_count > MaxNodeLimit) ) { + || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) { return false; // too large to safely clone } while( test != _head ) { // Scan till run off top of loop @@ -601,7 +600,7 @@ return false; if (new_body_size > unroll_limit || // Unrolling can result in a large amount of node construction - new_body_size >= MaxNodeLimit - (uint) phase->C->live_nodes()) { + new_body_size >= phase->C->max_node_limit() - phase->C->live_nodes()) { return false; } @@ -882,6 +881,20 @@ return n; } +bool PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) { + Node* castii = new (C) CastIINode(incr, TypeInt::INT, true); + castii->set_req(0, ctrl); + register_new_node(castii, ctrl); + for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) { + Node* n = incr->fast_out(i); + if (n->is_Phi() && n->in(0) == loop) { + int nrep = n->replace_edge(incr, castii); + return true; + } + } + return false; +} + //------------------------------insert_pre_post_loops-------------------------- // Insert pre and post loops. If peel_only is set, the pre-loop can not have // more iterations added. It acts as a 'peel' only, no lower-bound RCE, no @@ -1080,6 +1093,24 @@ } } + // Nodes inside the loop may be control dependent on a predicate + // that was moved before the preloop. If the back branch of the main + // or post loops becomes dead, those nodes won't be dependent on the + // test that guards that loop nest anymore which could lead to an + // incorrect array access because it executes independently of the + // test that was guarding the loop nest. We add a special CastII on + // the if branch that enters the loop, between the input induction + // variable value and the induction variable Phi to preserve correct + // dependencies. + + // CastII for the post loop: + bool inserted = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head); + assert(inserted, "no castII inserted"); + + // CastII for the main loop: + inserted = cast_incr_before_loop(pre_incr, min_taken, main_head); + assert(inserted, "no castII inserted"); + // Step B4: Shorten the pre-loop to run only 1 iteration (for now). // RCE and alignment may change this later. Node *cmp_end = pre_end->cmp_node(); @@ -2287,8 +2318,8 @@ // Skip next optimizations if running low on nodes. Note that // policy_unswitching and policy_maximally_unroll have this check. - uint nodes_left = MaxNodeLimit - (uint) phase->C->live_nodes(); - if ((2 * _body.size()) > nodes_left) { + int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes(); + if ((int)(2 * _body.size()) > nodes_left) { return true; } diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/loopUnswitch.cpp --- a/src/share/vm/opto/loopUnswitch.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/loopUnswitch.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -59,8 +59,8 @@ if (!_head->is_Loop()) { return false; } - uint nodes_left = MaxNodeLimit - phase->C->live_nodes(); - if (2 * _body.size() > nodes_left) { + int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes(); + if ((int)(2 * _body.size()) > nodes_left) { return false; // Too speculative if running low on nodes. } LoopNode* head = _head->as_Loop(); diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/loopnode.hpp --- a/src/share/vm/opto/loopnode.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/loopnode.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -602,6 +602,8 @@ return ctrl; } + bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); + public: bool has_node( Node* n ) const { guarantee(n != NULL, "No Node."); diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/loopopts.cpp --- a/src/share/vm/opto/loopopts.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/loopopts.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -734,7 +734,7 @@ for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { weight += region->fast_out(i)->outcnt(); } - int nodes_left = MaxNodeLimit - C->live_nodes(); + int nodes_left = C->max_node_limit() - C->live_nodes(); if (weight * 8 > nodes_left) { #ifndef PRODUCT if (PrintOpto) diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/memnode.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -1255,6 +1255,16 @@ result = new (phase->C) ConvI2LNode(phase->transform(result)); } #endif + // Boxing/unboxing can be done from signed & unsigned loads (e.g. LoadUB -> ... -> LoadB pair). + // Need to preserve unboxing load type if it is unsigned. + switch(this->Opcode()) { + case Op_LoadUB: + result = new (phase->C) AndINode(phase->transform(result), phase->intcon(0xFF)); + break; + case Op_LoadUS: + result = new (phase->C) AndINode(phase->transform(result), phase->intcon(0xFFFF)); + break; + } return result; } } diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/node.cpp --- a/src/share/vm/opto/node.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/node.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -69,7 +69,7 @@ Compile::set_debug_idx(new_debug_idx); set_debug_idx( new_debug_idx ); assert(Compile::current()->unique() < (INT_MAX - 1), "Node limit exceeded INT_MAX"); - assert(Compile::current()->live_nodes() < (uint)MaxNodeLimit, "Live Node limit exceeded limit"); + assert(Compile::current()->live_nodes() < Compile::current()->max_node_limit(), "Live Node limit exceeded limit"); if (BreakAtNode != 0 && (_debug_idx == BreakAtNode || (int)_idx == BreakAtNode)) { tty->print_cr("BreakAtNode: _idx=%d _debug_idx=%d", _idx, _debug_idx); BREAKPOINT; @@ -326,7 +326,7 @@ Node::Node(uint req) : _idx(IDX_INIT(req)) { - assert( req < (uint)(MaxNodeLimit - NodeLimitFudgeFactor), "Input limit exceeded" ); + assert( req < Compile::current()->max_node_limit() - NodeLimitFudgeFactor, "Input limit exceeded" ); debug_only( verify_construction() ); NOT_PRODUCT(nodes_created++); if (req == 0) { diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/phaseX.cpp --- a/src/share/vm/opto/phaseX.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/phaseX.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -1340,15 +1340,27 @@ } } - if( use->is_Cmp() ) { // Enable CMP/BOOL optimization + uint use_op = use->Opcode(); + if(use->is_Cmp()) { // Enable CMP/BOOL optimization add_users_to_worklist(use); // Put Bool on worklist - // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the - // phi merging either 0 or 1 onto the worklist if (use->outcnt() > 0) { Node* bol = use->raw_out(0); if (bol->outcnt() > 0) { Node* iff = bol->raw_out(0); - if (iff->outcnt() == 2) { + if (use_op == Op_CmpI && + iff->is_CountedLoopEnd()) { + CountedLoopEndNode* cle = iff->as_CountedLoopEnd(); + if (cle->limit() == n && cle->phi() != NULL) { + // If an opaque node feeds into the limit condition of a + // CountedLoop, we need to process the Phi node for the + // induction variable when the opaque node is removed: + // the range of values taken by the Phi is now known and + // so its type is also known. + _worklist.push(cle->phi()); + } + } else if (iff->outcnt() == 2) { + // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the + // phi merging either 0 or 1 onto the worklist Node* ifproj0 = iff->raw_out(0); Node* ifproj1 = iff->raw_out(1); if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) { @@ -1360,9 +1372,26 @@ } } } + if (use_op == Op_CmpI) { + Node* in1 = use->in(1); + for (uint i = 0; i < in1->outcnt(); i++) { + if (in1->raw_out(i)->Opcode() == Op_CastII) { + Node* castii = in1->raw_out(i); + if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) { + Node* ifnode = castii->in(0)->in(0); + if (ifnode->in(1) != NULL && ifnode->in(1)->is_Bool() && ifnode->in(1)->in(1) == use) { + // Reprocess a CastII node that may depend on an + // opaque node value when the opaque node is + // removed. In case it carries a dependency we can do + // a better job of computing its type. + _worklist.push(castii); + } + } + } + } + } } - uint use_op = use->Opcode(); // If changed Cast input, check Phi users for simple cycles if( use->is_ConstraintCast() || use->is_CheckCastPP() ) { for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/subnode.cpp --- a/src/share/vm/opto/subnode.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/subnode.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -1147,12 +1147,10 @@ //------------------------------dump_spec------------------------------------- // Print special per-node info -#ifndef PRODUCT void BoolTest::dump_on(outputStream *st) const { const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"}; st->print("%s", msg[_test]); } -#endif //============================================================================= uint BoolNode::hash() const { return (Node::hash() << 3)|(_test._test+1); } diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/opto/subnode.hpp --- a/src/share/vm/opto/subnode.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/opto/subnode.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -275,9 +275,7 @@ mask commute( ) const { return mask("032147658"[_test]-'0'); } mask negate( ) const { return mask(_test^4); } bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); } -#ifndef PRODUCT void dump_on(outputStream *st) const; -#endif }; //------------------------------BoolNode--------------------------------------- diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/prims/jvm.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -603,13 +603,14 @@ // Make shallow object copy const int size = obj->size(); - oop new_obj = NULL; + oop new_obj_oop = NULL; if (obj->is_array()) { const int length = ((arrayOop)obj())->length(); - new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); + new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); } else { - new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); + new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); } + // 4839641 (4840070): We must do an oop-atomic copy, because if another thread // is modifying a reference field in the clonee, a non-oop-atomic copy might // be suspended in the middle of copying the pointer and end up with parts @@ -620,24 +621,41 @@ // The same is true of StubRoutines::object_copy and the various oop_copy // variants, and of the code generated by the inline_native_clone intrinsic. assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); - Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj, + Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop, (size_t)align_object_size(size) / HeapWordsPerLong); // Clear the header - new_obj->init_mark(); + new_obj_oop->init_mark(); // Store check (mark entire object and let gc sort it out) BarrierSet* bs = Universe::heap()->barrier_set(); assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); - bs->write_region(MemRegion((HeapWord*)new_obj, size)); + bs->write_region(MemRegion((HeapWord*)new_obj_oop, size)); + + Handle new_obj(THREAD, new_obj_oop); + // Special handling for MemberNames. Since they contain Method* metadata, they + // must be registered so that RedefineClasses can fix metadata contained in them. + if (java_lang_invoke_MemberName::is_instance(new_obj()) && + java_lang_invoke_MemberName::is_method(new_obj())) { + Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj()); + // MemberName may be unresolved, so doesn't need registration until resolved. + if (method != NULL) { + methodHandle m(THREAD, method); + // This can safepoint and redefine method, so need both new_obj and method + // in a handle, for two different reasons. new_obj can move, method can be + // deleted if nothing is using it on the stack. + m->method_holder()->add_member_name(new_obj()); + } + } // Caution: this involves a java upcall, so the clone should be // "gc-robust" by this stage. if (klass->has_finalizer()) { assert(obj->is_instance(), "should be instanceOop"); - new_obj = InstanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL); + new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL); + new_obj = Handle(THREAD, new_obj_oop); } - return JNIHandles::make_local(env, oop(new_obj)); + return JNIHandles::make_local(env, new_obj()); JVM_END // java.lang.Compiler //////////////////////////////////////////////////// @@ -4526,7 +4544,7 @@ JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size)) { - memset(info, 0, sizeof(info_size)); + memset(info, 0, info_size); info->jvm_version = Abstract_VM_Version::jvm_version(); info->update_version = 0; /* 0 in HotSpot Express VM */ diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/prims/jvmtiEnv.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderExt.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "interpreter/bytecodeStream.hpp" @@ -475,7 +476,7 @@ if (TraceClassLoading) { tty->print_cr("[Opened %s]", zip_entry->name()); } - ClassLoader::add_to_list(zip_entry); + ClassLoaderExt::append_boot_classpath(zip_entry); return JVMTI_ERROR_NONE; } else { return JVMTI_ERROR_WRONG_PHASE; diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/prims/methodHandles.cpp --- a/src/share/vm/prims/methodHandles.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/prims/methodHandles.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -29,7 +29,6 @@ #include "interpreter/oopMapCache.hpp" #include "memory/allocation.inline.hpp" #include "memory/oopFactory.hpp" -#include "prims/jvmtiRedefineClassesTrace.hpp" #include "prims/methodHandles.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/javaCalls.hpp" @@ -271,9 +270,12 @@ // This is done eagerly, since it is readily available without // constructing any new objects. // TO DO: maybe intern mname_oop - m->method_holder()->add_member_name(m->method_idnum(), mname); - - return mname(); + if (m->method_holder()->add_member_name(mname)) { + return mname(); + } else { + // Redefinition caused this to fail. Return NULL (and an exception?) + return NULL; + } } oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { @@ -946,63 +948,27 @@ } } -void MemberNameTable::add_member_name(int index, jweak mem_name_wref) { +void MemberNameTable::add_member_name(jweak mem_name_wref) { assert_locked_or_safepoint(MemberNameTable_lock); - this->at_put_grow(index, mem_name_wref); -} - -// Return a member name oop or NULL. -oop MemberNameTable::get_member_name(int index) { - assert_locked_or_safepoint(MemberNameTable_lock); - - jweak ref = this->at(index); - oop mem_name = JNIHandles::resolve(ref); - return mem_name; + this->push(mem_name_wref); } #if INCLUDE_JVMTI -oop MemberNameTable::find_member_name_by_method(Method* old_method) { - assert_locked_or_safepoint(MemberNameTable_lock); - oop found = NULL; - int len = this->length(); - - for (int idx = 0; idx < len; idx++) { - oop mem_name = JNIHandles::resolve(this->at(idx)); - if (mem_name == NULL) { - continue; - } - Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name); - if (method == old_method) { - found = mem_name; - break; - } - } - return found; -} - -// It is called at safepoint only +// It is called at safepoint only for RedefineClasses void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods, int methods_length, bool *trace_name_printed) { assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); - // search the MemberNameTable for uses of either obsolete or EMCP methods + // For each redefined method for (int j = 0; j < methods_length; j++) { Method* old_method = old_methods[j]; Method* new_method = new_methods[j]; - oop mem_name = find_member_name_by_method(old_method); - if (mem_name != NULL) { - java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method); - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { - if (!(*trace_name_printed)) { - // RC_TRACE_MESG macro has an embedded ResourceMark - RC_TRACE_MESG(("adjust: name=%s", - old_method->method_holder()->external_name())); - *trace_name_printed = true; - } - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00400000, ("MemberName method update: %s(%s)", - new_method->name()->as_C_string(), - new_method->signature()->as_C_string())); + // search the MemberNameTable for uses of either obsolete or EMCP methods + for (int idx = 0; idx < length(); idx++) { + oop mem_name = JNIHandles::resolve(this->at(idx)); + if (mem_name != NULL) { + java_lang_invoke_MemberName::adjust_vmtarget(mem_name, old_method, new_method, + trace_name_printed); } } } diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/prims/methodHandles.hpp --- a/src/share/vm/prims/methodHandles.hpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/prims/methodHandles.hpp Fri Dec 12 14:39:40 2014 -0800 @@ -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 @@ -236,18 +236,14 @@ public: MemberNameTable(int methods_cnt); ~MemberNameTable(); - void add_member_name(int index, jweak mem_name_ref); - oop get_member_name(int index); + void add_member_name(jweak mem_name_ref); #if INCLUDE_JVMTI - public: // RedefineClasses() API support: // If a MemberName refers to old_method then update it // to refer to new_method. void adjust_method_entries(Method** old_methods, Method** new_methods, int methods_length, bool *trace_name_printed); - private: - oop find_member_name_by_method(Method* old_method); #endif // INCLUDE_JVMTI }; diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/prims/whitebox.cpp --- a/src/share/vm/prims/whitebox.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/prims/whitebox.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -56,6 +56,7 @@ #endif // INCLUDE_NMT #include "compiler/compileBroker.hpp" +#include "jvmtifiles/jvmtiEnv.hpp" #include "runtime/compilationPolicy.hpp" PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC @@ -126,6 +127,29 @@ return result; WB_END +WB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) { +#if INCLUDE_JVMTI + ResourceMark rm; + const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment)); + JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION); + jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg); + assert(err == JVMTI_ERROR_NONE, "must not fail"); +#endif +} +WB_END + +WB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) { +#if INCLUDE_JVMTI + ResourceMark rm; + const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment)); + JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION); + jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg); + assert(err == JVMTI_ERROR_NONE, "must not fail"); +#endif +} +WB_END + + WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { return (jlong)Arguments::max_heap_for_compressed_oops(); } @@ -958,6 +982,10 @@ CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", (void*) &WB_ParseCommandLine }, + {CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V", + (void*)&WB_AddToBootstrapClassLoaderSearch}, + {CC"addToSystemClassLoaderSearch", CC"(Ljava/lang/String;)V", + (void*)&WB_AddToSystemClassLoaderSearch}, {CC"getCompressedOopsMaxHeapSize", CC"()J", (void*)&WB_GetCompressedOopsMaxHeapSize}, {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, diff -r d6a05415f1f4 -r 41c3c456e326 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon Dec 01 19:09:54 2014 -0800 +++ b/src/share/vm/runtime/arguments.cpp Fri Dec 12 14:39:40 2014 -0800 @@ -3543,7 +3543,7 @@ if (nonEmptyDirs > 0) { jio_fprintf(defaultStream::output_stream(), - "Endorsed standards override mechanism and extension mechanism" + "Endorsed standards override mechanism and extension mechanism " "will not be supported in a future release.\n" "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n"); return false; diff -r d6a05415f1f4 -r 41c3c456e326 test/compiler/EliminateAutoBox/UnsignedLoads.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/EliminateAutoBox/UnsignedLoads.java Fri Dec 12 14:39:40 2014 -0800 @@ -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. 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. + */ + +/* + * @test + * @library /testlibrary + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox + * -XX:CompileOnly=::valueOf,::byteValue,::shortValue,::testUnsignedByte,::testUnsignedShort + * UnsignedLoads + */ +import static com.oracle.java.testlibrary.Asserts.assertEQ; + +public class UnsignedLoads { + public static int testUnsignedByte() { + byte[] bytes = new byte[] {-1}; + int res = 0; + for (int i = 0; i < 100000; i++) { + for (Byte b : bytes) { + res = b & 0xff; + } + } + return res; + } + + public static int testUnsignedShort() { + int res = 0; + short[] shorts = new short[] {-1}; + for (int i = 0; i < 100000; i++) { + for (Short s : shorts) { + res = s & 0xffff; + } + } + return res; + } + + public static void main(String[] args) { + assertEQ(testUnsignedByte(), 255); + assertEQ(testUnsignedShort(), 65535); + System.out.println("TEST PASSED"); + } +} diff -r d6a05415f1f4 -r 41c3c456e326 test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java Fri Dec 12 14:39:40 2014 -0800 @@ -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. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; + +import com.oracle.java.testlibrary.*; + +/* + * @test + * @bug 8050079 + * @summary Compiles a monomorphic call to finalizeObject() on a modified java.lang.Object to test C1 CHA. + * @library /testlibrary + * @compile -XDignore.symbol.file java/lang/Object.java TestMonomorphicObjectCall.java + * @run main TestMonomorphicObjectCall + */ +public class TestMonomorphicObjectCall { + final static String testClasses = System.getProperty("test.classes") + File.separator; + + private static void callFinalize(Object object) throws Throwable { + // Call modified version of java.lang.Object::finalize() that is + // not overridden by any subclass. C1 CHA should mark the call site + // as monomorphic and inline the method. + object.finalizeObject(); + } + + public static void main(String[] args) throws Throwable { + if (args.length == 0) { + // Execute new instance with modified java.lang.Object + executeTestJvm(); + } else { + // Trigger compilation of 'callFinalize' + callFinalize(new Object()); + } + } + + public static void executeTestJvm() throws Throwable { + // Execute test with modified version of java.lang.Object + // in -Xbootclasspath. + String[] vmOpts = new String[] { + "-Xbootclasspath/p:" + testClasses, + "-Xcomp", + "-XX:-VerifyDependencies", + "-XX:CompileOnly=TestMonomorphicObjectCall::callFinalize", + "-XX:CompileOnly=Object::finalizeObject", + "-XX:TieredStopAtLevel=1", + TestMonomorphicObjectCall.class.getName(), + "true"}; + OutputAnalyzer output = ProcessTools.executeTestJvm(vmOpts); + output.shouldHaveExitValue(0); + } +} diff -r d6a05415f1f4 -r 41c3c456e326 test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java Fri Dec 12 14:39:40 2014 -0800 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved. + * 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 java.lang; + +/** + * Slightly modified version of java.lang.Object that replaces + * finalize() by finalizeObject() to avoid overriding in subclasses. + */ +public class Object { + + private static native void registerNatives(); + static { + registerNatives(); + } + + public final native Class getClass(); + + public native int hashCode(); + + public boolean equals(Object obj) { + return (this == obj); + } + + protected native Object clone() throws CloneNotSupportedException; + + public String toString() { + return getClass().getName() + "@" + Integer.toHexString(hashCode()); + } + + public final native void notify(); + + public final native void notifyAll(); + + public final native void wait(long timeout) throws InterruptedException; + + public final void wait(long timeout, int nanos) throws InterruptedException { + if (timeout < 0) { + throw new IllegalArgumentException("timeout value is negative"); + } + + if (nanos < 0 || nanos > 999999) { + throw new IllegalArgumentException( + "nanosecond timeout value out of range"); + } + + if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { + timeout++; + } + + wait(timeout); + } + + public final void wait() throws InterruptedException { + wait(0); + } + + /** + * Replaces original finalize() method and is therefore not + * overridden by any subclasses of Object. + * @throws Throwable + */ + // protected void finalize() throws Throwable { } + public void finalizeObject() throws Throwable { } +} diff -r d6a05415f1f4 -r 41c3c456e326 test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java Fri Dec 12 14:39:40 2014 -0800 @@ -0,0 +1,174 @@ +/* + * 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 8042235 + * @summary redefining method used by multiple MethodHandles crashes VM + * @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java + * @run main RedefineMethodUsedByMultipleMethodHandles + */ + +import java.io.*; +import java.lang.instrument.*; +import java.lang.invoke.*; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.management.*; +import java.lang.reflect.*; +import java.nio.file.*; +import java.security.*; +import java.util.jar.*; + +import javax.tools.*; + +import jdk.internal.org.objectweb.asm.*; + +public class RedefineMethodUsedByMultipleMethodHandles { + + static class Foo { + public static Object getName() { + return "foo"; + } + } + + public static void main(String[] args) throws Throwable { + + Lookup lookup = MethodHandles.lookup(); + Method fooMethod = Foo.class.getDeclaredMethod("getName"); + + // fooMH2 displaces fooMH1 from the MemberNamesTable + MethodHandle fooMH1 = lookup.unreflect(fooMethod); + MethodHandle fooMH2 = lookup.unreflect(fooMethod); + + System.out.println("fooMH1.invoke = " + fooMH1.invokeExact()); + System.out.println("fooMH2.invoke = " + fooMH2.invokeExact()); + + // Redefining Foo.getName() causes vmtarget to be updated + // in fooMH2 but not fooMH1 + redefineFoo(); + + // Full GC causes fooMH1.vmtarget to be deallocated + System.gc(); + + // Calling fooMH1.vmtarget crashes the VM + System.out.println("fooMH1.invoke = " + fooMH1.invokeExact()); + } + + /** + * Adds the class file bytes for {@code c} to {@code jar}. + */ + static void add(JarOutputStream jar, Class c) throws IOException { + String classAsPath = c.getName().replace('.', '/') + ".class"; + jar.putNextEntry(new JarEntry(classAsPath)); + InputStream stream = c.getClassLoader().getResourceAsStream(classAsPath); + + int b; + while ((b = stream.read()) != -1) { + jar.write(b); + } + } + + static void redefineFoo() throws Exception { + Manifest manifest = new Manifest(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + Attributes mainAttrs = manifest.getMainAttributes(); + mainAttrs.putValue("Agent-Class", FooAgent.class.getName()); + mainAttrs.putValue("Can-Redefine-Classes", "true"); + mainAttrs.putValue("Can-Retransform-Classes", "true"); + + Path jar = Files.createTempFile("myagent", ".jar"); + try { + JarOutputStream jarStream = new JarOutputStream(new FileOutputStream(jar.toFile()), manifest); + add(jarStream, FooAgent.class); + add(jarStream, FooTransformer.class); + jarStream.close(); + runAgent(jar); + } finally { + Files.deleteIfExists(jar); + } + } + + public static void runAgent(Path agent) throws Exception { + String vmName = ManagementFactory.getRuntimeMXBean().getName(); + int p = vmName.indexOf('@'); + assert p != -1 : "VM name not in @ format: " + vmName; + String pid = vmName.substring(0, p); + ClassLoader cl = ToolProvider.getSystemToolClassLoader(); + Class c = Class.forName("com.sun.tools.attach.VirtualMachine", true, cl); + Method attach = c.getDeclaredMethod("attach", String.class); + Method loadAgent = c.getDeclaredMethod("loadAgent", String.class); + Method detach = c.getDeclaredMethod("detach"); + Object vm = attach.invoke(null, pid); + loadAgent.invoke(vm, agent.toString()); + detach.invoke(vm); + } + + public static class FooAgent { + + public static void agentmain(@SuppressWarnings("unused") String args, Instrumentation inst) throws Exception { + assert inst.isRedefineClassesSupported(); + assert inst.isRetransformClassesSupported(); + inst.addTransformer(new FooTransformer(), true); + Class[] classes = inst.getAllLoadedClasses(); + for (int i = 0; i < classes.length; i++) { + Class c = classes[i]; + if (c == Foo.class) { + inst.retransformClasses(new Class[]{c}); + } + } + } + } + + static class FooTransformer implements ClassFileTransformer { + + @Override + public byte[] transform(ClassLoader cl, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { + if (Foo.class.equals(classBeingRedefined)) { + System.out.println("redefining " + classBeingRedefined); + ClassReader cr = new ClassReader(classfileBuffer); + ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); + ClassVisitor adapter = new ClassVisitor(Opcodes.ASM5, cw) { + @Override + public MethodVisitor visitMethod(int access, String base, String desc, String signature, String[] exceptions) { + MethodVisitor mv = cv.visitMethod(access, base, desc, signature, exceptions); + if (mv != null) { + mv = new MethodVisitor(Opcodes.ASM5, mv) { + @Override + public void visitLdcInsn(Object cst) { + System.out.println("replacing \"" + cst + "\" with \"bar\""); + mv.visitLdcInsn("bar"); + } + }; + } + return mv; + } + }; + + cr.accept(adapter, ClassReader.SKIP_FRAMES); + cw.visitEnd(); + return cw.toByteArray(); + } + return classfileBuffer; + } + } +} diff -r d6a05415f1f4 -r 41c3c456e326 test/compiler/loopopts/TestDeadBackbranchArrayAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/loopopts/TestDeadBackbranchArrayAccess.java Fri Dec 12 14:39:40 2014 -0800 @@ -0,0 +1,58 @@ +/* + * 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 8054478 + * @summary dead backbranch in main loop results in erroneous array access + * @run main/othervm -XX:CompileOnly=TestDeadBackbranchArrayAccess -Xcomp TestDeadBackbranchArrayAccess + * + */ + +public class TestDeadBackbranchArrayAccess { + static char[] pattern0 = {0}; + static char[] pattern1 = {1}; + + static void test(char[] array) { + if (pattern1 == null) return; + + int i = 0; + int pos = 0; + char c = array[pos]; + + while (i >= 0 && (c == pattern0[i] || c == pattern1[i])) { + i--; + pos--; + if (pos != -1) { + c = array[pos]; + } + } + } + + public static void main(String[] args) { + for (int i = 0; i < 1000000; i++) { + test(new char[1]); + } + } +} diff -r d6a05415f1f4 -r 41c3c456e326 test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java --- a/test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java Mon Dec 01 19:09:54 2014 -0800 +++ b/test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java Fri Dec 12 14:39:40 2014 -0800 @@ -26,10 +26,16 @@ * @bug 8064667 * @summary Sanity test for -XX:+CheckEndorsedAndExtDirs * @library /testlibrary - * @run main/othervm -XX:+CheckEndorsedAndExtDirs EndorsedExtDirs + * @run main/othervm EndorsedExtDirs */ import com.oracle.java.testlibrary.*; +import java.io.File; +import java.io.IOException; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -38,9 +44,28 @@ public static void main(String arg[]) throws Exception { fatalError("-XX:+CheckEndorsedAndExtDirs", "-Djava.endorsed.dirs=foo"); fatalError("-XX:+CheckEndorsedAndExtDirs", "-Djava.ext.dirs=bar"); + testNonEmptySystemExtDirs(); } - static void fatalError(String... args) throws Exception { + static void testNonEmptySystemExtDirs() throws Exception { + String home = System.getProperty("java.home"); + Path ext = Paths.get(home, "lib", "ext"); + String extDirs = System.getProperty("java.ext.dirs"); + String[] dirs = extDirs.split(File.pathSeparator); + long count = 0; + for (String d : dirs) { + Path path = Paths.get(d); + if (Files.notExists(path) || path.equals(ext)) continue; + count += Files.find(path, 1, (Path p, BasicFileAttributes attr) + -> p.getFileName().toString().endsWith(".jar")) + .count(); + } + if (count > 0) { + fatalError("-XX:+CheckEndorsedAndExtDirs"); + } + } + + static ProcessBuilder newProcessBuilder(String... args) { List commands = new ArrayList<>(); String java = System.getProperty("java.home") + "/bin/java"; commands.add(java); @@ -51,8 +76,15 @@ commands.add(cpath); commands.add("EndorsedExtDirs"); - System.out.println("Launching " + commands); - ProcessBuilder pb = new ProcessBuilder(commands); + System.out.println("Process " + commands); + return new ProcessBuilder(commands); + } + + static void fatalError(String... args) throws Exception { + fatalError(newProcessBuilder(args)); + } + + static void fatalError(ProcessBuilder pb) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Could not create the Java Virtual Machine"); output.shouldHaveExitValue(1); diff -r d6a05415f1f4 -r 41c3c456e326 test/testlibrary/whitebox/sun/hotspot/WhiteBox.java --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Dec 01 19:09:54 2014 -0800 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Fri Dec 12 14:39:40 2014 -0800 @@ -90,6 +90,10 @@ public native URL[] getLookupCacheURLs(ClassLoader loader); public native int[] getLookupCacheMatches(ClassLoader loader, String name); + // JVMTI + public native void addToBootstrapClassLoaderSearch(String segment); + public native void addToSystemClassLoaderSearch(String segment); + // G1 public native boolean g1InConcurrentMark(); public native boolean g1IsHumongous(Object o);