Wed, 06 Aug 2014 08:47:40 +0200
8029443: 'assert(klass->is_loader_alive(_is_alive)) failed: must be alive' during VM_CollectForMetadataAllocation
Summary: Added missing metadata relocation to 'loadConP_no_oop_cheap' on Sparc if the pointer is referring to a Klass. Added jtreg test.
Reviewed-by: kvn
1.1 --- a/src/cpu/sparc/vm/sparc.ad Thu Jul 31 19:59:36 2014 +0200 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Wed Aug 06 08:47:40 2014 +0200 1.3 @@ -6184,7 +6184,11 @@ 1.4 ins_cost(DEFAULT_COST * 3/2); 1.5 format %{ "SET $con,$dst\t! non-oop ptr" %} 1.6 ins_encode %{ 1.7 - __ set($con$$constant, $dst$$Register); 1.8 + if (_opnds[1]->constant_reloc() == relocInfo::metadata_type) { 1.9 + __ set_metadata_constant((Metadata*)$con$$constant, $dst$$Register); 1.10 + } else { 1.11 + __ set($con$$constant, $dst$$Register); 1.12 + } 1.13 %} 1.14 ins_pipe(loadConP); 1.15 %}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java Wed Aug 06 08:47:40 2014 +0200 2.3 @@ -0,0 +1,145 @@ 2.4 +/* 2.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +import sun.hotspot.WhiteBox; 2.28 + 2.29 +import java.lang.reflect.Method; 2.30 +import java.net.URL; 2.31 +import java.net.URLClassLoader; 2.32 + 2.33 +/* 2.34 + * @test MethodUnloadingTest 2.35 + * @bug 8029443 2.36 + * @summary "Tests the unloading of methods to to class unloading" 2.37 + * @library /testlibrary /testlibrary/whitebox 2.38 + * @build TestMethodUnloading 2.39 + * @build WorkerClass 2.40 + * @run main ClassFileInstaller sun.hotspot.WhiteBox 2.41 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseCompressedOops -XX:+UseParallelGC -XX:CompileOnly=TestMethodUnloading::doWork TestMethodUnloading 2.42 + */ 2.43 +public class TestMethodUnloading { 2.44 + private static final String workerClassName = "WorkerClass"; 2.45 + private static int work = -1; 2.46 + 2.47 + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 2.48 + private static int COMP_LEVEL_SIMPLE = 1; 2.49 + private static int COMP_LEVEL_FULL_OPTIMIZATION = 4; 2.50 + 2.51 + /** 2.52 + * Does some work by either using the workerClass or locally producing values. 2.53 + * @param workerClass Class performing some work (will be unloaded) 2.54 + * @param useWorker If true the workerClass is used 2.55 + */ 2.56 + static private void doWork(Class<?> workerClass, boolean useWorker) throws InstantiationException, IllegalAccessException { 2.57 + if (useWorker) { 2.58 + // Create a new instance 2.59 + Object worker = workerClass.newInstance(); 2.60 + // We would like to call a method of WorkerClass here but we cannot cast to WorkerClass 2.61 + // because the class was loaded by a different class loader. One solution would be to use 2.62 + // reflection but since we want C2 to implement the call as an optimized IC we call 2.63 + // Object::hashCode() here which actually calls WorkerClass::hashCode(). 2.64 + // C2 will then implement this call as an optimized IC that points to a to-interpreter stub 2.65 + // referencing the Method* for WorkerClass::hashCode(). 2.66 + work = worker.hashCode(); 2.67 + if (work != 42) { 2.68 + new RuntimeException("Work not done"); 2.69 + } 2.70 + } else { 2.71 + // Do some important work here 2.72 + work = 1; 2.73 + } 2.74 + } 2.75 + 2.76 + /** 2.77 + * Makes sure that method is compiled by forcing compilation if not yet compiled. 2.78 + * @param m Method to be checked 2.79 + */ 2.80 + static private void makeSureIsCompiled(Method m) { 2.81 + // Make sure background compilation is disabled 2.82 + if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) { 2.83 + throw new RuntimeException("Background compilation enabled"); 2.84 + } 2.85 + 2.86 + // Check if already compiled 2.87 + if (!WHITE_BOX.isMethodCompiled(m)) { 2.88 + // If not, try to compile it with C2 2.89 + if(!WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION)) { 2.90 + // C2 compiler not available, try to compile with C1 2.91 + WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_SIMPLE); 2.92 + } 2.93 + // Because background compilation is disabled, method should now be compiled 2.94 + if(!WHITE_BOX.isMethodCompiled(m)) { 2.95 + throw new RuntimeException(m + " not compiled"); 2.96 + } 2.97 + } 2.98 + } 2.99 + 2.100 + /** 2.101 + * This test creates stale Method* metadata in a to-interpreter stub of an optimized IC. 2.102 + * 2.103 + * The following steps are performed: 2.104 + * (1) A workerClass is loaded by a custom class loader 2.105 + * (2) The method doWork that calls a method of the workerClass is compiled. The call 2.106 + * is implemented as an optimized IC calling a to-interpreted stub. The to-interpreter 2.107 + * stub contains a Method* to a workerClass method. 2.108 + * (3) Unloading of the workerClass is enforced. The to-interpreter stub now contains a dead Method*. 2.109 + * (4) Depending on the implementation of the IC, the compiled version of doWork should still be 2.110 + * valid. We call it again without using the workerClass. 2.111 + */ 2.112 + static public void main(String[] args) throws Exception { 2.113 + // (1) Create a custom class loader with no parent class loader 2.114 + URL url = TestMethodUnloading.class.getProtectionDomain().getCodeSource().getLocation(); 2.115 + URLClassLoader loader = new URLClassLoader(new URL[] {url}, null); 2.116 + 2.117 + // Load worker class with custom class loader 2.118 + Class<?> workerClass = Class.forName(workerClassName, true, loader); 2.119 + 2.120 + // (2) Make sure all paths of doWork are profiled and compiled 2.121 + for (int i = 0; i < 100000; ++i) { 2.122 + doWork(workerClass, true); 2.123 + doWork(workerClass, false); 2.124 + } 2.125 + 2.126 + // Make sure doWork is compiled now 2.127 + Method doWork = TestMethodUnloading.class.getDeclaredMethod("doWork", Class.class, boolean.class); 2.128 + makeSureIsCompiled(doWork); 2.129 + 2.130 + // (3) Throw away class loader and reference to workerClass to allow unloading 2.131 + loader.close(); 2.132 + loader = null; 2.133 + workerClass = null; 2.134 + 2.135 + // Force garbage collection to trigger unloading of workerClass 2.136 + // Dead reference to WorkerClass::hashCode triggers JDK-8029443 2.137 + WHITE_BOX.fullGC(); 2.138 + 2.139 + // (4) Depending on the implementation of the IC, the compiled version of doWork 2.140 + // may still be valid here. Execute it without a workerClass. 2.141 + doWork(null, false); 2.142 + if (work != 1) { 2.143 + throw new RuntimeException("Work not done"); 2.144 + } 2.145 + 2.146 + doWork(Object.class, false); 2.147 + } 2.148 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/compiler/classUnloading/methodUnloading/WorkerClass.java Wed Aug 06 08:47:40 2014 +0200 3.3 @@ -0,0 +1,37 @@ 3.4 +/* 3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/** 3.28 + * Worker class that is dynamically loaded/unloaded by TestMethodUnloading. 3.29 + */ 3.30 +public class WorkerClass { 3.31 + /** 3.32 + * We override hashCode here to be able to access this implementation 3.33 + * via an Object reference (we cannot cast to WorkerClass). 3.34 + */ 3.35 + @Override 3.36 + public int hashCode() { 3.37 + return 42; 3.38 + } 3.39 +} 3.40 +