24
24
*/
25
25
package jdk .graal .compiler .core .test .ea ;
26
26
27
+ import java .util .ArrayList ;
28
+ import java .util .Collections ;
29
+ import java .util .List ;
30
+
27
31
import org .junit .Assert ;
28
32
import org .junit .Test ;
29
33
34
+ import jdk .graal .compiler .api .directives .GraalDirectives ;
35
+ import jdk .graal .compiler .core .common .GraalOptions ;
30
36
import jdk .graal .compiler .core .test .GraalCompilerTest ;
37
+ import jdk .graal .compiler .debug .GraalError ;
31
38
import jdk .graal .compiler .nodes .StructuredGraph ;
32
39
import jdk .graal .compiler .nodes .StructuredGraph .AllowAssumptions ;
33
40
import jdk .graal .compiler .nodes .java .LoadFieldNode ;
41
+ import jdk .graal .compiler .options .OptionValues ;
34
42
import jdk .graal .compiler .virtual .phases .ea .ReadEliminationPhase ;
43
+ import jdk .vm .ci .code .InstalledCode ;
35
44
36
45
public class FinalReadEliminationTest extends GraalCompilerTest {
37
46
@@ -59,7 +68,7 @@ public void testAccrossVolatile01() {
59
68
StructuredGraph g = parseEager (getResolvedJavaMethod ("snippetAccessVolatile1" ), AllowAssumptions .NO );
60
69
createCanonicalizerPhase ().apply (g , getDefaultHighTierContext ());
61
70
new ReadEliminationPhase (createCanonicalizerPhase ()).apply (g , getDefaultHighTierContext ());
62
- Assert .assertEquals (1 , g .getNodes ().filter (LoadFieldNode .class ).filter (x -> !((LoadFieldNode ) x ).field ().isVolatile ()).count ());
71
+ Assert .assertEquals (2 , g .getNodes ().filter (LoadFieldNode .class ).filter (x -> !((LoadFieldNode ) x ).field ().isVolatile ()).count ());
63
72
}
64
73
65
74
public static int snippetAccessVolatile2 (A a ) {
@@ -76,4 +85,120 @@ public void testAccrossVolatile02() {
76
85
new ReadEliminationPhase (createCanonicalizerPhase ()).apply (g , getDefaultHighTierContext ());
77
86
Assert .assertEquals (2 , g .getNodes ().filter (LoadFieldNode .class ).filter (x -> !((LoadFieldNode ) x ).field ().isVolatile ()).count ());
78
87
}
88
+
89
+ // Checkstyle: stop
90
+ public static final boolean LOG = false ;
91
+
92
+ static class ThisEscaper {
93
+ final int x ;
94
+ static volatile ThisEscaper volatileField1 ;
95
+
96
+ ThisEscaper () {
97
+ volatileField1 = this ;
98
+ while (!flag1 ) {
99
+ }
100
+ this .x = 42 ;
101
+ flag = true ;
102
+ }
103
+ }
104
+
105
+ static volatile boolean flag ;
106
+
107
+ static volatile boolean flag1 ;
108
+
109
+ // compile this method
110
+ static void readerAction () {
111
+ if (GraalDirectives .inCompiledCode ()) {
112
+ if (LOG ) {
113
+ GraalDirectives .log ("Executing compiled code\n " );
114
+ }
115
+ }
116
+ while (ThisEscaper .volatileField1 == null ) {
117
+ }
118
+ ThisEscaper localA = ThisEscaper .volatileField1 ;
119
+ int t1 = localA .x ; // = 0
120
+ while (!flag ) {
121
+ /* loop until it changed */
122
+ }
123
+ int t2 = localA .x ; // = 42
124
+
125
+ if (t1 == t2 ) {
126
+ throw new IllegalArgumentException ("must be different values but is t1=" + t1 + " t2=" + t2 );
127
+ }
128
+ if (t1 != 0 || t2 != 42 ) {
129
+ throw new IllegalArgumentException ("whaat t1=" + t1 + " t2=" + t2 );
130
+ }
131
+ if (LOG ) {
132
+ System .out .printf ("t1=%s t2=%s%n" , t1 , t2 );
133
+ }
134
+ }
135
+
136
+ static Runnable readerRunnable = new Runnable () {
137
+
138
+ @ Override
139
+ public void run () {
140
+ readerAction ();
141
+ }
142
+ };
143
+ static Runnable setRunnable = new Runnable () {
144
+
145
+ @ Override
146
+ public void run () {
147
+ try {
148
+ if (LOG ) {
149
+ System .out .println ("Starting sleeping before setting flag1" );
150
+ }
151
+ Thread .sleep (1000 * 2 );
152
+ if (LOG ) {
153
+ System .out .println ("Done sleeping before setting flag1" );
154
+ }
155
+ } catch (InterruptedException e ) {
156
+ throw GraalError .shouldNotReachHere (e );
157
+ }
158
+ flag1 = true ;
159
+ if (LOG ) {
160
+ System .out .println ("Done setting flag1" );
161
+ }
162
+ }
163
+ };
164
+
165
+ @ SuppressWarnings ("unused" )
166
+ @ Test
167
+ public void testThreadsThisEscape () throws InterruptedException {
168
+ // first do all compiles
169
+ OptionValues opt = new OptionValues (getInitialOptions (), GraalOptions .OptConvertDeoptsToGuards , false );
170
+ InstalledCode ic = getCode (getResolvedJavaMethod ("readerAction" ), null , true , true , opt );
171
+ assert ic .isAlive ();
172
+ assert ic .isValid ();
173
+
174
+ // then run the program
175
+ Thread readerThread = new Thread (readerRunnable );
176
+ Thread setThread = new Thread (setRunnable );
177
+
178
+ List <Throwable > t = Collections .synchronizedList (new ArrayList <Throwable >());
179
+
180
+ Thread .UncaughtExceptionHandler h = new Thread .UncaughtExceptionHandler () {
181
+ @ Override
182
+ public void uncaughtException (Thread th , Throwable ex ) {
183
+ t .add (ex );
184
+ }
185
+ };
186
+
187
+ readerThread .setUncaughtExceptionHandler (h );
188
+ setThread .setUncaughtExceptionHandler (h );
189
+
190
+ readerThread .start ();
191
+ setThread .start ();
192
+
193
+ // start them then allocate
194
+ new ThisEscaper ();
195
+
196
+ readerThread .join ();
197
+ setThread .join ();
198
+
199
+ for (Throwable throwable : t ) {
200
+ throw GraalError .shouldNotReachHere (throwable );
201
+ }
202
+ }
203
+ // Checkstyle: resume
79
204
}
0 commit comments