# HG changeset patch # User Thomas Wuerthinger # Date 1429725030 -7200 # Node ID de2fb3e4df49528deed5c0bae468ee2a1a5ec702 # Parent c5365790bf4967e20db16f5ec880fd0b079d7faa# Parent 2e9250b29d1417e3ebe15fff9b0ed3eccf7eb80b Merge. diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed Apr 22 19:50:30 2015 +0200 @@ -2249,8 +2249,8 @@ } } - public void nullCheck(Register r) { - testl(AMD64.rax, new AMD64Address(r, 0)); + public void nullCheck(AMD64Address address) { + testl(AMD64.rax, address); } @Override diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/CompressedNullCheckTest.java --- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/CompressedNullCheckTest.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/CompressedNullCheckTest.java Wed Apr 22 19:50:30 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -24,11 +24,15 @@ import org.junit.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.options.*; +import com.oracle.graal.options.OptionValue.OverrideScope; /** * Ensures that frame omission works in cases where it is expected to. @@ -36,17 +40,60 @@ public class CompressedNullCheckTest extends GraalCompilerTest { private static final class Container { - Integer i = new Integer(1); + Integer i; } public static void testSnippet(Container c) { c.i.intValue(); } + private void testImplicit(Integer i) { + Assume.assumeTrue(HotSpotGraalRuntime.runtime().getConfig().useCompressedOops); + + Container c = new Container(); + c.i = i; + + try (OverrideScope s = OptionValue.override(GraalOptions.OptImplicitNullChecks, true)) { + ResolvedJavaMethod method = getResolvedJavaMethod("testSnippet"); + Result expect = executeExpected(method, null, c); + + // make sure we don't get a profile that removes the implicit null check + method.reprofile(); + + Result actual = executeActual(method, null, c); + assertEquals(expect, actual); + } + } + + private void testExplicit(Integer i) { + Assume.assumeTrue(HotSpotGraalRuntime.runtime().getConfig().useCompressedOops); + + Container c = new Container(); + c.i = i; + + try (OverrideScope s = OptionValue.override(GraalOptions.OptImplicitNullChecks, false)) { + test("testSnippet", c); + } + } + @Test - public void test() { - Assume.assumeTrue(HotSpotGraalRuntime.runtime().getConfig().useCompressedOops); - test("testSnippet", new Container()); + public void implicit() { + testImplicit(new Integer(1)); + } + + @Test + public void implicitNull() { + testImplicit(null); + } + + @Test + public void explicit() { + testExplicit(new Integer(1)); + } + + @Test + public void explicitNull() { + testExplicit(null); } @Override diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Apr 22 19:50:30 2015 +0200 @@ -736,16 +736,16 @@ public void emitNullCheck(Value address, LIRFrameState state) { if (address.getLIRKind().getPlatformKind() == Kind.Int) { CompressEncoding encoding = config.getOopEncoding(); + Value uncompressed; if (encoding.shift <= 3) { - AMD64AddressValue uncompressionAddress = emitAddress(getProviders().getRegisters().getHeapBaseRegister().asValue(), 0, load(address), 1 << encoding.shift); - append(new AMD64HotSpotMove.CompressedNullCheckOp(uncompressionAddress, state)); + uncompressed = emitAddress(getProviders().getRegisters().getHeapBaseRegister().asValue(), 0, load(address), 1 << encoding.shift); } else { - Value uncompress = emitUncompress(address, encoding, false); - append(new AMD64Move.NullCheckOp(load(uncompress), state)); + uncompressed = emitUncompress(address, encoding, false); } + append(new AMD64Move.NullCheckOp(asAddressValue(uncompressed), state)); } else { assert address.getKind() == Kind.Object || address.getKind() == Kind.Long : address + " - " + address.getKind() + " not a pointer!"; - append(new AMD64Move.NullCheckOp(load(address), state)); + append(new AMD64Move.NullCheckOp(asAddressValue(address), state)); } } diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Wed Apr 22 19:50:30 2015 +0200 @@ -25,7 +25,6 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; @@ -241,27 +240,4 @@ masm.addq(register, scratch); } } - - public static final class CompressedNullCheckOp extends AMD64LIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CompressedNullCheckOp.class); - - @Use({COMPOSITE}) protected AMD64AddressValue address; - @State protected LIRFrameState state; - - public CompressedNullCheckOp(AMD64AddressValue address, LIRFrameState state) { - super(TYPE); - this.address = address; - this.state = state; - } - - @Override - public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - crb.recordImplicitException(masm.position(), state); - masm.testl(AMD64.rax, address.toAddress()); - } - - public LIRFrameState getState() { - return state; - } - } } diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Wed Apr 22 19:50:30 2015 +0200 @@ -112,8 +112,8 @@ @Snippet public static void g1PreWriteBarrier(Object object, Object expectedObject, Object location, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace) { - if (nullCheck && object == null) { - DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException); + if (nullCheck) { + NullCheckNode.nullCheck(object); } Word thread = registerAsWord(threadRegister); Object fixedObject = FixedValueAnchorNode.getObject(object); diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed Apr 22 19:50:30 2015 +0200 @@ -182,23 +182,23 @@ public static final class NullCheckOp extends AMD64LIRInstruction implements NullCheck { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(NullCheckOp.class); - @Use({REG}) protected AllocatableValue input; + @Use({COMPOSITE}) protected AMD64AddressValue address; @State protected LIRFrameState state; - public NullCheckOp(Variable input, LIRFrameState state) { + public NullCheckOp(AMD64AddressValue address, LIRFrameState state) { super(TYPE); - this.input = input; + this.address = address; this.state = state; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { crb.recordImplicitException(masm.position(), state); - masm.nullCheck(asRegister(input)); + masm.nullCheck(address.toAddress()); } public Value getCheckedValue() { - return input; + return address.base; } public LIRFrameState getState() { diff -r c5365790bf49 -r de2fb3e4df49 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Wed Apr 22 19:50:17 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Wed Apr 22 19:50:30 2015 +0200 @@ -52,4 +52,7 @@ public boolean canDeoptimize() { return true; } + + @NodeIntrinsic + public static native void nullCheck(Object object); }