# HG changeset patch # User Roland Schatz # Date 1428408423 -7200 # Node ID 7ba8fb19d56dbe6b0da498578b0d91023385c715 # Parent 617943492e0080a6c7e1921387da8e8552d282ab Check that snippets only access locations that are either accessed by the replacee, or are private to the snippet. diff -r 617943492e00 -r 7ba8fb19d56d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Tue Apr 07 13:30:09 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Tue Apr 07 14:07:03 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -67,7 +67,7 @@ public static class Templates extends AbstractTemplates { - private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic"); + private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic", SECONDARY_SUPER_CACHE_LOCATION); public Templates(HotSpotProviders providers, TargetDescription target) { super(providers, providers.getSnippetReflection(), target); diff -r 617943492e00 -r 7ba8fb19d56d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Apr 07 13:30:09 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Apr 07 14:07:03 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -216,9 +216,9 @@ private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile"); private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact"); private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary"); - private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); - private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); - private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom"); + private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary", SECONDARY_SUPER_CACHE_LOCATION); + private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic", SECONDARY_SUPER_CACHE_LOCATION); + private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom", SECONDARY_SUPER_CACHE_LOCATION); public Templates(HotSpotProviders providers, TargetDescription target) { super(providers, providers.getSnippetReflection(), target); diff -r 617943492e00 -r 7ba8fb19d56d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Tue Apr 07 13:30:09 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Tue Apr 07 14:07:03 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -69,7 +69,7 @@ public static class Templates extends AbstractTemplates { - private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException"); + private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException", EXCEPTION_OOP_LOCATION, EXCEPTION_PC_LOCATION); public Templates(HotSpotProviders providers, TargetDescription target) { super(providers, providers.getSnippetReflection(), target); diff -r 617943492e00 -r 7ba8fb19d56d 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 Tue Apr 07 13:30:09 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Apr 07 14:07:03 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -401,11 +401,13 @@ public static class Templates extends AbstractTemplates { - 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 allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic"); - private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray"); + private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", INIT_LOCATION, MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); + private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray", INIT_LOCATION, MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); + private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic", INIT_LOCATION, MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, + TLAB_END_LOCATION); + private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic", INIT_LOCATION, MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, + TLAB_END_LOCATION); + private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", INIT_LOCATION); private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap"); public Templates(HotSpotProviders providers, TargetDescription target) { diff -r 617943492e00 -r 7ba8fb19d56d 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 Tue Apr 07 13:30:09 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Tue Apr 07 14:07:03 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -334,13 +334,13 @@ public static class Templates extends AbstractTemplates { - private final SnippetInfo serialWriteBarrier = snippet(WriteBarrierSnippets.class, "serialWriteBarrier"); + private final SnippetInfo serialWriteBarrier = snippet(WriteBarrierSnippets.class, "serialWriteBarrier", GC_CARD_LOCATION); private final SnippetInfo serialArrayRangeWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayRangeWriteBarrier"); - private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier"); - private final SnippetInfo g1ReferentReadBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier"); - private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier"); - private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier"); - private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier"); + private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); + private final SnippetInfo g1ReferentReadBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); + private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); + private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); + private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); private final CompressEncoding oopEncoding; diff -r 617943492e00 -r 7ba8fb19d56d graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Apr 07 13:30:09 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Apr 07 14:07:03 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -34,6 +34,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; +import java.util.function.*; import java.util.stream.*; import com.oracle.graal.api.code.*; @@ -87,6 +88,7 @@ public abstract static class SnippetInfo { protected final ResolvedJavaMethod method; + protected final LocationIdentity[] privateLocations; /** * Lazily constructed parts of {@link SnippetInfo}. @@ -147,8 +149,9 @@ protected abstract Lazy lazy(); - protected SnippetInfo(ResolvedJavaMethod method) { + protected SnippetInfo(ResolvedJavaMethod method, LocationIdentity[] privateLocations) { this.method = method; + this.privateLocations = privateLocations; instantiationCounter = Debug.metric("SnippetInstantiationCount[%s]", method); instantiationTimer = Debug.timer("SnippetInstantiationTime[%s]", method); assert method.isStatic() : "snippet method must be static: " + method.format("%H.%n"); @@ -193,8 +196,8 @@ protected static class LazySnippetInfo extends SnippetInfo { protected final AtomicReference lazy = new AtomicReference<>(null); - protected LazySnippetInfo(ResolvedJavaMethod method) { - super(method); + protected LazySnippetInfo(ResolvedJavaMethod method, LocationIdentity[] privateLocations) { + super(method, privateLocations); } @Override @@ -209,8 +212,8 @@ protected static class EagerSnippetInfo extends SnippetInfo { protected final Lazy lazy; - protected EagerSnippetInfo(ResolvedJavaMethod method) { - super(method); + protected EagerSnippetInfo(ResolvedJavaMethod method, LocationIdentity[] privateLocations) { + super(method, privateLocations); lazy = new Lazy(method); } @@ -497,7 +500,7 @@ * {@link Snippet} and returns a {@link SnippetInfo} value describing it. There must be * exactly one snippet method in {@code declaringClass}. */ - protected SnippetInfo snippet(Class declaringClass, String methodName) { + protected SnippetInfo snippet(Class declaringClass, String methodName, LocationIdentity... privateLocations) { assert methodName != null; Method method = findMethod(declaringClass, methodName, null); assert method != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + " named " + methodName; @@ -506,9 +509,9 @@ ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(method); providers.getReplacements().registerSnippet(javaMethod); if (LAZY_SNIPPETS) { - return new LazySnippetInfo(javaMethod); + return new LazySnippetInfo(javaMethod, privateLocations); } else { - return new EagerSnippetInfo(javaMethod); + return new EagerSnippetInfo(javaMethod, privateLocations); } } @@ -555,6 +558,8 @@ */ protected SnippetTemplate(final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args) { this.snippetReflection = snippetReflection; + this.info = args.info; + Object[] constantArgs = getConstantArgs(args); StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method, constantArgs); instantiationTimer = Debug.timer("SnippetTemplateInstantiationTime[%#s]", args); @@ -820,6 +825,8 @@ */ private final StructuredGraph snippet; + private final SnippetInfo info; + /** * The named parameters of this template that must be bound to values during instantiation. For * a parameter that is still live after specialization, the value in this map is either a @@ -1097,21 +1104,23 @@ } private void rewireMemoryGraph(ValueNode replacee, Map duplicates) { - // rewire outgoing memory edges - replaceMemoryUsages(replacee, new MemoryOutputMap(replacee, duplicates)); + if (replacee.graph().isAfterFloatingReadPhase()) { + // rewire outgoing memory edges + replaceMemoryUsages(replacee, new MemoryOutputMap(replacee, duplicates)); - ReturnNode ret = (ReturnNode) duplicates.get(returnNode); - MemoryMapNode memoryMap = ret.getMemoryMap(); - ret.setMemoryMap(null); - memoryMap.safeDelete(); + ReturnNode ret = (ReturnNode) duplicates.get(returnNode); + MemoryMapNode memoryMap = ret.getMemoryMap(); + ret.setMemoryMap(null); + memoryMap.safeDelete(); - if (memoryAnchor != null) { - // rewire incoming memory edges - MemoryAnchorNode memoryDuplicate = (MemoryAnchorNode) duplicates.get(memoryAnchor); - replaceMemoryUsages(memoryDuplicate, new MemoryInputMap(replacee)); + if (memoryAnchor != null) { + // rewire incoming memory edges + MemoryAnchorNode memoryDuplicate = (MemoryAnchorNode) duplicates.get(memoryAnchor); + replaceMemoryUsages(memoryDuplicate, new MemoryInputMap(replacee)); - if (memoryDuplicate.hasNoUsages()) { - memoryDuplicate.graph().removeFixed(memoryDuplicate); + if (memoryDuplicate.hasNoUsages()) { + memoryDuplicate.graph().removeFixed(memoryDuplicate); + } } } } @@ -1128,7 +1137,7 @@ } } - private static void replaceMemoryUsages(ValueNode node, MemoryMap map) { + private void replaceMemoryUsages(ValueNode node, MemoryMap map) { for (Node usage : node.usages().snapshot()) { if (usage instanceof MemoryMapNode) { continue; @@ -1141,7 +1150,10 @@ Position pos = iter.nextPosition(); if (pos.getInputType() == InputType.Memory && pos.get(usage) == node) { MemoryNode replacement = map.getLastLocationAccess(location); - if (replacement != null) { + if (replacement == null) { + assert LocationIdentity.any().equals(location) || Arrays.stream(info.privateLocations).anyMatch(Predicate.isEqual(location)) : "Snippet " + info.method.format("%h.%n") + + " contains access to the non-private location " + location + ", but replacee doesn't access this location."; + } else { pos.set(usage, replacement.asNode()); } }