diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java index 50e072eb1b87..cb16fb4f2014 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java @@ -45,7 +45,6 @@ import com.oracle.graal.pointsto.api.HostVM; import com.oracle.graal.pointsto.api.PointstoOptions; import com.oracle.graal.pointsto.constraints.UnsupportedFeatures; -import com.oracle.graal.pointsto.flow.AllSynchronizedTypeFlow; import com.oracle.graal.pointsto.flow.AnyPrimitiveSourceTypeFlow; import com.oracle.graal.pointsto.flow.FieldTypeFlow; import com.oracle.graal.pointsto.flow.FormalParamTypeFlow; @@ -104,7 +103,6 @@ public abstract class PointsToAnalysis extends AbstractAnalysisEngine { */ private final boolean trackPrimitiveValues; private AnyPrimitiveSourceTypeFlow anyPrimitiveSourceTypeFlow; - private TypeFlow allSynchronizedTypeFlow; protected final boolean trackTypeFlowInputs; protected final boolean reportAnalysisStatistics; @@ -132,7 +130,6 @@ public PointsToAnalysis(OptionValues options, AnalysisUniverse universe, HostVM * instantiated types yet, so the state is empty at first. */ objectType.getTypeFlow(this, true); - allSynchronizedTypeFlow = new AllSynchronizedTypeFlow(); trackTypeFlowInputs = PointstoOptions.TrackInputFlows.getValue(options); reportAnalysisStatistics = PointstoOptions.PrintPointsToStatistics.getValue(options); @@ -258,7 +255,6 @@ public boolean trackConcreteAnalysisObjects(@SuppressWarnings("unused") Analysis @Override public void cleanupAfterAnalysis() { super.cleanupAfterAnalysis(); - allSynchronizedTypeFlow = null; anyPrimitiveSourceTypeFlow = null; unsafeLoads = null; unsafeStores = null; @@ -287,25 +283,13 @@ public Iterable getAllInstantiatedTypes() { return getAllInstantiatedTypeFlow().getState().types(this); } - public TypeFlow getAllSynchronizedTypeFlow() { - return allSynchronizedTypeFlow; - } - public AnyPrimitiveSourceTypeFlow getAnyPrimitiveSourceTypeFlow() { return anyPrimitiveSourceTypeFlow; } @Override public Iterable getAllSynchronizedTypes() { - /* - * If all-synchrnonized type flow, i.e., the type flow that keeps track of the types of all - * monitor objects, is saturated then we need to assume that any type can be used for - * monitors. - */ - if (allSynchronizedTypeFlow.isSaturated()) { - return getAllInstantiatedTypes(); - } - return allSynchronizedTypeFlow.getState().types(this); + return getAllInstantiatedTypes(); } @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 ee8097982b71..6892a5f9b26d 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 @@ -116,7 +116,6 @@ import jdk.graal.compiler.nodes.java.LoadFieldNode; import jdk.graal.compiler.nodes.java.LoadIndexedNode; import jdk.graal.compiler.nodes.java.MethodCallTargetNode; -import jdk.graal.compiler.nodes.java.MonitorEnterNode; import jdk.graal.compiler.nodes.java.NewArrayNode; import jdk.graal.compiler.nodes.java.NewArrayWithExceptionNode; import jdk.graal.compiler.nodes.java.NewInstanceNode; @@ -1122,18 +1121,6 @@ protected void node(FixedNode n) { }); cloneBuilder.addObserverDependency(inputBuilder); state.add(node.asFixedNode(), cloneBuilder); - } else if (n instanceof MonitorEnterNode) { - MonitorEnterNode node = (MonitorEnterNode) n; - TypeFlowBuilder objectBuilder = state.lookup(node.object()); - - TypeFlowBuilder monitorEntryBuilder = TypeFlowBuilder.create(bb, node, MonitorEnterTypeFlow.class, () -> { - MonitorEnterTypeFlow monitorEntryFlow = new MonitorEnterTypeFlow(AbstractAnalysisEngine.sourcePosition(node), bb); - flowsGraph.addMiscEntryFlow(monitorEntryFlow); - return monitorEntryFlow; - }); - monitorEntryBuilder.addUseDependency(objectBuilder); - /* Monitor enters must not be removed. */ - typeFlowGraphBuilder.registerSinkBuilder(monitorEntryBuilder); } else if (n instanceof MacroInvokable node) { /* * Macro nodes can either be constant folded during compilation, or lowered back to diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MonitorEnterTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MonitorEnterTypeFlow.java deleted file mode 100644 index 411fbb99d047..000000000000 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MonitorEnterTypeFlow.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, 2017, 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.graal.pointsto.flow; - -import com.oracle.graal.pointsto.PointsToAnalysis; - -import jdk.vm.ci.code.BytecodePosition; - -public class MonitorEnterTypeFlow extends TypeFlow { - - @SuppressWarnings("this-escape") - public MonitorEnterTypeFlow(BytecodePosition position, PointsToAnalysis bb) { - super(position, null); - this.addUse(bb, bb.getAllSynchronizedTypeFlow()); - } - - public BytecodePosition getLocation() { - return source; - } - - @Override - public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph methodFlows) { - return this; - } - - @Override - public String toString() { - return "MonitorEnterFlow<" + getState() + ">"; - } - -} diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java index 667ee6257ec9..13fc569cdea7 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java @@ -61,7 +61,6 @@ import com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadInstanceFieldTypeFlow; import com.oracle.graal.pointsto.flow.LoadFieldTypeFlow.LoadStaticFieldTypeFlow; import com.oracle.graal.pointsto.flow.MergeTypeFlow; -import com.oracle.graal.pointsto.flow.MonitorEnterTypeFlow; import com.oracle.graal.pointsto.flow.NewInstanceTypeFlow; import com.oracle.graal.pointsto.flow.NullCheckTypeFlow; import com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.LoadIndexedTypeFlow; @@ -506,9 +505,6 @@ private static String asString(TypeFlow flow) { return "Source @ " + formatSource(flow); } else if (flow instanceof CloneTypeFlow) { return "Clone @ " + formatSource(flow); - } else if (flow instanceof MonitorEnterTypeFlow) { - MonitorEnterTypeFlow monitor = (MonitorEnterTypeFlow) flow; - return "MonitorEnter @ " + formatMethod(monitor.getSource().getMethod()); } else { return ClassUtil.getUnqualifiedName(flow.getClass()) + "@" + formatSource(flow); } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CompactingOldGeneration.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CompactingOldGeneration.java index f0de34f37a7f..d219f81d010c 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CompactingOldGeneration.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CompactingOldGeneration.java @@ -288,7 +288,7 @@ private void fixupReferencesBeforeCompaction(ChunkReleaser chunkReleaser, Timers Timer oldFixupImageHeapTimer = timers.oldFixupImageHeap.open(); try { - for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { GCImpl.walkImageHeapRoots(info, fixupVisitor); } if (AuxiliaryImageHeap.isPresent()) { diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index fd77d1607339..bd5510d304b7 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -913,7 +913,7 @@ private void blackenDirtyImageHeapRoots() { Timer blackenImageHeapRootsTimer = timers.blackenImageHeapRoots.open(); try { - for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { blackenDirtyImageHeapChunkRoots(info.getFirstWritableAlignedChunk(), info.getFirstWritableUnalignedChunk(), info.getLastWritableUnalignedChunk()); } @@ -964,7 +964,7 @@ private void blackenImageHeapRoots() { Timer blackenImageHeapRootsTimer = timers.blackenImageHeapRoots.open(); try { - for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { blackenImageHeapRoots(info); } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java index cc98db104231..ce83b03251ea 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java @@ -69,6 +69,7 @@ import com.oracle.svm.core.jdk.UninterruptibleUtils.AtomicReference; import com.oracle.svm.core.jfr.JfrTicks; import com.oracle.svm.core.jfr.events.SystemGCEvent; +import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton; import com.oracle.svm.core.locks.VMCondition; import com.oracle.svm.core.locks.VMMutex; import com.oracle.svm.core.log.Log; @@ -105,7 +106,6 @@ public final class HeapImpl extends Heap { private final ObjectHeaderImpl objectHeaderImpl = new ObjectHeaderImpl(); private final GCImpl gcImpl; private final RuntimeCodeInfoGCSupportImpl runtimeCodeInfoGcSupport; - private final ImageHeapInfo firstImageHeapInfo = new ImageHeapInfo(); private final HeapAccounting accounting = new HeapAccounting(); /** Head of the linked list of currently pending (ready to be enqueued) {@link Reference}s. */ @@ -140,9 +140,9 @@ public static HeapImpl getHeapImpl() { return (HeapImpl) heap; } - @Fold - public static ImageHeapInfo getFirstImageHeapInfo() { - return getHeapImpl().firstImageHeapInfo; + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + public static ImageHeapInfo[] getImageHeapInfos() { + return MultiLayeredImageSingleton.getAllLayers(ImageHeapInfo.class); } @Fold @@ -177,7 +177,7 @@ public boolean isInPrimaryImageHeap(Object obj) { @Override @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public boolean isInPrimaryImageHeap(Pointer objPointer) { - for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) { + for (ImageHeapInfo info : getImageHeapInfos()) { if (info.isInImageHeap(objPointer)) { return true; } @@ -284,9 +284,10 @@ void logChunks(Log log) { getChunkProvider().logFreeChunks(log); } + @SuppressWarnings("static-method") void logImageHeapPartitionBoundaries(Log log) { log.string("Native image heap boundaries:").indent(true); - for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { info.print(log); } log.indent(false); @@ -331,8 +332,8 @@ static void logZapValues(Log log) { @Override @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public int getClassCount() { - int count = firstImageHeapInfo.dynamicHubCount; - for (ImageHeapInfo info = firstImageHeapInfo.next; info != null; info = info.next) { + int count = 0; + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { count += info.dynamicHubCount; } return count; @@ -354,7 +355,7 @@ private ArrayList> findAllDynamicHubs() { int dynamicHubCount = getClassCount(); ArrayList> list = new ArrayList<>(dynamicHubCount); - for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { ImageHeapWalker.walkRegions(info, new ClassListBuilderVisitor(list.size() + info.dynamicHubCount, list)); } @@ -467,7 +468,7 @@ public boolean walkImageHeapObjects(ObjectVisitor visitor) { if (visitor == null) { return true; } - for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { if (!ImageHeapWalker.walkImageHeapObjects(info, visitor)) { return false; } @@ -731,7 +732,7 @@ public UnsignedWord getUsedMemoryAfterLastGC() { } private boolean printLocationInfo(Log log, Pointer ptr, boolean allowJavaHeapAccess, boolean allowUnsafeOperations) { - for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { if (info.isInReadOnlyRegularPartition(ptr)) { log.string("points into the image heap (read-only)"); return true; diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java index 20bfd41ac7f2..91e1856014ea 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java @@ -73,7 +73,7 @@ public boolean verify(Occasion occasion) { protected boolean verifyImageHeap() { boolean success = true; - for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { success &= verifyAlignedChunks(null, info.getFirstWritableAlignedChunk()); success &= verifyUnalignedChunks(null, info.getFirstWritableUnalignedChunk(), info.getLastWritableUnalignedChunk()); } @@ -129,7 +129,7 @@ private static boolean verifyRememberedSets() { boolean success = true; RememberedSet rememberedSet = RememberedSet.get(); - for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) { + for (ImageHeapInfo info : HeapImpl.getImageHeapInfos()) { success &= rememberedSet.verify(info.getFirstWritableAlignedChunk()); success &= rememberedSet.verify(info.getFirstWritableUnalignedChunk(), info.getLastWritableUnalignedChunk()); } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java index 62f133c81d2d..8aae5b0ad445 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java @@ -24,6 +24,8 @@ */ package com.oracle.svm.core.genscavenge; +import java.util.EnumSet; + import org.graalvm.word.Pointer; import org.graalvm.word.UnsignedWord; import org.graalvm.word.WordFactory; @@ -35,6 +37,9 @@ import com.oracle.svm.core.heap.UnknownObjectField; import com.oracle.svm.core.heap.UnknownPrimitiveField; import com.oracle.svm.core.hub.LayoutEncoding; +import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags; +import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton; +import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.snippets.KnownIntrinsics; @@ -44,7 +49,7 @@ * Information on the multiple partitions that make up the image heap, which don't necessarily form * a contiguous block of memory (there can be holes in between), and their boundaries. */ -public final class ImageHeapInfo { +public final class ImageHeapInfo implements MultiLayeredImageSingleton, UnsavedSingleton { /** Indicates no chunk with {@link #initialize} chunk offset parameters. */ public static final long NO_CHUNK = -1; @@ -73,14 +78,7 @@ public final class ImageHeapInfo { @UnknownPrimitiveField(availability = AfterHeapLayout.class) public int dynamicHubCount; - public final ImageHeapInfo next; - public ImageHeapInfo() { - this(null); - } - - public ImageHeapInfo(ImageHeapInfo next) { - this.next = next; } @SuppressWarnings("hiding") @@ -205,4 +203,9 @@ public void print(Log log) { log.string("Writable Huge: ").zhex(Word.objectToUntrackedPointer(firstWritableHugeObject)).string(" - ").zhex(getObjectEnd(lastWritableHugeObject)).newline(); log.string("ReadOnly Huge: ").zhex(Word.objectToUntrackedPointer(firstReadOnlyHugeObject)).string(" - ").zhex(getObjectEnd(lastReadOnlyHugeObject)).newline(); } + + @Override + public EnumSet getImageBuilderFlags() { + return LayeredImageSingletonBuilderFlags.ALL_ACCESS; + } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java index bccf67fc10da..fe67125edde0 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java @@ -90,8 +90,8 @@ public void afterRegistration(AfterRegistrationAccess access) { @Override public void duringSetup(DuringSetupAccess access) { - HeapImpl heap = new HeapImpl(); - ImageSingletons.add(Heap.class, heap); + ImageSingletons.add(Heap.class, new HeapImpl()); + ImageSingletons.add(ImageHeapInfo.class, new ImageHeapInfo()); ImageSingletons.add(GCAllocationSupport.class, new GenScavengeAllocationSupport()); if (ImageSingletons.contains(PerfManager.class)) { @@ -125,16 +125,19 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { access.registerAsUsed(Object[].class); } + private static ImageHeapInfo getImageHeapInfo() { + return ImageSingletons.lookup(ImageHeapInfo.class); + } + @Override public void afterAnalysis(AfterAnalysisAccess access) { - ImageHeapLayouter heapLayouter = new ChunkedImageHeapLayouter(HeapImpl.getFirstImageHeapInfo(), Heap.getHeap().getImageHeapOffsetInAddressSpace()); + ImageHeapLayouter heapLayouter = new ChunkedImageHeapLayouter(getImageHeapInfo(), Heap.getHeap().getImageHeapOffsetInAddressSpace()); ImageSingletons.add(ImageHeapLayouter.class, heapLayouter); } @Override public void beforeCompilation(BeforeCompilationAccess access) { - ImageHeapInfo imageHeapInfo = HeapImpl.getFirstImageHeapInfo(); - access.registerAsImmutable(imageHeapInfo); + access.registerAsImmutable(getImageHeapInfo()); } @Override diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/jdk/SubstrateObjectCloneSnippets.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/jdk/SubstrateObjectCloneSnippets.java index b05a41d32c37..99aa7eed79b6 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/jdk/SubstrateObjectCloneSnippets.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/jdk/SubstrateObjectCloneSnippets.java @@ -127,7 +127,7 @@ private static Object doClone(Object original) throws CloneNotSupportedException int firstFieldOffset = ConfigurationValues.getObjectLayout().getFirstFieldOffset(); int curOffset = firstFieldOffset; - NonmovableArray referenceMapEncoding = DynamicHubSupport.getReferenceMapEncoding(); + NonmovableArray referenceMapEncoding = DynamicHubSupport.forLayer(hub.getLayerId()).getReferenceMapEncoding(); int referenceSize = ConfigurationValues.getObjectLayout().getReferenceSize(); int referenceMapIndex = hub.getReferenceMapIndex(); int entryCount = NonmovableByteArrayReader.getS4(referenceMapEncoding, referenceMapIndex); 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 c8a604b3f0ce..7c88c23dbace 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 @@ -363,6 +363,8 @@ public final class DynamicHub implements AnnotatedElement, java.lang.reflect.Typ @UnknownPrimitiveField(availability = AfterHostedUniverse.class)// private int referenceMapIndex; + private final byte layerId; + /** * Back link to the SubstrateType used by the substrate meta access. Only used for the subset of * types for which a SubstrateType exists. @@ -432,7 +434,10 @@ public final class DynamicHub implements AnnotatedElement, java.lang.reflect.Typ @Platforms(Platform.HOSTED_ONLY.class) public DynamicHub(Class hostedJavaClass, String name, int hubType, ReferenceType referenceType, DynamicHub superType, DynamicHub componentHub, String sourceFileName, int modifiers, ClassLoader classLoader, boolean isHidden, boolean isRecord, Class nestHost, boolean assertionStatus, boolean hasDefaultMethods, boolean declaresDefaultMethods, - boolean isSealed, boolean isVMInternal, boolean isLambdaFormHidden, boolean isLinked, String simpleBinaryName, Object declaringClass, String signature, boolean isProxyClass) { + boolean isSealed, boolean isVMInternal, boolean isLambdaFormHidden, boolean isLinked, String simpleBinaryName, Object declaringClass, String signature, boolean isProxyClass, + int layerId) { + VMError.guarantee(layerId == (byte) layerId, "Layer id %d not in expected range", layerId); + this.hostedJavaClass = hostedJavaClass; this.module = hostedJavaClass.getModule(); this.name = name; @@ -446,6 +451,7 @@ public DynamicHub(Class hostedJavaClass, String name, int hubType, ReferenceT this.simpleBinaryName = simpleBinaryName; this.declaringClass = declaringClass; this.signature = signature; + this.layerId = (byte) layerId; this.flags = NumUtil.safeToUShort(makeFlag(IS_PRIMITIVE_FLAG_BIT, hostedJavaClass.isPrimitive()) | makeFlag(IS_INTERFACE_FLAG_BIT, hostedJavaClass.isInterface()) | @@ -737,6 +743,16 @@ public int getReferenceMapIndex() { return referenceMapIndex; } + /** + * The identifier of the {@linkplain com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport + * layer} that introduces this type which is an index into the array returned by + * {@link com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton#getAllLayers}. + */ + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + public int getLayerId() { + return layerId; + } + public boolean isInstantiated() { return isFlagSet(additionalFlags, IS_INSTANTIATED_BIT); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubSupport.java index 2ea055c6f21f..a9d8b038458d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubSupport.java @@ -24,10 +24,13 @@ */ package com.oracle.svm.core.hub; +import java.util.EnumSet; + import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; +import com.oracle.svm.core.AlwaysInline; import com.oracle.svm.core.BuildPhaseProvider.AfterHostedUniverse; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.NonmovableArray; @@ -35,17 +38,32 @@ import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton; import com.oracle.svm.core.heap.UnknownObjectField; import com.oracle.svm.core.heap.UnknownPrimitiveField; +import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport; +import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags; +import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton; +import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton; @AutomaticallyRegisteredImageSingleton -public final class DynamicHubSupport { +public final class DynamicHubSupport implements MultiLayeredImageSingleton, UnsavedSingleton { @UnknownPrimitiveField(availability = AfterHostedUniverse.class) private int maxTypeId; @UnknownObjectField(availability = AfterHostedUniverse.class) private byte[] referenceMapEncoding; + @Platforms(Platform.HOSTED_ONLY.class) public static DynamicHubSupport singleton() { return ImageSingletons.lookup(DynamicHubSupport.class); } + @AlwaysInline("Performance") + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + public static DynamicHubSupport forLayer(int layerIndex) { + if (!ImageLayerBuildingSupport.buildingImageLayer()) { + return ImageSingletons.lookup(DynamicHubSupport.class); + } + DynamicHubSupport[] supports = MultiLayeredImageSingleton.getAllLayers(DynamicHubSupport.class); + return supports[layerIndex]; + } + @Platforms(Platform.HOSTED_ONLY.class) public DynamicHubSupport() { } @@ -66,7 +84,12 @@ public void setReferenceMapEncoding(NonmovableArray referenceMapEncoding) } @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public static NonmovableArray getReferenceMapEncoding() { - return NonmovableArrays.fromImageHeap(ImageSingletons.lookup(DynamicHubSupport.class).referenceMapEncoding); + public NonmovableArray getReferenceMapEncoding() { + return NonmovableArrays.fromImageHeap(referenceMapEncoding); + } + + @Override + public EnumSet getImageBuilderFlags() { + return LayeredImageSingletonBuilderFlags.ALL_ACCESS; } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/InteriorObjRefWalker.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/InteriorObjRefWalker.java index c86044d5a763..8ffa4550e36d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/InteriorObjRefWalker.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/InteriorObjRefWalker.java @@ -101,7 +101,7 @@ public static boolean walkInstanceReferenceOffsets(DynamicHub objHub, IntConsume throw new IllegalArgumentException("Unsupported hub type: " + objHub.getHubType()); } - NonmovableArray referenceMapEncoding = DynamicHubSupport.getReferenceMapEncoding(); + NonmovableArray referenceMapEncoding = DynamicHubSupport.forLayer(objHub.getLayerId()).getReferenceMapEncoding(); long referenceMapIndex = objHub.getReferenceMapIndex(); return InstanceReferenceMapDecoder.walkOffsetsFromPointer(WordFactory.zero(), referenceMapEncoding, referenceMapIndex, new ObjectReferenceVisitor() { @@ -116,7 +116,7 @@ public boolean visitObjectReference(Pointer objRef, boolean compressed, Object h @AlwaysInline("Performance critical version") @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) private static boolean walkInstance(Object obj, ObjectReferenceVisitor visitor, DynamicHub objHub, Pointer objPointer) { - NonmovableArray referenceMapEncoding = DynamicHubSupport.getReferenceMapEncoding(); + NonmovableArray referenceMapEncoding = DynamicHubSupport.forLayer(objHub.getLayerId()).getReferenceMapEncoding(); long referenceMapIndex = objHub.getReferenceMapIndex(); // Visit Object reference in the fields of the Object. 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 600ce9024967..4eb4ec502a76 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 @@ -91,6 +91,7 @@ import com.oracle.svm.core.hub.Hybrid; import com.oracle.svm.core.hub.PredefinedClassesSupport; import com.oracle.svm.core.hub.ReferenceType; +import com.oracle.svm.core.imagelayer.DynamicImageLayerInfo; import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport; import com.oracle.svm.core.interpreter.InterpreterSupport; import com.oracle.svm.core.jdk.InternalVMMethod; @@ -191,6 +192,7 @@ public enum UsageKind { private final FieldValueInterceptionSupport fieldValueInterceptionSupport; private final MissingRegistrationSupport missingRegistrationSupport; + private final int layerId; private final boolean useBaseLayer; private Set excludedFields; @@ -224,6 +226,7 @@ public SVMHost(OptionValues options, ImageClassLoader loader, ClassInitializatio } fieldValueInterceptionSupport = new FieldValueInterceptionSupport(annotationSubstitutions, classInitializationSupport); ImageSingletons.add(FieldValueInterceptionSupport.class, fieldValueInterceptionSupport); + layerId = ImageLayerBuildingSupport.buildingImageLayer() ? DynamicImageLayerInfo.singleton().layerNumber : 0; useBaseLayer = ImageLayerBuildingSupport.buildingExtensionLayer(); if (SubstrateOptions.includeAll()) { initializeExcludedFields(); @@ -490,7 +493,7 @@ private DynamicHub createHub(AnalysisType type) { return new DynamicHub(javaClass, className, computeHubType(type), computeReferenceType(type), superHub, componentHub, sourceFileName, modifiers, hubClassLoader, isHidden, isRecord, nestHost, assertionStatus, type.hasDefaultMethods(), type.declaresDefaultMethods(), isSealed, isVMInternal, isLambdaFormHidden, isLinked, simpleBinaryName, - getDeclaringClass(javaClass), getSignature(javaClass), isProxyClass); + getDeclaringClass(javaClass), getSignature(javaClass), isProxyClass, layerId); } private static final Method getSignature = ReflectionUtil.lookupMethod(Class.class, "getGenericSignature0"); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java index 97ad466a7cbb..f70fae0fcaaf 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java @@ -59,7 +59,6 @@ import com.oracle.graal.pointsto.flow.LoadFieldTypeFlow; import com.oracle.graal.pointsto.flow.MergeTypeFlow; import com.oracle.graal.pointsto.flow.MethodFlowsGraph; -import com.oracle.graal.pointsto.flow.MonitorEnterTypeFlow; import com.oracle.graal.pointsto.flow.NewInstanceTypeFlow; import com.oracle.graal.pointsto.flow.NullCheckTypeFlow; import com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow; @@ -361,7 +360,6 @@ public static class DashboardTypeFlowNames { names.put(FormalReceiverTypeFlow.class, "formalReceiver"); names.put(OffsetLoadTypeFlow.LoadIndexedTypeFlow.class, "loadIndexed"); names.put(MergeTypeFlow.class, "merge"); - names.put(MonitorEnterTypeFlow.class, "monitorEnter"); names.put(ProxyTypeFlow.class, "proxy"); names.put(SourceTypeFlow.class, "source"); names.put(OffsetStoreTypeFlow.StoreIndexedTypeFlow.class, "storeIndexed"); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ObjectGroupHistogram.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ObjectGroupHistogram.java index 85c2ab1f5fab..c9b93c356121 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ObjectGroupHistogram.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/ObjectGroupHistogram.java @@ -105,7 +105,7 @@ private void doPrint() { * order in which types are prcessed matters. */ processType(DynamicHub.class, "DynamicHub", true, null, ObjectGroupHistogram::filterDynamicHubField); - processObject(NonmovableArrays.getHostedArray(DynamicHubSupport.getReferenceMapEncoding()), "DynamicHub", true, null, null); + processObject(NonmovableArrays.getHostedArray(DynamicHubSupport.singleton().getReferenceMapEncoding()), "DynamicHub", true, null, null); processObject(CodeInfoTable.getImageCodeCache(), "ImageCodeInfo", true, ObjectGroupHistogram::filterCodeInfoObjects, null); processObject(readTruffleRuntimeCompilationSupportField("graphEncoding"), "CompressedGraph", true, ObjectGroupHistogram::filterGraalSupportObjects, null); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java index c1af300c33ff..b93b4879f7f1 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java @@ -914,8 +914,7 @@ private void buildHubs() { long referenceMapIndex = referenceMapEncoder.lookupEncoding(referenceMap); DynamicHub hub = type.getHub(); - hub.setSharedData(layoutHelper, monitorOffset, identityHashOffset, - referenceMapIndex, type.isInstantiated()); + hub.setSharedData(layoutHelper, monitorOffset, identityHashOffset, referenceMapIndex, type.isInstantiated()); if (SubstrateOptions.closedTypeWorld()) { CFunctionPointer[] vtable = new CFunctionPointer[type.closedTypeWorldVTable.length];