Path: blob/master/test/hotspot/jtreg/compiler/c2/Test6880034.java
41149 views
/*1* Copyright (c) 2009 SAP SE. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 688003426* @summary SIGBUS during deoptimisation at a safepoint on 64bit-SPARC27*28* @run main/othervm -Xcomp -Xbatch29* -XX:+PrintCompilation30* -XX:CompileCommand=compileonly,compiler.c2.Test6880034::deopt_compiledframe_at_safepoint31* compiler.c2.Test688003432*/3334package compiler.c2;3536// This test provokes a deoptimisation at a safepoint.37//38// It achieves this by compiling the method 'deopt_compiledframe_at_safepoint'39// before its first usage at a point in time when a call to the virtual method40// A::doSomething() from within 'deopt_compiledframe_at_safepoint' can be41// optimised to a static call because class A has no descendants.42//43// Later, when deopt_compiledframe_at_safepoint() is running, class B which44// extends A and overrides the virtual method "doSomething()", is loaded45// asynchronously in another thread. This makes the compiled code of46// 'deopt_compiledframe_at_safepoint' invalid and triggers a deoptimisation of47// the frame where 'deopt_compiledframe_at_safepoint' is running in a48// loop.49//50// The deoptimisation leads to a SIGBUS on 64-bit server VMs on SPARC and to51// an incorrect result on 32-bit server VMs on SPARC due to a regression52// introduced by the change: "6420645: Create a vm that uses compressed oops53// for up to 32gb heapsizes"54// (http://hg.openjdk.java.net/jdk7/jdk7/hotspot/rev/ba764ed4b6f2). Further55// investigation showed that change 6420645 is not really the root cause of56// this error but only reveals a problem with the float register encodings in57// sparc.ad which was hidden until now.58//59// Notice that for this test to fail in jtreg it is crucial that60// deopt_compiledframe_at_safepoint() runs in the main thread. Otherwise a61// crash in deopt_compiledframe_at_safepoint() will not be detected as a test62// failure by jtreg.63//64// Author: Volker H. Simonis6566public class Test6880034 {67static class A {68public int doSomething() {69return 0;70}71}7273static class B extends A {74public B() {}75// override 'A::doSomething()'76public int doSomething() {77return 1;78}79}8081static class G {82public static volatile A a = new A();8384// Change 'a' to point to a 'B' object85public static void setAtoB() {86try {87a = (A) ClassLoader.88getSystemClassLoader().89loadClass("B").90getConstructor(new Class[] {}).91newInstance(new Object[] {});92}93catch (Exception e) {94System.out.println(e);95}96}97}9899public static volatile boolean is_in_loop = false;100public static volatile boolean stop_while_loop = false;101102public static double deopt_compiledframe_at_safepoint() {103// This will be an optimised static call to A::doSomething() until we load "B"104int i = G.a.doSomething();105106// Need more than 16 'double' locals in this frame107double local1 = 1;108double local2 = 2;109double local3 = 3;110double local4 = 4;111double local5 = 5;112double local6 = 6;113double local7 = 7;114double local8 = 8;115116long k = 0;117// Once we load "B", this method will be made 'not entrant' and deoptimised118// at the safepoint which is at the end of this loop.119while (!stop_while_loop) {120if (k == 1) local1 += i;121if (k == 2) local2 += i;122if (k == 3) local3 += i;123if (k == 4) local4 += i;124if (k == 5) local5 += i;125if (k == 6) local6 += i;126if (k == 7) local7 += i;127if (k == 8) local8 += i;128129// Tell the world that we're now running wild in the loop130if (k++ == 20000) is_in_loop = true;131}132133return134local1 + local2 + local3 + local4 +135local5 + local6 + local7 + local8 + i;136}137138public static void main(String[] args) {139140// Just to resolve G before we compile deopt_compiledframe_at_safepoint()141G g = new G();142143// Asynchronous thread which will eventually invalidate the code for144// deopt_compiledframe_at_safepoint() and therefore triggering a145// deoptimisation of that method.146new Thread() {147public void run() {148while (!is_in_loop) {149// Wait until the loop is running150}151// Load class 'B' asynchronously..152G.setAtoB();153// ..and stop the loop154stop_while_loop = true;155}156}.start();157158// Run the loop in deopt_compiledframe_at_safepoint()159double retVal = deopt_compiledframe_at_safepoint();160161System.out.println(retVal == 36 ? "OK" : "ERROR : " + retVal);162if (retVal != 36) throw new RuntimeException();163}164}165166167