1 /*
2  * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 /*
24  */
25 
26 
27 package org.graalvm.compiler.core.test.deopt;
28 
29 import java.util.concurrent.CountDownLatch;
30 
31 import org.junit.Assert;
32 import org.junit.Assume;
33 import org.junit.Test;
34 
35 import org.graalvm.compiler.core.common.GraalOptions;
36 import org.graalvm.compiler.core.test.GraalCompilerTest;
37 
38 import jdk.vm.ci.code.InstalledCode;
39 
40 public final class SafepointRethrowDeoptTest extends GraalCompilerTest {
41 
42     private static final Object RETURN_VALUE = "1 2 3";
43     private static final RuntimeException BREAK_EX = new RuntimeException();
44     private static final RuntimeException CONTINUE_EX = new RuntimeException();
45     private static volatile int terminate;
46     private static volatile int entered;
47 
execute()48     public static Object execute() {
49         entered = 1;
50         for (;;) {
51             try {
52                 if (terminate != 0) {
53                     throw BREAK_EX;
54                 } else {
55                     throw CONTINUE_EX;
56                 }
57             } catch (RuntimeException e) {
58                 if (e == BREAK_EX) {
59                     break;
60                 } else if (e == CONTINUE_EX) {
61                     continue;
62                 }
63                 throw e;
64             }
65         }
66         return RETURN_VALUE;
67     }
68 
69     @Test
test()70     public void test() {
71         Assume.assumeTrue(GraalOptions.GenLoopSafepoints.getValue(getInitialOptions()));
72         synchronized (SafepointRethrowDeoptTest.class) {
73             // needs static fields
74             terminate = 1;
75 
76             InstalledCode installed = getCode(getResolvedJavaMethod("execute"));
77 
78             terminate = 0;
79             entered = 0;
80             CountDownLatch cdl = new CountDownLatch(1);
81             Thread t1 = new Thread(() -> {
82                 try {
83                     cdl.await();
84                     while (entered == 0) {
85                         /* spin */
86                     }
87                     installed.invalidate();
88                 } catch (InterruptedException e) {
89                     Assert.fail("interrupted");
90                 } finally {
91                     terminate = 1;
92                 }
93             });
94             Thread t2 = new Thread(() -> {
95                 cdl.countDown();
96                 Object result;
97                 try {
98                     result = installed.executeVarargs();
99                 } catch (Exception e) {
100                     e.printStackTrace();
101                     Assert.fail("exception");
102                     return;
103                 }
104                 Assert.assertEquals(RETURN_VALUE, result);
105             });
106 
107             t1.start();
108             t2.start();
109             try {
110                 t1.join();
111                 t2.join();
112             } catch (InterruptedException e) {
113                 Assert.fail("interrupted");
114             }
115         }
116     }
117 }
118