# HG changeset patch # User Christian Haeubl # Date 1371194950 -7200 # Node ID 91b9c3f0100a39a9142f2107bb3f469b1ed6eba4 # Parent 5260095a574b5150f43fab462b0a55f184c4fa12# Parent 055430b5abb9b1a16acff38b60015423958541c8 Merge. diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Jun 14 09:29:10 2013 +0200 @@ -358,7 +358,7 @@ test(method, expect, Collections. emptySet(), receiver, args); } - protected void test(Method method, Result expect, Set shouldNotDeopt, Object receiver, Object... args) { + protected Result executeActualCheckDeopt(Method method, Set shouldNotDeopt, Object receiver, Object... args) { Map deoptCounts = new EnumMap<>(DeoptimizationReason.class); ProfilingInfo profile = runtime.lookupJavaMethod(method).getProfilingInfo(); for (DeoptimizationReason reason : shouldNotDeopt) { @@ -368,7 +368,10 @@ for (DeoptimizationReason reason : shouldNotDeopt) { Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason)); } + return actual; + } + protected void assertEquals(Result expect, Result actual) { if (expect.exception != null) { Assert.assertTrue("expected " + expect.exception, actual.exception != null); Assert.assertEquals(expect.exception.getClass(), actual.exception.getClass()); @@ -382,6 +385,11 @@ } } + protected void test(Method method, Result expect, Set shouldNotDeopt, Object receiver, Object... args) { + Result actual = executeActualCheckDeopt(method, shouldNotDeopt, receiver, args); + assertEquals(expect, actual); + } + private Map cache = new HashMap<>(); /** diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Jun 14 09:29:10 2013 +0200 @@ -37,37 +37,37 @@ CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); if (FullUnroll.getValue()) { - addPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue())); + appendPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue())); } if (OptTailDuplication.getValue()) { - addPhase(new TailDuplicationPhase()); + appendPhase(new TailDuplicationPhase()); } if (PartialEscapeAnalysis.getValue()) { - addPhase(new PartialEscapePhase(true, canonicalizer)); + appendPhase(new PartialEscapePhase(true, canonicalizer)); } if (OptConvertDeoptsToGuards.getValue()) { - addPhase(new ConvertDeoptimizeToGuardPhase()); + appendPhase(new ConvertDeoptimizeToGuardPhase()); } - addPhase(new LockEliminationPhase()); + appendPhase(new LockEliminationPhase()); if (OptLoopTransform.getValue()) { - addPhase(new LoopTransformHighPhase()); - addPhase(new LoopTransformLowPhase()); + appendPhase(new LoopTransformHighPhase()); + appendPhase(new LoopTransformLowPhase()); } - addPhase(new RemoveValueProxyPhase()); + appendPhase(new RemoveValueProxyPhase()); if (CullFrameStates.getValue()) { - addPhase(new CullFrameStatesPhase()); + appendPhase(new CullFrameStatesPhase()); } if (OptCanonicalizer.getValue()) { - addPhase(canonicalizer); + appendPhase(canonicalizer); } - addPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS)); + appendPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS)); } } diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Fri Jun 14 09:29:10 2013 +0200 @@ -30,12 +30,12 @@ public class LowTier extends PhaseSuite { public LowTier() { - addPhase(new LoweringPhase(LoweringType.AFTER_GUARDS)); + appendPhase(new LoweringPhase(LoweringType.AFTER_GUARDS)); - addPhase(new FrameStateAssignmentPhase()); + appendPhase(new FrameStateAssignmentPhase()); - addPhase(new ExpandLogicPhase()); + appendPhase(new ExpandLogicPhase()); - addPhase(new DeadCodeEliminationPhase()); + appendPhase(new DeadCodeEliminationPhase()); } } diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Jun 14 09:29:10 2013 +0200 @@ -35,50 +35,50 @@ CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); if (OptPushThroughPi.getValue()) { - addPhase(new PushThroughPiPhase()); + appendPhase(new PushThroughPiPhase()); if (OptCanonicalizer.getValue()) { - addPhase(canonicalizer); + appendPhase(canonicalizer); } } if (OptFloatingReads.getValue()) { IncrementalCanonicalizerPhase incCanonicalizer = new IncrementalCanonicalizerPhase<>(); - incCanonicalizer.addPhase(new FloatingReadPhase()); - addPhase(incCanonicalizer); + incCanonicalizer.appendPhase(new FloatingReadPhase()); + appendPhase(incCanonicalizer); if (OptReadElimination.getValue()) { - addPhase(new ReadEliminationPhase()); + appendPhase(new ReadEliminationPhase()); } } - addPhase(new RemoveValueProxyPhase()); + appendPhase(new RemoveValueProxyPhase()); if (OptCanonicalizer.getValue()) { - addPhase(canonicalizer); + appendPhase(canonicalizer); } if (OptEliminatePartiallyRedundantGuards.getValue()) { - addPhase(new EliminatePartiallyRedundantGuardsPhase(false, true)); + appendPhase(new EliminatePartiallyRedundantGuardsPhase(false, true)); } if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - addPhase(new IterativeConditionalEliminationPhase()); + appendPhase(new IterativeConditionalEliminationPhase()); } if (OptEliminatePartiallyRedundantGuards.getValue()) { - addPhase(new EliminatePartiallyRedundantGuardsPhase(true, true)); + appendPhase(new EliminatePartiallyRedundantGuardsPhase(true, true)); } if (OptCanonicalizer.getValue()) { - addPhase(canonicalizer); + appendPhase(canonicalizer); } - addPhase(new LoopSafepointEliminationPhase()); + appendPhase(new LoopSafepointEliminationPhase()); - addPhase(new SafepointInsertionPhase()); + appendPhase(new SafepointInsertionPhase()); - addPhase(new GuardLoweringPhase()); + appendPhase(new GuardLoweringPhase()); if (OptCanonicalizer.getValue()) { - addPhase(canonicalizer); + appendPhase(canonicalizer); } } } diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Jun 14 09:29:10 2013 +0200 @@ -329,6 +329,11 @@ public int klassOffset; /** + * The offset of the injected array klass field in a {@link Class}. + */ + public int arrayKlassOffset; + + /** * The offset of the injected graal_mirror field in a {@link Class}. */ public int graalMirrorInClassOffset; diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Jun 14 09:29:10 2013 +0200 @@ -768,6 +768,10 @@ if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { newObjectSnippets.lower((NewArrayNode) n); } + } else if (n instanceof DynamicNewArrayNode) { + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + newObjectSnippets.lower((DynamicNewArrayNode) n); + } } else if (n instanceof MonitorEnterNode) { if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { monitorSnippets.lower((MonitorEnterNode) n, tool); @@ -1070,15 +1074,15 @@ if (AOTCompilation.getValue()) { // lowering introduces class constants, therefore it must be after lowering - ret.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase()); + ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase()); if (VerifyPhases.getValue()) { - ret.getHighTier().addPhase(new AheadOfTimeVerifcationPhase()); + ret.getHighTier().appendPhase(new AheadOfTimeVerifcationPhase()); } } - ret.getMidTier().addPhase(new WriteBarrierAdditionPhase()); + ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase()); if (VerifyPhases.getValue()) { - ret.getMidTier().addPhase(new WriteBarrierVerificationPhase()); + ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase()); } return ret; diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Jun 14 09:29:10 2013 +0200 @@ -521,6 +521,11 @@ } @Fold + public static int arrayKlassOffset() { + return config().arrayKlassOffset; + } + + @Fold public static int classMirrorOffset() { return config().classMirrorOffset; } diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Jun 14 09:29:10 2013 +0200 @@ -121,6 +121,33 @@ return unsafeArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic(), anchorNode); } + @Snippet + public static Object allocateArrayDynamic(Class elementType, int length, @ConstantParameter boolean fillContents) { + Word hub = loadWordFromObject(elementType, arrayKlassOffset()); + if (hub.equal(Word.zero())) { + // the array class is not yet loaded + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.Unresolved); + } + + int layoutHelper = readLayoutHelper(hub); + //@formatter:off + // For arrays, layout helper is a negative number, containing four + // distinct bytes, as follows: + // MSB:[tag, hsz, ebt, log2(esz)]:LSB + // where: + // tag is 0x80 if the elements are oops, 0xC0 if non-oops + // hsz is array header size in bytes (i.e., offset of first element) + // ebt is the BasicType of the elements + // esz is the element size in bytes + //@formatter:on + + int headerSize = (layoutHelper >> 16) & 0xFF; + int log2ElementSize = layoutHelper & 0xFF; + Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); + + return allocateArray(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents); + } + /** * Computes the size of the memory chunk allocated for an array. This size accounts for the * array header size, boy size and any padding after the last element to satisfy object @@ -201,6 +228,7 @@ private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance"); private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray"); + private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic"); private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray"); public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { @@ -253,6 +281,16 @@ template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args); } + public void lower(DynamicNewArrayNode newArrayNode) { + Arguments args = new Arguments(allocateArrayDynamic); + args.add("elementType", newArrayNode.getElementType()); + args.add("length", newArrayNode.length()); + args.addConst("fillContents", newArrayNode.fillContents()); + + SnippetTemplate template = template(args); + template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args); + } + public void lower(NewMultiArrayNode newmultiarrayNode) { StructuredGraph graph = newmultiarrayNode.graph(); int rank = newmultiarrayNode.dimensionCount(); diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Fri Jun 14 09:29:10 2013 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, 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.nodes.java; + +import java.lang.reflect.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * The {@code DynamicNewArrayNode} is used for allocation of arrays when the type is not a + * compile-time constant. + */ +public class DynamicNewArrayNode extends FixedWithNextNode implements Canonicalizable, Lowerable, ArrayLengthProvider { + + @Input private ValueNode elementType; + @Input private ValueNode length; + private final boolean fillContents; + + public DynamicNewArrayNode(ValueNode elementType, ValueNode length) { + this(elementType, length, true); + } + + public DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) { + super(StampFactory.objectNonNull()); + this.length = length; + this.elementType = elementType; + this.fillContents = fillContents; + } + + public ValueNode getElementType() { + return elementType; + } + + @Override + public ValueNode length() { + return length; + } + + public boolean fillContents() { + return fillContents; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (elementType.isConstant()) { + Class elementClass = (Class) elementType.asConstant().asObject(); + if (elementClass != null && !(elementClass.equals(void.class))) { + ResolvedJavaType javaType = tool.runtime().lookupJavaType(elementClass); + return graph().add(new NewArrayNode(javaType, length, fillContents)); + } + } + return this; + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + tool.getRuntime().lower(this, tool); + } + + @NodeIntrinsic + public static Object newArray(Class componentType, int length) { + return Array.newInstance(componentType, length); + } +} diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Jun 14 09:29:10 2013 +0200 @@ -156,7 +156,7 @@ int mark = graph.getMark(); IncrementalCanonicalizerPhase canonicalizer = new IncrementalCanonicalizerPhase<>(); - canonicalizer.addPhase(round); + canonicalizer.appendPhase(round); canonicalizer.apply(graph, context); if (!round.deferred && !containsLowerable(graph.getNewNodes(mark))) { diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java Fri Jun 14 09:29:10 2013 +0200 @@ -34,7 +34,17 @@ this.phases = new ArrayList<>(); } - public final void addPhase(BasePhase phase) { + /** + * Add a new phase at the beginning of this suite. + */ + public final void prependPhase(BasePhase phase) { + phases.add(0, phase); + } + + /** + * Add a new phase at the end of this suite. + */ + public final void appendPhase(BasePhase phase) { phases.add(phase); } diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DynamicNewArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DynamicNewArrayTest.java Fri Jun 14 09:29:10 2013 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, 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.replacements.test; + +import java.lang.reflect.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.test.*; + +/** + * Tests the implementation of Array.createInstance. + */ +public class DynamicNewArrayTest extends GraalCompilerTest { + + private class Element { + } + + @Test + public void test1() { + test("test1snippet"); + } + + @Test + public void test2() { + test("test2snippet"); + } + + @Test + public void test3() { + test("dynamic", Long.class, 7); + } + + @Test + public void test4() { + test("dynamic", Boolean.class, -7); + } + + @Test + public void test5() { + test("dynamic", byte.class, 7); + } + + @Test + public void test6() { + test("dynamic", null, 5); + } + + @Test + public void test7() { + Method method = getMethod("dynamic"); + Result actual1 = executeActual(method, null, Element.class, 7); + Result actual2 = executeActualCheckDeopt(method, Collections. singleton(DeoptimizationReason.Unresolved), null, Element.class, 7); + Result expected = executeExpected(method, null, Element.class, 7); + assertEquals(actual1, expected); + assertEquals(actual2, expected); + } + + public static Object test1snippet() { + return Array.newInstance(Integer.class, 7); + } + + public static Object test2snippet() { + return Array.newInstance(char.class, 7); + } + + public static Object dynamic(Class elementType, int length) { + return Array.newInstance(elementType, length); + } +} diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java Fri Jun 14 09:29:10 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, 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.replacements; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; + +/** + * Substitutions for {@link java.lang.reflect.Array} methods. + */ +@ClassSubstitution(java.lang.reflect.Array.class) +public class ArraySubstitutions { + + @MethodSubstitution + public static Object newArray(Class componentType, int length) throws NegativeArraySizeException { + if (componentType == null) { + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.NullCheckException); + } + return DynamicNewArrayNode.newArray(componentType, length); + } +} diff -r 5260095a574b -r 91b9c3f0100a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Jun 14 09:28:07 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Jun 14 09:29:10 2013 +0200 @@ -41,6 +41,7 @@ } if (Intrinsify.getValue()) { + replacements.registerSubstitutions(ArraySubstitutions.class); replacements.registerSubstitutions(MathSubstitutionsX86.class); replacements.registerSubstitutions(DoubleSubstitutions.class); replacements.registerSubstitutions(FloatSubstitutions.class); diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/code/codeCache.cpp --- a/src/share/vm/code/codeCache.cpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/code/codeCache.cpp Fri Jun 14 09:29:10 2013 +0200 @@ -303,6 +303,15 @@ } } +#ifdef GRAAL +void CodeCache::alive_nmethods_do_graal_methods(OopClosure* closure) { + assert_locked_or_safepoint(CodeCache_lock); + FOR_ALL_ALIVE_NMETHODS(nm) { + nm->mark_graal_reference(closure); + } +} +#endif + int CodeCache::alignment_unit() { return (int)_heap->alignment_unit(); } diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/code/codeCache.hpp --- a/src/share/vm/code/codeCache.hpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/code/codeCache.hpp Fri Jun 14 09:29:10 2013 +0200 @@ -81,7 +81,12 @@ static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs static void nmethods_do(void f(nmethod* nm)); // iterates over all nmethods static void alive_nmethods_do(void f(nmethod* nm)); // iterates over all alive nmethods - +#ifdef GRAAL + //Special method iterating and marking all HotSpotNMethods which are weakly referenced by nmethods. + //This has to be done since the HotSpotNMethods are only referenced from within the nmethods and the GC + //believes they are dead since they are not marked. + static void alive_nmethods_do_graal_methods(OopClosure* closure); +#endif // Lookup static CodeBlob* find_blob(void* start); static nmethod* find_nmethod(void* start); diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/code/nmethod.cpp Fri Jun 14 09:29:10 2013 +0200 @@ -1861,6 +1861,13 @@ #endif } +#ifdef GRAAL +void nmethod::mark_graal_reference(OopClosure* f) { + if (_graal_installed_code != NULL) { + f->do_oop((oop*) &_graal_installed_code); + } +} +#endif // Iterate over metadata calling this function. Used by RedefineClasses void nmethod::metadata_do(void f(Metadata*)) { diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/code/nmethod.hpp Fri Jun 14 09:29:10 2013 +0200 @@ -743,6 +743,10 @@ nm->metadata_do(Metadata::mark_on_stack); } void metadata_do(void f(Metadata*)); + +#ifdef GRAAL + void mark_graal_reference(OopClosure* f); +#endif }; // Locks an nmethod so its code will not get removed and it will not diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Jun 14 09:29:10 2013 +0200 @@ -726,6 +726,7 @@ set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset())); set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset())); set_int("klassOffset", java_lang_Class::klass_offset_in_bytes()); + set_int("arrayKlassOffset", java_lang_Class::array_klass_offset_in_bytes()); set_int("graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes()); set_int("klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset())); set_int("klassSuperKlassOffset", in_bytes(Klass::super_offset())); diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/memory/referenceProcessor.cpp --- a/src/share/vm/memory/referenceProcessor.cpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/memory/referenceProcessor.cpp Fri Jun 14 09:29:10 2013 +0200 @@ -32,6 +32,10 @@ #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "runtime/jniHandles.hpp" +#ifdef GRAAL +#include "code/codeCache.hpp" +#include "code/nmethod.hpp" +#endif ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; @@ -243,6 +247,9 @@ task_executor->set_single_threaded_mode(); } process_phaseJNI(is_alive, keep_alive, complete_gc); +#ifdef GRAAL + process_phaseGraalNMethods(keep_alive, complete_gc); +#endif } } @@ -284,6 +291,14 @@ complete_gc->do_void(); } +#ifdef GRAAL +void ReferenceProcessor::process_phaseGraalNMethods(OopClosure* keep_alive, + VoidClosure* complete_gc) { + CodeCache::alive_nmethods_do_graal_methods(keep_alive); + complete_gc->do_void(); +} + +#endif template bool enqueue_discovered_ref_helper(ReferenceProcessor* ref, diff -r 5260095a574b -r 91b9c3f0100a src/share/vm/memory/referenceProcessor.hpp --- a/src/share/vm/memory/referenceProcessor.hpp Fri Jun 14 09:28:07 2013 +0200 +++ b/src/share/vm/memory/referenceProcessor.hpp Fri Jun 14 09:29:10 2013 +0200 @@ -293,6 +293,10 @@ void process_phaseJNI(BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc); +#ifdef GRAAL + void process_phaseGraalNMethods(OopClosure* keep_alive, + VoidClosure* complete_gc); +#endif // Work methods used by the method process_discovered_reflist // Phase1: keep alive all those referents that are otherwise