# HG changeset patch # User Roland Schatz # Date 1414491301 -3600 # Node ID b9f31ed0643b9dc138d6f235bf6e96cf60a07dd3 # Parent 89f97291c3a5c18796a521d6bdac228449b201a8 Unit tests for data patches. diff -r 89f97291c3a5 -r b9f31ed0643b graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/DataPatchInConstantsTest.java --- /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); + } + } + } +} diff -r 89f97291c3a5 -r b9f31ed0643b graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/DataPatchTest.java --- /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); + } +} diff -r 89f97291c3a5 -r b9f31ed0643b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- 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); }