diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java index 07fd7c61607e..0f9e1640d97d 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java @@ -27,6 +27,7 @@ import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.gc.BarrierSet; import org.graalvm.compiler.nodes.gc.CardTableBarrierSet; @@ -36,6 +37,7 @@ import org.graalvm.compiler.nodes.spi.GCProvider; import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaType; public class HotSpotGCProvider implements GCProvider { private final BarrierSet barrierSet; @@ -52,7 +54,9 @@ public BarrierSet getBarrierSet() { private BarrierSet createBarrierSet(GraalHotSpotVMConfig config, MetaAccessProvider metaAccess) { boolean useDeferredInitBarriers = config.useDeferredInitBarriers; if (config.useG1GC) { - return new G1BarrierSet(metaAccess) { + ResolvedJavaType referenceType = HotSpotReplacementsUtil.referenceType(metaAccess); + long referentOffset = HotSpotReplacementsUtil.referentOffset(metaAccess); + return new G1BarrierSet(referenceType, referentOffset) { @Override protected boolean writeRequiresPostBarrier(FixedAccessNode initializingWrite, ValueNode writtenValue) { if (!super.writeRequiresPostBarrier(initializingWrite, writtenValue)) { diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java index e3c147506ff1..741b383a9914 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java @@ -203,8 +203,7 @@ public Templates(OptionValues options, Iterable factories, g1PreWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1PreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION, SATB_QUEUE_MARKING_LOCATION, SATB_QUEUE_INDEX_LOCATION, SATB_QUEUE_BUFFER_LOCATION); g1ReferentReadBarrier = snippet(G1WriteBarrierSnippets.class, "g1ReferentReadBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION, SATB_QUEUE_MARKING_LOCATION, - SATB_QUEUE_INDEX_LOCATION, - SATB_QUEUE_BUFFER_LOCATION); + SATB_QUEUE_INDEX_LOCATION, SATB_QUEUE_BUFFER_LOCATION); g1PostWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1PostWriteBarrier", null, receiver, GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION, CARD_QUEUE_INDEX_LOCATION, CARD_QUEUE_BUFFER_LOCATION); g1ArrayRangePreWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION, SATB_QUEUE_MARKING_LOCATION, diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java index 1e6bddb3837b..41966c9dd27d 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java @@ -25,8 +25,6 @@ */ package org.graalvm.compiler.nodes.gc; -import java.lang.ref.Reference; - import org.graalvm.compiler.core.common.type.AbstractObjectStamp; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.nodes.NodeView; @@ -45,27 +43,16 @@ import org.graalvm.compiler.nodes.type.StampTool; import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaType; public class G1BarrierSet implements BarrierSet { - private final long referentFieldOffset; private final ResolvedJavaType referenceType; + private final long referentFieldOffset; - public G1BarrierSet(MetaAccessProvider metaAccess) { - this.referenceType = metaAccess.lookupJavaType(Reference.class); - int offset = -1; - for (ResolvedJavaField field : referenceType.getInstanceFields(true)) { - if (field.getName().equals("referent")) { - offset = field.getOffset(); - } - } - if (offset == 1) { - throw new GraalError("Can't find Reference.referent field"); - } - this.referentFieldOffset = offset; + public G1BarrierSet(ResolvedJavaType referenceType, long referentFieldOffset) { + this.referenceType = referenceType; + this.referentFieldOffset = referentFieldOffset; } @Override diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java index 073b96f5ea7e..76260ab951d5 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java @@ -289,7 +289,7 @@ public void registerUsedElements() { } else if (n instanceof ConstantNode) { ConstantNode cn = (ConstantNode) n; - if (cn.hasUsages() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) { + if (cn.hasUsages() && cn.isJavaConstant() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) { assert StampTool.isExactType(cn); AnalysisType type = (AnalysisType) StampTool.typeOrNull(cn); type.registerAsInHeap(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/DuplicatedInNativeCode.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/DuplicatedInNativeCode.java new file mode 100644 index 000000000000..c77ad21c1e3c --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/DuplicatedInNativeCode.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, 2019, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.svm.core.annotate; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Documents that a value or logic is duplicated in native code so it must not be changed or moved + * without adapting native code as well. + */ +@Retention(RetentionPolicy.SOURCE) +@Target(value = {ElementType.METHOD, ElementType.TYPE, ElementType.FIELD}) +public @interface DuplicatedInNativeCode { +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/CodeReferenceMapDecoder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/CodeReferenceMapDecoder.java index f510fcc2ceef..438e18a9459c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/CodeReferenceMapDecoder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/CodeReferenceMapDecoder.java @@ -34,11 +34,13 @@ import com.oracle.svm.core.FrameAccess; import com.oracle.svm.core.annotate.AlwaysInline; +import com.oracle.svm.core.annotate.DuplicatedInNativeCode; import com.oracle.svm.core.c.NonmovableArray; import com.oracle.svm.core.code.CodeInfoQueryResult; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.util.NonmovableByteArrayReader; +@DuplicatedInNativeCode public class CodeReferenceMapDecoder { /** diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java index a09c2e366eba..e71829ce138a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java @@ -31,6 +31,7 @@ import org.graalvm.nativeimage.hosted.Feature; import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.annotate.DuplicatedInNativeCode; import com.oracle.svm.core.util.VMError; /** @@ -40,9 +41,9 @@ public class GCCause { @Platforms(Platform.HOSTED_ONLY.class) private static final ArrayList HostedGCCauseList = new ArrayList<>(); - public static final GCCause JavaLangSystemGC = new GCCause("java.lang.System.gc()", 0); - public static final GCCause UnitTest = new GCCause("UnitTest", 1); - public static final GCCause TestGCInDeoptimizer = new GCCause("TestGCInDeoptimizer", 2); + @DuplicatedInNativeCode public static final GCCause JavaLangSystemGC = new GCCause("java.lang.System.gc()", 0); + @DuplicatedInNativeCode public static final GCCause UnitTest = new GCCause("UnitTest", 1); + @DuplicatedInNativeCode public static final GCCause TestGCInDeoptimizer = new GCCause("TestGCInDeoptimizer", 2); protected static GCCause[] GCCauses = new GCCause[]{JavaLangSystemGC, UnitTest, TestGCInDeoptimizer}; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/InstanceReferenceMapDecoder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/InstanceReferenceMapDecoder.java index d449a6cead5a..064d9dbacaab 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/InstanceReferenceMapDecoder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/InstanceReferenceMapDecoder.java @@ -27,11 +27,13 @@ import org.graalvm.word.Pointer; import com.oracle.svm.core.annotate.AlwaysInline; +import com.oracle.svm.core.annotate.DuplicatedInNativeCode; import com.oracle.svm.core.c.NonmovableArray; import com.oracle.svm.core.code.CodeInfoQueryResult; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.util.NonmovableByteArrayReader; +@DuplicatedInNativeCode public class InstanceReferenceMapDecoder { @AlwaysInline("de-virtualize calls to ObjectReferenceVisitor") public static boolean walkOffsetsFromPointer(Pointer baseAddress, NonmovableArray referenceMapEncoding, long referenceMapIndex, ObjectReferenceVisitor visitor) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java index d19d0db16fad..35f514bd59b7 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java @@ -110,6 +110,11 @@ public final class DynamicHub implements JavaKind.FormatWithToString, AnnotatedE */ private String name; + /** + * Used to quickly determine in which category a certain hub falls (e.g., instance or array). + */ + private int hubType; + /** * Encoding of the object or array size. Decode using {@link LayoutEncoding}. */ @@ -317,9 +322,10 @@ public void setModule(Object module) { private final LazyFinalReference packageNameReference = new LazyFinalReference<>(this::computePackageName); @Platforms(Platform.HOSTED_ONLY.class) - public DynamicHub(String name, boolean isLocalClass, Object isAnonymousClass, DynamicHub superType, DynamicHub componentHub, String sourceFileName, int modifiers, - ClassLoader classLoader) { + public DynamicHub(String name, HubType hubType, boolean isLocalClass, Object isAnonymousClass, DynamicHub superType, DynamicHub componentHub, String sourceFileName, + int modifiers, ClassLoader classLoader) { this.name = name; + this.hubType = hubType.getValue(); this.isLocalClass = isLocalClass; this.isAnonymousClass = isAnonymousClass; this.superHub = superType; @@ -559,14 +565,12 @@ public String getName() { } public boolean isInstanceClass() { - // Special handling for hybrids, which are arrays from the point of view of LayoutEncoding. - return LayoutEncoding.isInstance(getLayoutEncoding()) || (LayoutEncoding.isArray(getLayoutEncoding()) && name.charAt(0) != '['); + return HubType.isInstance(hubType); } @Substitute public boolean isArray() { - // Cannot use LayoutEncoding.isArray because it returns the wrong result for hybrids. - return name.charAt(0) == '['; + return HubType.isArray(hubType); } @Substitute diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/HubType.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/HubType.java new file mode 100644 index 000000000000..56c482394bda --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/HubType.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019, 2019, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.svm.core.hub; + +import com.oracle.svm.core.annotate.DuplicatedInNativeCode; + +@DuplicatedInNativeCode +public enum HubType { + // instance hubs + Instance(0), + InstanceReference(1), + // other hubs + Other(2), + // array hubs + TypeArray(4), + ObjectArray(5); + + private final int value; + + HubType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public static boolean isInstance(int hubType) { + return hubType <= InstanceReference.getValue(); + } + + public static boolean isArray(int hubType) { + return hubType >= TypeArray.getValue(); + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayoutEncoding.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayoutEncoding.java index b797f12fca5a..da4d22b85162 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayoutEncoding.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayoutEncoding.java @@ -34,6 +34,7 @@ import org.graalvm.word.UnsignedWord; import org.graalvm.word.WordFactory; +import com.oracle.svm.core.annotate.DuplicatedInNativeCode; import com.oracle.svm.core.annotate.Uninterruptible; import com.oracle.svm.core.config.ObjectLayout; import com.oracle.svm.core.snippets.KnownIntrinsics; @@ -55,6 +56,7 @@ * size based on the array length * */ +@DuplicatedInNativeCode public class LayoutEncoding { private static final int NEUTRAL_VALUE = 0; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java index 5df3ac150573..d6a260ca6341 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Safepoint.java @@ -45,6 +45,7 @@ import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.annotate.DuplicatedInNativeCode; import com.oracle.svm.core.annotate.NeverInline; import com.oracle.svm.core.annotate.RestrictHeapAccess; import com.oracle.svm.core.annotate.Uninterruptible; @@ -449,9 +450,9 @@ private static void enterSlowPathTransitionFromNativeToNewStatus(int newStatus) /** Methods for the thread that brings the system to a safepoint. */ public static final class Master { - private static final int NOT_AT_SAFEPOINT = 0; - private static final int SYNCHRONIZING = 1; - private static final int AT_SAFEPOINT = 2; + @DuplicatedInNativeCode private static final int NOT_AT_SAFEPOINT = 0; + @DuplicatedInNativeCode private static final int SYNCHRONIZING = 1; + @DuplicatedInNativeCode private static final int AT_SAFEPOINT = 2; static void initialize() { ImageSingletons.add(Master.class, new Master()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java index 36eec22daee1..74a51fdd2adc 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java @@ -64,6 +64,7 @@ import com.oracle.svm.core.annotate.UnknownPrimitiveField; import com.oracle.svm.core.graal.meta.SubstrateForeignCallLinkage; import com.oracle.svm.core.graal.meta.SubstrateForeignCallsProvider; +import com.oracle.svm.core.hub.HubType; import com.oracle.svm.core.hub.DynamicHub; import com.oracle.svm.core.option.SubstrateOptionsParser; import com.oracle.svm.core.util.HostedStringDeduplication; @@ -270,7 +271,7 @@ private DynamicHub createHub(AnalysisType type) { */ String sourceFileName = stringTable.deduplicate(type.getSourceFileName(), true); - final DynamicHub dynamicHub = new DynamicHub(className, type.isLocal(), isAnonymousClass(javaClass), superHub, componentHub, sourceFileName, modifiers, hubClassLoader); + final DynamicHub dynamicHub = new DynamicHub(className, computeHubType(type), type.isLocal(), isAnonymousClass(javaClass), superHub, componentHub, sourceFileName, modifiers, hubClassLoader); if (JavaVersionUtil.JAVA_SPEC > 8) { ModuleAccess.extractAndSetModule(dynamicHub, javaClass); } @@ -335,6 +336,21 @@ public UnsafeAutomaticSubstitutionProcessor getAutomaticSubstitutionProcessor() return automaticSubstitutions; } + private static HubType computeHubType(AnalysisType type) { + if (type.isArray()) { + if (type.getComponentType().isPrimitive() || type.getComponentType().isWordType()) { + return HubType.TypeArray; + } else { + return HubType.ObjectArray; + } + } else if (type.isInstanceClass()) { + // in the future, we will need to distinguish references as well + return HubType.Instance; + } else { + return HubType.Other; + } + } + @Override public void checkMethod(BigBang bb, AnalysisMethod method, StructuredGraph graph) { if (method.isEntryPoint() && !Modifier.isStatic(graph.method().getModifiers())) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/flow/SVMMethodTypeFlowBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/flow/SVMMethodTypeFlowBuilder.java index 1ce0e1265ec7..10030019f845 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/flow/SVMMethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/flow/SVMMethodTypeFlowBuilder.java @@ -66,7 +66,7 @@ public void registerUsedElements() { for (Node n : graph.getNodes()) { if (n instanceof ConstantNode) { ConstantNode cn = (ConstantNode) n; - if (cn.hasUsages() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) { + if (cn.hasUsages() && cn.isJavaConstant() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) { /* * Constants that are embedded into graphs via constant folding of static fields * have already been replaced. But constants embedded manually by graph builder