# HG changeset patch # User Doug Simon # Date 1337069013 -7200 # Node ID 028c9ce0fc0f97c9e6b5f83b38ad05896ab29c47 # Parent c976c744c8023e20306dfb52f2c3092384cd1923 added support for -G:+CheckcastCounters in checkcast snippets diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Mon May 14 22:07:14 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Tue May 15 10:03:33 2012 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.cri.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.*; import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; @@ -1013,27 +1014,13 @@ Map duplicates = graph.addDuplicates(nodes, replacements); Debug.dump(graph, "After inlining snippet %s", snippetCopy.method()); -// if (tool != null) { -// boolean innerLowering = false; -// for (Node node : duplicates.values()) { -// if (node instanceof Lowerable) { -// innerLowering = true; -// ((Lowerable) node).lower(tool); -// -// } -// } -// if (innerLowering) { -// Debug.dump(graph, "After inner lowering"); -// } -// } - // Remove all frame states from the inlined snippet graph. Snippets must be atomic (i.e. free // of side-effects that prevent deoptimizing to a point before the snippet). for (Node node : graph.getNewNodes(mark)) { if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; FrameState frameState = stateSplit.stateAfter(); - assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node + "\n " + replacee.graph(); + assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node + "\n " + frameState.toString(Verbosity.Debugger); if (frameState != null) { stateSplit.setStateAfter(null); } diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon May 14 22:07:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue May 15 10:03:33 2012 +0200 @@ -289,6 +289,7 @@ CiCompilationStatistics.clear("final"); MethodEntryCounters.printCounters(compiler); HotSpotXirGenerator.printCounters(TTY.out().out()); + CheckCastSnippets.printCounters(TTY.out().out()); } private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) { diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Mon May 14 22:07:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Tue May 15 10:03:33 2012 +0200 @@ -28,8 +28,8 @@ import java.util.*; import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.phases.CanonicalizerPhase.IsImmutablePredicate; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.phases.CanonicalizerPhase.IsImmutablePredicate; import com.oracle.graal.compiler.target.*; import com.oracle.graal.compiler.util.*; import com.oracle.graal.cri.*; @@ -39,6 +39,7 @@ import com.oracle.graal.hotspot.Compiler; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.snippets.*; +import com.oracle.graal.hotspot.snippets.CheckCastSnippets.Counter; import com.oracle.graal.hotspot.target.amd64.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -81,7 +82,11 @@ Snippets.install(this, compiler.getTarget(), new ArrayCopySnippets()); Snippets.install(this, compiler.getTarget(), new CheckCastSnippets()); try { - checkcastSnippet = getRiMethod(CheckCastSnippets.class.getDeclaredMethod("checkcast", Object.class, Object.class, Object[].class, boolean.class)); + if (GraalOptions.CheckcastCounters) { + checkcastSnippet = getRiMethod(CheckCastSnippets.class.getDeclaredMethod("checkcastWithCounters", Object.class, Object.class, Object[].class, boolean.class, Counter.class)); + } else { + checkcastSnippet = getRiMethod(CheckCastSnippets.class.getDeclaredMethod("checkcast", Object.class, Object.class, Object[].class, boolean.class)); + } } catch (NoSuchMethodException e) { throw new GraalInternalError(e); } @@ -432,8 +437,12 @@ final CiConstant hintHubsConst = CiConstant.forObject(hintHubs); hintHubsSet.put(hintHubsConst, hintHubsConst); Debug.log("Lowering checkcast in %s: node=%s, hintsHubs=%s, exact=%b", graph, checkcast, Arrays.toString(hints.types), hints.exact); - - InliningUtil.inlineSnippet(this, checkcast, checkcast, snippetGraph, true, immutabilityPredicate, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact)); + if (GraalOptions.CheckcastCounters) { + Counter noHintsCounter = checkcast.targetClass() == null ? Counter.noHints_unknown : checkcast.targetClass().isInterface() ? Counter.noHints_iface : Counter.noHints_class; + InliningUtil.inlineSnippet(this, checkcast, checkcast, snippetGraph, true, immutabilityPredicate, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact), CiConstant.forObject(noHintsCounter)); + } else { + InliningUtil.inlineSnippet(this, checkcast, checkcast, snippetGraph, true, immutabilityPredicate, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact)); + } new DeadCodeEliminationPhase().apply(graph); } } else { diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Mon May 14 22:07:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Tue May 15 10:03:33 2012 +0200 @@ -1010,7 +1010,7 @@ } private static void printCounter(PrintStream out, CheckcastCounter name, long count, long total) { - double percent = ((double) (count * 100)) / total; + double percent = total == 0D ? 0D : ((double) (count * 100)) / total; out.println(String.format("%16s: %5.2f%%%10d // %s", name, percent, count, name.desc)); } @@ -1036,7 +1036,7 @@ Arrays.sort(counters); out.println(); - out.println("** Checkcast counters **"); + out.println("** XIR checkcast counters **"); for (Count c : counters) { printCounter(out, c.name, c.c, total); } diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Mon May 14 22:07:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Tue May 15 10:03:33 2012 +0200 @@ -21,8 +21,7 @@ * questions. */ package com.oracle.graal.hotspot.snippets; -import com.oracle.graal.cri.*; -import com.oracle.graal.graph.Node.*; +import com.oracle.graal.graph.Node.Fold; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -32,6 +31,7 @@ import com.oracle.max.cri.ci.*; +@SuppressWarnings("unused") public class ArrayCopySnippets implements SnippetsInterface{ @Snippet @@ -346,92 +346,13 @@ DirectObjectStoreNode.store(dest, header, i + destOffset, a); } } - private static class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable { - @Input private ValueNode object; - - public GetObjectAddressNode(ValueNode obj) { - super(StampFactory.forKind(CiKind.Long)); - this.object = obj; - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static long get(Object array) { - throw new UnsupportedOperationException(); - } - - @Override - public void generate(LIRGeneratorTool gen) { - CiValue obj = gen.newVariable(gen.target().wordKind); - gen.emitMove(gen.operand(object), obj); - gen.setResult(this, obj); - } - } - private static class DirectStoreNode extends FixedWithNextNode implements LIRLowerable { - @Input private ValueNode address; - @Input private ValueNode value; - - public DirectStoreNode(ValueNode address, ValueNode value) { - super(StampFactory.illegal()); - this.address = address; - this.value = value; - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(long address, long value) { - throw new UnsupportedOperationException(); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(long address, boolean value) { - throw new UnsupportedOperationException(); - } - - @Override - public void generate(LIRGeneratorTool gen) { - CiValue v = gen.operand(value); - gen.emitStore(new CiAddress(v.kind, gen.operand(address)), v, false); - } - } - - private static class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable { - @Input private ValueNode object; - @Input private ValueNode value; - @Input private ValueNode offset; - private final int displacement; - - public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) { - super(StampFactory.illegal()); - this.object = object; - this.value = value; - this.offset = offset; - this.displacement = displacement; - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) { - throw new UnsupportedOperationException(); - } - - @Override - public void lower(CiLoweringTool tool) { - StructuredGraph graph = (StructuredGraph) this.graph(); - IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, false); - WriteNode write = graph.add(new WriteNode(object, value, location)); - graph.replaceFixedWithFixed(this, write); - } - } - @Fold private static int wordSize() { return CompilerImpl.getInstance().getTarget().wordSize; } @Fold - private static int arrayHeaderSizeFor(CiKind elementKind) { + static int arrayHeaderSizeFor(CiKind elementKind) { return CompilerImpl.getInstance().getConfig().getArrayOffset(elementKind); } diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Mon May 14 22:07:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Tue May 15 10:03:33 2012 +0200 @@ -21,18 +21,40 @@ * questions. */ package com.oracle.graal.hotspot.snippets; +import static com.oracle.graal.hotspot.snippets.CheckCastSnippets.Counter.*; + +import java.io.*; +import java.util.*; + +import sun.misc.*; + +import com.oracle.graal.compiler.*; +import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Fold; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.snippets.*; import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; - +/** + * Snippets used for lowering {@link CheckCastNode}s. + */ public class CheckCastSnippets implements SnippetsInterface { + /** + * Checks that a given object is null or is a subtype of a given type. + * + * @param hub the hub of the type being checked against + * @param object the object whose type is being checked against {@code hub} + * @param hintHubs the hubs of objects that have been profiled during previous executions + * @param hintsAreExact specifies if {@code hintHubs} contains all subtypes of {@code hub} + * @return {@code object} if the type check succeeds + * @throws ClassCastException if the type check fails + */ @Snippet public static Object checkcast(Object hub, Object object, Object[] hintHubs, boolean hintsAreExact) { if (object == null) { @@ -52,8 +74,138 @@ return object; } + /** + * Counters for the various code paths through a type check. + */ + public enum Counter { + hintsHit("hit a hint type"), + hintsMissed("missed the hint types"), + exact("tested type is (statically) final"), + noHints_class("profile information is not used (test type is a class)"), + noHints_iface("profile information is not used (test type is an interface)"), + noHints_unknown("test type is not a compile-time constant"), + isNull("object tested is null"), + exception("type test failed with a ClassCastException"); + + final String description; + final int index; + long count; + + private Counter(String desc) { + this.description = desc; + this.index = ordinal(); + } + + @Fold + static int countOffset() { + try { + return (int) Unsafe.getUnsafe().objectFieldOffset(Counter.class.getDeclaredField("count")); + } catch (Exception e) { + throw new GraalInternalError(e); + } + } + + /** + * Increments this counter if counters are enabled. The body of this method has been carefully crafted + * such that it contains no safepoints and no calls, neither of which are permissible in a snippet. + * Also, increments are not guaranteed to be atomic but that's acceptable for a counter like this. + */ + void inc() { + if (ENABLED) { + DirectObjectStoreNode.store(this, countOffset(), 0, count + 1); + } + } + + static final Counter[] VALUES = values(); + static final boolean ENABLED = GraalOptions.CheckcastCounters; + } + + /** + * @see #checkcast(Object, Object, Object[], boolean) + */ + @Snippet + public static Object checkcastWithCounters(Object hub, Object object, Object[] hintHubs, boolean hintsAreExact, Counter noHintsCounter) { + if (object == null) { + isNull.inc(); + return object; + } + Object objectHub = UnsafeLoadNode.load(object, 0, hubOffset(), CiKind.Object); + if (hintHubs.length == 0) { + noHintsCounter.inc(); + if (!TypeCheckSlowPath.check(objectHub, hub)) { + exception.inc(); + DeoptimizeNode.deopt(RiDeoptAction.InvalidateReprofile, RiDeoptReason.ClassCastException); + } + } else { + // if we get an exact match: succeed immediately + for (int i = 0; i < hintHubs.length; i++) { + Object hintHub = hintHubs[i]; + if (hintHub == objectHub) { + if (hintsAreExact) { + exact.inc(); + } else { + hintsHit.inc(); + } + return object; + } + } + if (!hintsAreExact) { + if (!TypeCheckSlowPath.check(objectHub, hub)) { + exception.inc(); + DeoptimizeNode.deopt(RiDeoptAction.InvalidateReprofile, RiDeoptReason.ClassCastException); + } else { + hintsMissed.inc(); + } + } else { + exception.inc(); + DeoptimizeNode.deopt(RiDeoptAction.InvalidateReprofile, RiDeoptReason.ClassCastException); + } + } + return object; + } + @Fold private static int hubOffset() { return CompilerImpl.getInstance().getConfig().hubOffset; } + + @Fold + private static boolean isInterface(RiResolvedType type) { + return type.isInterface(); + } + + public static void printCounter(PrintStream out, Counter c, long total) { + double percent = total == 0D ? 0D : ((double) (c.count * 100)) / total; + out.println(String.format("%16s: %5.2f%%%10d // %s", c.name(), percent, c.count, c.description)); + } + + public static void printCounters(PrintStream out) { + if (!Counter.ENABLED) { + return; + } + Counter[] counters = Counter.values(); + Arrays.sort(counters, new Comparator() { + @Override + public int compare(Counter o1, Counter o2) { + if (o1.count > o2.count) { + return -1; + } else if (o2.count > o1.count) { + return 1; + } + return 0; + } + + }); + + long total = 0; + for (Counter c : counters) { + total += c.count; + } + + out.println(); + out.println("** Checkcast counters **"); + for (Counter c : counters) { + printCounter(out, c, total); + } + } } diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java Tue May 15 10:03:33 2012 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, 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.snippets; + +import com.oracle.graal.cri.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * A special purpose store node that differs from {@link UnsafeStoreNode} in that + * it is not a {@link StateSplit} and does not include a write barrier. + */ +class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable { + @Input private ValueNode object; + @Input private ValueNode value; + @Input private ValueNode offset; + private final int displacement; + + public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) { + super(StampFactory.illegal()); + this.object = object; + this.value = value; + this.offset = offset; + this.displacement = displacement; + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, long value) { + throw new UnsupportedOperationException(); + } + + @Override + public void lower(CiLoweringTool tool) { + StructuredGraph graph = (StructuredGraph) this.graph(); + IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, false); + WriteNode write = graph.add(new WriteNode(object, value, location)); + graph.replaceFixedWithFixed(this, write); + } +} diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectStoreNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectStoreNode.java Tue May 15 10:03:33 2012 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, 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.snippets; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ci.*; + +/** + * A special purpose store node that differs from {@link UnsafeStoreNode} in that + * it is not a {@link StateSplit} and takes a computed address instead of an object. + */ +class DirectStoreNode extends FixedWithNextNode implements LIRLowerable { + @Input private ValueNode address; + @Input private ValueNode value; + + public DirectStoreNode(ValueNode address, ValueNode value) { + super(StampFactory.illegal()); + this.address = address; + this.value = value; + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static void store(long address, long value) { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static void store(long address, boolean value) { + throw new UnsupportedOperationException(); + } + + @Override + public void generate(LIRGeneratorTool gen) { + CiValue v = gen.operand(value); + gen.emitStore(new CiAddress(v.kind, gen.operand(address)), v, false); + } +} diff -r c976c744c802 -r 028c9ce0fc0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/GetObjectAddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/GetObjectAddressNode.java Tue May 15 10:03:33 2012 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012, 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.snippets; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ci.*; + +/** + * Intrinsification for getting the address of an object. + * The code path(s) between a call to {@link #get(Object)} and all uses + * of the returned value must be atomic. The only exception to this is + * if the usage is not an attempt to dereference the value. + */ +class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable { + @Input private ValueNode object; + + public GetObjectAddressNode(ValueNode obj) { + super(StampFactory.forKind(CiKind.Long)); + this.object = obj; + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static long get(Object array) { + throw new UnsupportedOperationException(); + } + + @Override + public void generate(LIRGeneratorTool gen) { + CiValue obj = gen.newVariable(gen.target().wordKind); + gen.emitMove(gen.operand(object), obj); + gen.setResult(this, obj); + } +}