changeset 18178:b9f31ed0643b

Unit tests for data patches.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 28 Oct 2014 11:15:01 +0100
parents 89f97291c3a5
children 37be28df9dd7
files graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/DataPatchInConstantsTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/DataPatchTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java
diffstat 3 files changed, 319 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/DataPatchInConstantsTest.java	Tue Oct 28 11:15:01 2014 +0100
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.amd64.test;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.nodes.CompressionNode.CompressionOp;
+import com.oracle.graal.hotspot.nodes.type.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class DataPatchInConstantsTest extends GraalCompilerTest {
+
+    private static final Object object = new Object() {
+
+        @Override
+        public String toString() {
+            return "testObject";
+        }
+    };
+
+    private static Object loadThroughPatch(Object obj) {
+        return obj;
+    }
+
+    public static Object oopSnippet() {
+        Object patch = loadThroughPatch(object);
+        if (object != patch) {
+            return "invalid patch";
+        }
+        System.gc();
+        patch = loadThroughPatch(object);
+        if (object != patch) {
+            return "failed after gc";
+        }
+        return patch;
+    }
+
+    @Test
+    public void oopTest() {
+        test("oopSnippet");
+    }
+
+    private static Object loadThroughCompressedPatch(Object obj) {
+        return obj;
+    }
+
+    public static Object narrowOopSnippet() {
+        Object patch = loadThroughCompressedPatch(object);
+        if (object != patch) {
+            return "invalid patch";
+        }
+        System.gc();
+        patch = loadThroughCompressedPatch(object);
+        if (object != patch) {
+            return "failed after gc";
+        }
+        return patch;
+    }
+
+    @Test
+    public void narrowOopTest() {
+        Assume.assumeTrue("skipping narrow oop data patch test", config.useCompressedOops);
+        test("narrowOopSnippet");
+    }
+
+    public static Object compareSnippet() {
+        Object uncompressed = loadThroughPatch(object);
+        Object compressed = loadThroughCompressedPatch(object);
+        if (object != uncompressed) {
+            return "uncompressed failed";
+        }
+        if (object != compressed) {
+            return "compressed failed";
+        }
+        if (uncompressed != compressed) {
+            return "uncompressed != compressed";
+        }
+        return object;
+    }
+
+    @Test
+    public void compareTest() {
+        Assume.assumeTrue("skipping narrow oop data patch test", config.useCompressedOops);
+        test("compareSnippet");
+    }
+
+    private static final HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
+    private static boolean initReplacements = false;
+
+    @Before
+    public void initReplacements() {
+        if (!initReplacements) {
+            getReplacements().registerSubstitutions(DataPatchInConstantsTest.class, DataPatchInConstantsTestSubstitutions.class);
+            initReplacements = true;
+        }
+    }
+
+    @ClassSubstitution(DataPatchInConstantsTest.class)
+    private static class DataPatchInConstantsTestSubstitutions {
+
+        @MethodSubstitution
+        public static Object loadThroughPatch(Object obj) {
+            return LoadThroughPatchNode.load(obj);
+        }
+
+        @MethodSubstitution
+        public static Object loadThroughCompressedPatch(Object obj) {
+            Object compressed = CompressionNode.compression(CompressionOp.Compress, obj, config.getOopEncoding());
+            Object patch = LoadThroughPatchNode.load(compressed);
+            return CompressionNode.compression(CompressionOp.Uncompress, patch, config.getOopEncoding());
+        }
+    }
+
+    @NodeInfo
+    private static class LoadThroughPatchNode extends FixedWithNextNode implements LIRLowerable {
+
+        @Input protected ValueNode input;
+
+        public static LoadThroughPatchNode create(ValueNode input) {
+            return new LoadThroughPatchNode(input);
+        }
+
+        protected LoadThroughPatchNode(ValueNode input) {
+            super(input.stamp());
+            this.input = input;
+        }
+
+        public void generate(NodeLIRBuilderTool generator) {
+            assert input.isConstant();
+
+            LIRGeneratorTool gen = generator.getLIRGeneratorTool();
+            Variable ret = gen.newVariable(gen.getLIRKind(stamp()));
+
+            gen.append(new LoadThroughPatchOp(input.asConstant(), stamp() instanceof NarrowOopStamp, ret));
+            generator.setResult(this, ret);
+        }
+
+        @NodeIntrinsic
+        public static native Object load(Object obj);
+    }
+
+    private static class LoadThroughPatchOp extends LIRInstructionBase {
+
+        final Constant c;
+        final boolean compressed;
+        @Def({REG}) AllocatableValue result;
+
+        LoadThroughPatchOp(Constant c, boolean compressed, AllocatableValue result) {
+            this.c = c;
+            this.compressed = compressed;
+            this.result = result;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb) {
+            AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(c, compressed ? 4 : 8);
+            AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
+            if (compressed) {
+                asm.movl(asRegister(result), address);
+            } else {
+                asm.movq(asRegister(result), address);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/DataPatchTest.java	Tue Oct 28 11:15:01 2014 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.nodes.CompressionNode.CompressionOp;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class DataPatchTest extends GraalCompilerTest {
+
+    public static double doubleSnippet() {
+        return 84.72;
+    }
+
+    @Test
+    public void doubleTest() {
+        test("doubleSnippet");
+    }
+
+    public static Object oopSnippet() {
+        return "asdf";
+    }
+
+    @Test
+    public void oopTest() {
+        test("oopSnippet");
+    }
+
+    private static Object compressUncompress(Object obj) {
+        return obj;
+    }
+
+    public static Object narrowOopSnippet() {
+        return compressUncompress("narrowAsdf");
+    }
+
+    @Test
+    public void narrowOopTest() {
+        Assume.assumeTrue("skipping narrow oop data patch test", config.useCompressedOops);
+        test("narrowOopSnippet");
+    }
+
+    private static final HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
+    private static boolean initReplacements = false;
+
+    @Before
+    public void initReplacements() {
+        if (!initReplacements) {
+            getReplacements().registerSubstitutions(DataPatchTest.class, DataPatchTestSubstitutions.class);
+            initReplacements = true;
+        }
+    }
+
+    @ClassSubstitution(DataPatchTest.class)
+    private static class DataPatchTestSubstitutions {
+
+        @MethodSubstitution
+        public static Object compressUncompress(Object obj) {
+            Object compressed = CompressionNode.compression(CompressionOp.Compress, obj, config.getOopEncoding());
+            Object proxy = ConstantFoldBarrier.wrap(compressed);
+            return CompressionNode.compression(CompressionOp.Uncompress, proxy, config.getOopEncoding());
+        }
+    }
+
+    @NodeInfo
+    private static class ConstantFoldBarrier extends FloatingNode implements LIRLowerable {
+
+        @Input protected ValueNode input;
+
+        public static ConstantFoldBarrier create(ValueNode input) {
+            return new ConstantFoldBarrier(input);
+        }
+
+        protected ConstantFoldBarrier(ValueNode input) {
+            super(input.stamp());
+            this.input = input;
+        }
+
+        public void generate(NodeLIRBuilderTool generator) {
+            generator.setResult(this, generator.operand(input));
+        }
+
+        @NodeIntrinsic
+        public static native Object wrap(Object object);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon Oct 27 14:24:02 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Tue Oct 28 11:15:01 2014 +0100
@@ -42,7 +42,7 @@
 @NodeInfo(nameTemplate = "{p#op/s}")
 public class CompressionNode extends UnaryNode implements ConvertNode, LIRLowerable {
 
-    enum CompressionOp {
+    public enum CompressionOp {
         Compress,
         Uncompress
     }
@@ -196,4 +196,7 @@
         }
         gen.setResult(this, result);
     }
+
+    @NodeIntrinsic
+    public static native Object compression(@ConstantNodeParameter CompressionOp op, Object object, @ConstantNodeParameter CompressEncoding encoding);
 }