001/*
002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.replacements.test;
024
025import jdk.internal.jvmci.code.*;
026import jdk.internal.jvmci.meta.*;
027
028import org.junit.*;
029
030import com.oracle.graal.compiler.test.*;
031import com.oracle.graal.nodes.*;
032import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
033import com.oracle.graal.nodes.calc.*;
034import com.oracle.graal.nodes.extended.*;
035import com.oracle.graal.nodes.memory.address.*;
036import com.oracle.graal.phases.*;
037import com.oracle.graal.phases.common.*;
038import com.oracle.graal.phases.tiers.*;
039import com.oracle.graal.replacements.*;
040import com.oracle.graal.word.*;
041import com.oracle.graal.word.nodes.*;
042
043/**
044 * Tests for the {@link Pointer} read and write operations.
045 */
046public class PointerTest extends GraalCompilerTest implements Snippets {
047
048    private static final LocationIdentity ID = NamedLocationIdentity.mutable("ID");
049    private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object};
050    private final TargetDescription target;
051    private final ReplacementsImpl installer;
052
053    public PointerTest() {
054        target = getCodeCache().getTarget();
055        installer = (ReplacementsImpl) getProviders().getReplacements();
056    }
057
058    @Override
059    protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) {
060        return installer.makeGraph(m, null, null);
061    }
062
063    @Test
064    public void testRead1() {
065        for (Kind kind : KINDS) {
066            assertRead(parseEager("read" + kind.name() + "1", AllowAssumptions.YES), kind, true, ID);
067        }
068    }
069
070    @Test
071    public void testRead2() {
072        for (Kind kind : KINDS) {
073            assertRead(parseEager("read" + kind.name() + "2", AllowAssumptions.YES), kind, true, ID);
074        }
075    }
076
077    @Test
078    public void testRead3() {
079        for (Kind kind : KINDS) {
080            assertRead(parseEager("read" + kind.name() + "3", AllowAssumptions.YES), kind, true, LocationIdentity.any());
081        }
082    }
083
084    @Test
085    public void testWrite1() {
086        for (Kind kind : KINDS) {
087            assertWrite(parseEager("write" + kind.name() + "1", AllowAssumptions.YES), true, ID);
088        }
089    }
090
091    @Test
092    public void testWrite2() {
093        for (Kind kind : KINDS) {
094            assertWrite(parseEager("write" + kind.name() + "2", AllowAssumptions.YES), true, ID);
095        }
096    }
097
098    @Test
099    public void testWrite3() {
100        for (Kind kind : KINDS) {
101            assertWrite(parseEager("write" + kind.name() + "3", AllowAssumptions.YES), true, LocationIdentity.any());
102        }
103    }
104
105    private void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) {
106        WordCastNode cast = (WordCastNode) graph.start().next();
107
108        JavaReadNode read = (JavaReadNode) cast.next();
109        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
110
111        OffsetAddressNode address = (OffsetAddressNode) read.getAddress();
112        Assert.assertEquals(cast, address.getBase());
113        Assert.assertEquals(graph.getParameter(0), cast.getInput());
114        Assert.assertEquals(target.wordKind, cast.stamp().getStackKind());
115
116        Assert.assertEquals(locationIdentity, read.getLocationIdentity());
117
118        if (indexConvert) {
119            SignExtendNode convert = (SignExtendNode) address.getOffset();
120            Assert.assertEquals(convert.getInputBits(), 32);
121            Assert.assertEquals(convert.getResultBits(), 64);
122            Assert.assertEquals(graph.getParameter(1), convert.getValue());
123        } else {
124            Assert.assertEquals(graph.getParameter(1), address.getOffset());
125        }
126
127        ReturnNode ret = (ReturnNode) read.next();
128        Assert.assertEquals(read, ret.result());
129    }
130
131    private void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) {
132        WordCastNode cast = (WordCastNode) graph.start().next();
133
134        JavaWriteNode write = (JavaWriteNode) cast.next();
135        Assert.assertEquals(graph.getParameter(2), write.value());
136        Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci);
137
138        OffsetAddressNode address = (OffsetAddressNode) write.getAddress();
139        Assert.assertEquals(cast, address.getBase());
140        Assert.assertEquals(graph.getParameter(0), cast.getInput());
141        Assert.assertEquals(target.wordKind, cast.stamp().getStackKind());
142
143        Assert.assertEquals(locationIdentity, write.getLocationIdentity());
144
145        if (indexConvert) {
146            SignExtendNode convert = (SignExtendNode) address.getOffset();
147            Assert.assertEquals(convert.getInputBits(), 32);
148            Assert.assertEquals(convert.getResultBits(), 64);
149            Assert.assertEquals(graph.getParameter(1), convert.getValue());
150        } else {
151            Assert.assertEquals(graph.getParameter(1), address.getOffset());
152        }
153
154        ReturnNode ret = (ReturnNode) write.next();
155        Assert.assertEquals(null, ret.result());
156    }
157
158    @Snippet
159    public static byte readByte1(Object o, int offset) {
160        return Word.fromObject(o).readByte(offset, ID);
161    }
162
163    @Snippet
164    public static byte readByte2(Object o, int offset) {
165        return Word.fromObject(o).readByte(Word.signed(offset), ID);
166    }
167
168    @Snippet
169    public static byte readByte3(Object o, int offset) {
170        return Word.fromObject(o).readByte(offset);
171    }
172
173    @Snippet
174    public static void writeByte1(Object o, int offset, byte value) {
175        Word.fromObject(o).writeByte(offset, value, ID);
176    }
177
178    @Snippet
179    public static void writeByte2(Object o, int offset, byte value) {
180        Word.fromObject(o).writeByte(Word.signed(offset), value, ID);
181    }
182
183    @Snippet
184    public static void writeByte3(Object o, int offset, byte value) {
185        Word.fromObject(o).writeByte(offset, value);
186    }
187
188    @Snippet
189    public static char readChar1(Object o, int offset) {
190        return Word.fromObject(o).readChar(offset, ID);
191    }
192
193    @Snippet
194    public static char readChar2(Object o, int offset) {
195        return Word.fromObject(o).readChar(Word.signed(offset), ID);
196    }
197
198    @Snippet
199    public static char readChar3(Object o, int offset) {
200        return Word.fromObject(o).readChar(offset);
201    }
202
203    @Snippet
204    public static void writeChar1(Object o, int offset, char value) {
205        Word.fromObject(o).writeChar(offset, value, ID);
206    }
207
208    @Snippet
209    public static void writeChar2(Object o, int offset, char value) {
210        Word.fromObject(o).writeChar(Word.signed(offset), value, ID);
211    }
212
213    @Snippet
214    public static void writeChar3(Object o, int offset, char value) {
215        Word.fromObject(o).writeChar(offset, value);
216    }
217
218    @Snippet
219    public static short readShort1(Object o, int offset) {
220        return Word.fromObject(o).readShort(offset, ID);
221    }
222
223    @Snippet
224    public static short readShort2(Object o, int offset) {
225        return Word.fromObject(o).readShort(Word.signed(offset), ID);
226    }
227
228    @Snippet
229    public static short readShort3(Object o, int offset) {
230        return Word.fromObject(o).readShort(offset);
231    }
232
233    @Snippet
234    public static void writeShort1(Object o, int offset, short value) {
235        Word.fromObject(o).writeShort(offset, value, ID);
236    }
237
238    @Snippet
239    public static void writeShort2(Object o, int offset, short value) {
240        Word.fromObject(o).writeShort(Word.signed(offset), value, ID);
241    }
242
243    @Snippet
244    public static void writeShort3(Object o, int offset, short value) {
245        Word.fromObject(o).writeShort(offset, value);
246    }
247
248    @Snippet
249    public static int readInt1(Object o, int offset) {
250        return Word.fromObject(o).readInt(offset, ID);
251    }
252
253    @Snippet
254    public static int readInt2(Object o, int offset) {
255        return Word.fromObject(o).readInt(Word.signed(offset), ID);
256    }
257
258    @Snippet
259    public static int readInt3(Object o, int offset) {
260        return Word.fromObject(o).readInt(offset);
261    }
262
263    @Snippet
264    public static void writeInt1(Object o, int offset, int value) {
265        Word.fromObject(o).writeInt(offset, value, ID);
266    }
267
268    @Snippet
269    public static void writeInt2(Object o, int offset, int value) {
270        Word.fromObject(o).writeInt(Word.signed(offset), value, ID);
271    }
272
273    @Snippet
274    public static void writeInt3(Object o, int offset, int value) {
275        Word.fromObject(o).writeInt(offset, value);
276    }
277
278    @Snippet
279    public static long readLong1(Object o, int offset) {
280        return Word.fromObject(o).readLong(offset, ID);
281    }
282
283    @Snippet
284    public static long readLong2(Object o, int offset) {
285        return Word.fromObject(o).readLong(Word.signed(offset), ID);
286    }
287
288    @Snippet
289    public static long readLong3(Object o, int offset) {
290        return Word.fromObject(o).readLong(offset);
291    }
292
293    @Snippet
294    public static void writeLong1(Object o, int offset, long value) {
295        Word.fromObject(o).writeLong(offset, value, ID);
296    }
297
298    @Snippet
299    public static void writeLong2(Object o, int offset, long value) {
300        Word.fromObject(o).writeLong(Word.signed(offset), value, ID);
301    }
302
303    @Snippet
304    public static void writeLong3(Object o, int offset, long value) {
305        Word.fromObject(o).writeLong(offset, value);
306    }
307
308    @Snippet
309    public static float readFloat1(Object o, int offset) {
310        return Word.fromObject(o).readFloat(offset, ID);
311    }
312
313    @Snippet
314    public static float readFloat2(Object o, int offset) {
315        return Word.fromObject(o).readFloat(Word.signed(offset), ID);
316    }
317
318    @Snippet
319    public static float readFloat3(Object o, int offset) {
320        return Word.fromObject(o).readFloat(offset);
321    }
322
323    @Snippet
324    public static void writeFloat1(Object o, int offset, float value) {
325        Word.fromObject(o).writeFloat(offset, value, ID);
326    }
327
328    @Snippet
329    public static void writeFloat2(Object o, int offset, float value) {
330        Word.fromObject(o).writeFloat(Word.signed(offset), value, ID);
331    }
332
333    @Snippet
334    public static void writeFloat3(Object o, int offset, float value) {
335        Word.fromObject(o).writeFloat(offset, value);
336    }
337
338    @Snippet
339    public static double readDouble1(Object o, int offset) {
340        return Word.fromObject(o).readDouble(offset, ID);
341    }
342
343    @Snippet
344    public static double readDouble2(Object o, int offset) {
345        return Word.fromObject(o).readDouble(Word.signed(offset), ID);
346    }
347
348    @Snippet
349    public static double readDouble3(Object o, int offset) {
350        return Word.fromObject(o).readDouble(offset);
351    }
352
353    @Snippet
354    public static void writeDouble1(Object o, int offset, double value) {
355        Word.fromObject(o).writeDouble(offset, value, ID);
356    }
357
358    @Snippet
359    public static void writeDouble2(Object o, int offset, double value) {
360        Word.fromObject(o).writeDouble(Word.signed(offset), value, ID);
361    }
362
363    @Snippet
364    public static void writeDouble3(Object o, int offset, double value) {
365        Word.fromObject(o).writeDouble(offset, value);
366    }
367
368    @Snippet
369    public static Object readObject1(Object o, int offset) {
370        return Word.fromObject(o).readObject(offset, ID);
371    }
372
373    @Snippet
374    public static Object readObject2(Object o, int offset) {
375        return Word.fromObject(o).readObject(Word.signed(offset), ID);
376    }
377
378    @Snippet
379    public static Object readObject3(Object o, int offset) {
380        return Word.fromObject(o).readObject(offset);
381    }
382
383    @Snippet
384    public static void writeObject1(Object o, int offset, Object value) {
385        Word.fromObject(o).writeObject(offset, value, ID);
386    }
387
388    @Snippet
389    public static void writeObject2(Object o, int offset, Object value) {
390        Word.fromObject(o).writeObject(Word.signed(offset), value, ID);
391    }
392
393    @Snippet
394    public static void writeObject3(Object o, int offset, Object value) {
395        Word.fromObject(o).writeObject(offset, value);
396    }
397
398    private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
399        HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL);
400
401        StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES);
402        new CanonicalizerPhase().apply(graph, context);
403        Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count());
404    }
405
406    @Test
407    public void testUnusedFromObject() {
408        assertNumWordCasts("unusedFromObject", 0);
409    }
410
411    @Snippet
412    public static void unusedFromObject(Object o) {
413        Word.fromObject(o);
414    }
415
416    @Test
417    public void testUnusedRawValue() {
418        assertNumWordCasts("unusedRawValue", 0);
419    }
420
421    @Snippet
422    public static void unusedRawValue(Object o) {
423        Word.fromObject(o).rawValue();
424    }
425
426    @Test
427    public void testUsedRawValue() {
428        assertNumWordCasts("usedRawValue", 1);
429    }
430
431    @Snippet
432    public static long usedRawValue(Object o) {
433        return Word.fromObject(o).rawValue();
434    }
435
436    @Test
437    public void testUnusedToObject() {
438        assertNumWordCasts("unusedToObject", 0);
439    }
440
441    @Snippet
442    public static void unusedToObject(Word w) {
443        w.toObject();
444    }
445
446    @Test
447    public void testUsedToObject() {
448        assertNumWordCasts("usedToObject", 1);
449    }
450
451    @Snippet
452    public static Object usedToObject(Word w) {
453        return w.toObject();
454    }
455}