PointerTest.java revision 12657:6ef01bd40ce2
1/*
2 * Copyright (c) 2013, 2016, 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 */
23package org.graalvm.compiler.replacements.test;
24
25import org.junit.Assert;
26import org.junit.Test;
27
28import org.graalvm.compiler.api.replacements.Snippet;
29import org.graalvm.compiler.core.common.CompilationIdentifier;
30import org.graalvm.compiler.core.common.LocationIdentity;
31import org.graalvm.compiler.core.test.GraalCompilerTest;
32import org.graalvm.compiler.nodes.NamedLocationIdentity;
33import org.graalvm.compiler.nodes.ReturnNode;
34import org.graalvm.compiler.nodes.StructuredGraph;
35import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
36import org.graalvm.compiler.nodes.calc.SignExtendNode;
37import org.graalvm.compiler.nodes.extended.JavaReadNode;
38import org.graalvm.compiler.nodes.extended.JavaWriteNode;
39import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
40import org.graalvm.compiler.phases.OptimisticOptimizations;
41import org.graalvm.compiler.phases.common.CanonicalizerPhase;
42import org.graalvm.compiler.phases.tiers.HighTierContext;
43import org.graalvm.compiler.replacements.ReplacementsImpl;
44import org.graalvm.compiler.replacements.Snippets;
45import org.graalvm.compiler.word.Pointer;
46import org.graalvm.compiler.word.Word;
47import org.graalvm.compiler.word.nodes.WordCastNode;
48
49import jdk.vm.ci.code.BytecodeFrame;
50import jdk.vm.ci.code.TargetDescription;
51import jdk.vm.ci.meta.JavaKind;
52import jdk.vm.ci.meta.ResolvedJavaMethod;
53
54/**
55 * Tests for the {@link Pointer} read and write operations.
56 */
57public class PointerTest extends GraalCompilerTest implements Snippets {
58
59    private static final LocationIdentity ID = NamedLocationIdentity.mutable("ID");
60    private static final JavaKind[] KINDS = new JavaKind[]{JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Float, JavaKind.Double, JavaKind.Object};
61    private final TargetDescription target;
62    private final ReplacementsImpl installer;
63
64    public PointerTest() {
65        target = getCodeCache().getTarget();
66        installer = (ReplacementsImpl) getProviders().getReplacements();
67    }
68
69    @Override
70    protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {
71        return installer.makeGraph(m, null, null);
72    }
73
74    @Test
75    public void testRead1() {
76        for (JavaKind kind : KINDS) {
77            assertRead(parseEager("read" + kind.name() + "1", AllowAssumptions.YES), kind, true, ID);
78        }
79    }
80
81    @Test
82    public void testRead2() {
83        for (JavaKind kind : KINDS) {
84            assertRead(parseEager("read" + kind.name() + "2", AllowAssumptions.YES), kind, true, ID);
85        }
86    }
87
88    @Test
89    public void testRead3() {
90        for (JavaKind kind : KINDS) {
91            assertRead(parseEager("read" + kind.name() + "3", AllowAssumptions.YES), kind, true, LocationIdentity.any());
92        }
93    }
94
95    @Test
96    public void testWrite1() {
97        for (JavaKind kind : KINDS) {
98            assertWrite(parseEager("write" + kind.name() + "1", AllowAssumptions.YES), true, ID);
99        }
100    }
101
102    @Test
103    public void testWrite2() {
104        for (JavaKind kind : KINDS) {
105            assertWrite(parseEager("write" + kind.name() + "2", AllowAssumptions.YES), true, ID);
106        }
107    }
108
109    @Test
110    public void testWrite3() {
111        for (JavaKind kind : KINDS) {
112            assertWrite(parseEager("write" + kind.name() + "3", AllowAssumptions.YES), true, LocationIdentity.any());
113        }
114    }
115
116    private void assertRead(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity) {
117        WordCastNode cast = (WordCastNode) graph.start().next();
118
119        JavaReadNode read = (JavaReadNode) cast.next();
120        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
121
122        OffsetAddressNode address = (OffsetAddressNode) read.getAddress();
123        Assert.assertEquals(cast, address.getBase());
124        Assert.assertEquals(graph.getParameter(0), cast.getInput());
125        Assert.assertEquals(target.wordJavaKind, cast.stamp().getStackKind());
126
127        Assert.assertEquals(locationIdentity, read.getLocationIdentity());
128
129        if (indexConvert) {
130            SignExtendNode convert = (SignExtendNode) address.getOffset();
131            Assert.assertEquals(convert.getInputBits(), 32);
132            Assert.assertEquals(convert.getResultBits(), 64);
133            Assert.assertEquals(graph.getParameter(1), convert.getValue());
134        } else {
135            Assert.assertEquals(graph.getParameter(1), address.getOffset());
136        }
137
138        ReturnNode ret = (ReturnNode) read.next();
139        Assert.assertEquals(read, ret.result());
140    }
141
142    private void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) {
143        WordCastNode cast = (WordCastNode) graph.start().next();
144
145        JavaWriteNode write = (JavaWriteNode) cast.next();
146        Assert.assertEquals(graph.getParameter(2), write.value());
147        Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci);
148
149        OffsetAddressNode address = (OffsetAddressNode) write.getAddress();
150        Assert.assertEquals(cast, address.getBase());
151        Assert.assertEquals(graph.getParameter(0), cast.getInput());
152        Assert.assertEquals(target.wordJavaKind, cast.stamp().getStackKind());
153
154        Assert.assertEquals(locationIdentity, write.getLocationIdentity());
155
156        if (indexConvert) {
157            SignExtendNode convert = (SignExtendNode) address.getOffset();
158            Assert.assertEquals(convert.getInputBits(), 32);
159            Assert.assertEquals(convert.getResultBits(), 64);
160            Assert.assertEquals(graph.getParameter(1), convert.getValue());
161        } else {
162            Assert.assertEquals(graph.getParameter(1), address.getOffset());
163        }
164
165        ReturnNode ret = (ReturnNode) write.next();
166        Assert.assertEquals(null, ret.result());
167    }
168
169    @Snippet
170    public static byte readByte1(Object o, int offset) {
171        return Word.objectToTrackedPointer(o).readByte(offset, ID);
172    }
173
174    @Snippet
175    public static byte readByte2(Object o, int offset) {
176        return Word.objectToTrackedPointer(o).readByte(Word.signed(offset), ID);
177    }
178
179    @Snippet
180    public static byte readByte3(Object o, int offset) {
181        return Word.objectToTrackedPointer(o).readByte(offset);
182    }
183
184    @Snippet
185    public static void writeByte1(Object o, int offset, byte value) {
186        Word.objectToTrackedPointer(o).writeByte(offset, value, ID);
187    }
188
189    @Snippet
190    public static void writeByte2(Object o, int offset, byte value) {
191        Word.objectToTrackedPointer(o).writeByte(Word.signed(offset), value, ID);
192    }
193
194    @Snippet
195    public static void writeByte3(Object o, int offset, byte value) {
196        Word.objectToTrackedPointer(o).writeByte(offset, value);
197    }
198
199    @Snippet
200    public static char readChar1(Object o, int offset) {
201        return Word.objectToTrackedPointer(o).readChar(offset, ID);
202    }
203
204    @Snippet
205    public static char readChar2(Object o, int offset) {
206        return Word.objectToTrackedPointer(o).readChar(Word.signed(offset), ID);
207    }
208
209    @Snippet
210    public static char readChar3(Object o, int offset) {
211        return Word.objectToTrackedPointer(o).readChar(offset);
212    }
213
214    @Snippet
215    public static void writeChar1(Object o, int offset, char value) {
216        Word.objectToTrackedPointer(o).writeChar(offset, value, ID);
217    }
218
219    @Snippet
220    public static void writeChar2(Object o, int offset, char value) {
221        Word.objectToTrackedPointer(o).writeChar(Word.signed(offset), value, ID);
222    }
223
224    @Snippet
225    public static void writeChar3(Object o, int offset, char value) {
226        Word.objectToTrackedPointer(o).writeChar(offset, value);
227    }
228
229    @Snippet
230    public static short readShort1(Object o, int offset) {
231        return Word.objectToTrackedPointer(o).readShort(offset, ID);
232    }
233
234    @Snippet
235    public static short readShort2(Object o, int offset) {
236        return Word.objectToTrackedPointer(o).readShort(Word.signed(offset), ID);
237    }
238
239    @Snippet
240    public static short readShort3(Object o, int offset) {
241        return Word.objectToTrackedPointer(o).readShort(offset);
242    }
243
244    @Snippet
245    public static void writeShort1(Object o, int offset, short value) {
246        Word.objectToTrackedPointer(o).writeShort(offset, value, ID);
247    }
248
249    @Snippet
250    public static void writeShort2(Object o, int offset, short value) {
251        Word.objectToTrackedPointer(o).writeShort(Word.signed(offset), value, ID);
252    }
253
254    @Snippet
255    public static void writeShort3(Object o, int offset, short value) {
256        Word.objectToTrackedPointer(o).writeShort(offset, value);
257    }
258
259    @Snippet
260    public static int readInt1(Object o, int offset) {
261        return Word.objectToTrackedPointer(o).readInt(offset, ID);
262    }
263
264    @Snippet
265    public static int readInt2(Object o, int offset) {
266        return Word.objectToTrackedPointer(o).readInt(Word.signed(offset), ID);
267    }
268
269    @Snippet
270    public static int readInt3(Object o, int offset) {
271        return Word.objectToTrackedPointer(o).readInt(offset);
272    }
273
274    @Snippet
275    public static void writeInt1(Object o, int offset, int value) {
276        Word.objectToTrackedPointer(o).writeInt(offset, value, ID);
277    }
278
279    @Snippet
280    public static void writeInt2(Object o, int offset, int value) {
281        Word.objectToTrackedPointer(o).writeInt(Word.signed(offset), value, ID);
282    }
283
284    @Snippet
285    public static void writeInt3(Object o, int offset, int value) {
286        Word.objectToTrackedPointer(o).writeInt(offset, value);
287    }
288
289    @Snippet
290    public static long readLong1(Object o, int offset) {
291        return Word.objectToTrackedPointer(o).readLong(offset, ID);
292    }
293
294    @Snippet
295    public static long readLong2(Object o, int offset) {
296        return Word.objectToTrackedPointer(o).readLong(Word.signed(offset), ID);
297    }
298
299    @Snippet
300    public static long readLong3(Object o, int offset) {
301        return Word.objectToTrackedPointer(o).readLong(offset);
302    }
303
304    @Snippet
305    public static void writeLong1(Object o, int offset, long value) {
306        Word.objectToTrackedPointer(o).writeLong(offset, value, ID);
307    }
308
309    @Snippet
310    public static void writeLong2(Object o, int offset, long value) {
311        Word.objectToTrackedPointer(o).writeLong(Word.signed(offset), value, ID);
312    }
313
314    @Snippet
315    public static void writeLong3(Object o, int offset, long value) {
316        Word.objectToTrackedPointer(o).writeLong(offset, value);
317    }
318
319    @Snippet
320    public static float readFloat1(Object o, int offset) {
321        return Word.objectToTrackedPointer(o).readFloat(offset, ID);
322    }
323
324    @Snippet
325    public static float readFloat2(Object o, int offset) {
326        return Word.objectToTrackedPointer(o).readFloat(Word.signed(offset), ID);
327    }
328
329    @Snippet
330    public static float readFloat3(Object o, int offset) {
331        return Word.objectToTrackedPointer(o).readFloat(offset);
332    }
333
334    @Snippet
335    public static void writeFloat1(Object o, int offset, float value) {
336        Word.objectToTrackedPointer(o).writeFloat(offset, value, ID);
337    }
338
339    @Snippet
340    public static void writeFloat2(Object o, int offset, float value) {
341        Word.objectToTrackedPointer(o).writeFloat(Word.signed(offset), value, ID);
342    }
343
344    @Snippet
345    public static void writeFloat3(Object o, int offset, float value) {
346        Word.objectToTrackedPointer(o).writeFloat(offset, value);
347    }
348
349    @Snippet
350    public static double readDouble1(Object o, int offset) {
351        return Word.objectToTrackedPointer(o).readDouble(offset, ID);
352    }
353
354    @Snippet
355    public static double readDouble2(Object o, int offset) {
356        return Word.objectToTrackedPointer(o).readDouble(Word.signed(offset), ID);
357    }
358
359    @Snippet
360    public static double readDouble3(Object o, int offset) {
361        return Word.objectToTrackedPointer(o).readDouble(offset);
362    }
363
364    @Snippet
365    public static void writeDouble1(Object o, int offset, double value) {
366        Word.objectToTrackedPointer(o).writeDouble(offset, value, ID);
367    }
368
369    @Snippet
370    public static void writeDouble2(Object o, int offset, double value) {
371        Word.objectToTrackedPointer(o).writeDouble(Word.signed(offset), value, ID);
372    }
373
374    @Snippet
375    public static void writeDouble3(Object o, int offset, double value) {
376        Word.objectToTrackedPointer(o).writeDouble(offset, value);
377    }
378
379    @Snippet
380    public static Object readObject1(Object o, int offset) {
381        return Word.objectToTrackedPointer(o).readObject(offset, ID);
382    }
383
384    @Snippet
385    public static Object readObject2(Object o, int offset) {
386        return Word.objectToTrackedPointer(o).readObject(Word.signed(offset), ID);
387    }
388
389    @Snippet
390    public static Object readObject3(Object o, int offset) {
391        return Word.objectToTrackedPointer(o).readObject(offset);
392    }
393
394    @Snippet
395    public static void writeObject1(Object o, int offset, Object value) {
396        Word.objectToTrackedPointer(o).writeObject(offset, value, ID);
397    }
398
399    @Snippet
400    public static void writeObject2(Object o, int offset, Object value) {
401        Word.objectToTrackedPointer(o).writeObject(Word.signed(offset), value, ID);
402    }
403
404    @Snippet
405    public static void writeObject3(Object o, int offset, Object value) {
406        Word.objectToTrackedPointer(o).writeObject(offset, value);
407    }
408
409    private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
410        HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL);
411
412        StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES);
413        new CanonicalizerPhase().apply(graph, context);
414        Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count());
415    }
416
417    @Test
418    public void testUnusedFromObject() {
419        assertNumWordCasts("unusedFromObject", 0);
420    }
421
422    @Snippet
423    public static void unusedFromObject(Object o) {
424        Word.objectToTrackedPointer(o);
425    }
426
427    @Test
428    public void testUnusedRawValue() {
429        assertNumWordCasts("unusedRawValue", 0);
430    }
431
432    @Snippet
433    public static void unusedRawValue(Object o) {
434        Word.objectToTrackedPointer(o).rawValue();
435    }
436
437    @Test
438    public void testUsedRawValue() {
439        assertNumWordCasts("usedRawValue", 1);
440    }
441
442    @Snippet
443    public static long usedRawValue(Object o) {
444        return Word.objectToTrackedPointer(o).rawValue();
445    }
446
447    @Test
448    public void testUnusedToObject() {
449        assertNumWordCasts("unusedToObject", 0);
450    }
451
452    @Snippet
453    public static void unusedToObject(Word w) {
454        w.toObject();
455    }
456
457    @Test
458    public void testUsedToObject() {
459        assertNumWordCasts("usedToObject", 1);
460    }
461
462    @Snippet
463    public static Object usedToObject(Word w) {
464        return w.toObject();
465    }
466}
467