From a8e66a0dbdb83dacac1108d6c27338fee744d9c9 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Fri, 13 Jun 2025 09:45:12 +0200 Subject: [PATCH] Make sure that JDWP commands related to retrieving loaded classes include loaded array classes --- .../espresso/jdwp/api/JDWPContext.java | 7 +- .../truffle/espresso/jdwp/api/KlassRef.java | 5 +- .../truffle/espresso/jdwp/impl/JDWP.java | 13 ++-- .../oracle/truffle/espresso/cds/Reader.java | 2 +- .../espresso/impl/ClassRegistries.java | 69 +++++++++++++++---- .../truffle/espresso/impl/ClassRegistry.java | 42 ++++++++--- .../oracle/truffle/espresso/impl/Klass.java | 33 ++++++--- .../truffle/espresso/jvmci/JVMCIUtils.java | 2 +- .../oracle/truffle/espresso/meta/Meta.java | 4 +- .../redefinition/InnerClassRedefiner.java | 2 +- .../espresso/runtime/GuestAllocator.java | 2 +- .../espresso/runtime/JDWPContextImpl.java | 39 ++++++----- ..._jvmci_meta_EspressoResolvedArrayType.java | 2 +- .../Target_java_lang_reflect_Array.java | 2 +- ...et_sun_instrument_InstrumentationImpl.java | 11 +-- .../truffle/espresso/vm/Management.java | 4 +- .../com/oracle/truffle/espresso/vm/VM.java | 4 +- 17 files changed, 165 insertions(+), 78 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java index dd7b3d8f22d6..82f2392e7d4f 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java @@ -24,6 +24,7 @@ import java.nio.file.Path; import java.util.List; +import java.util.Set; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.Frame; @@ -65,7 +66,7 @@ public interface JDWPContext { * * @return array containing every class loaded */ - KlassRef[] getAllLoadedClasses(); + Set getAllLoadedClasses(); /** * Finds the method for which an root node was created from. @@ -177,9 +178,9 @@ public interface JDWPContext { * Returns all classes for which the class loader initiated loading. * * @param classLoader guest language class loader - * @return array of classes initiated by the class loader + * @return set of classes initiated by the class loader */ - List getInitiatedClasses(Object classLoader); + Set getInitiatedClasses(Object classLoader); /** * Retrieves the field value of a static field. diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/KlassRef.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/KlassRef.java index 3df70b0f59d6..84e6eb72cd9d 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/KlassRef.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/KlassRef.java @@ -147,12 +147,13 @@ public interface KlassRef { int getModifiers(); /** - * Returns the array klass for this klass with the given dimensions. + * Returns the array klass for this klass with the given dimensions iff the array type was + * loaded. * * @param dimensions array dimension * @return array klass */ - KlassRef getArrayClass(int dimensions); + KlassRef getArrayClassNoCreate(int dimensions); /** * Returns the major version of the corresponding class file for this klass. diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java index 3f0eed6d69b1..2bca8e9c34e8 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.espresso.classfile.attributes.LineNumberTableRef; @@ -112,8 +113,8 @@ static class ALL_CLASSES { static CommandResult createReply(Packet packet, JDWPContext context, DebuggerController controller) { PacketStream reply = new PacketStream().replyPacket().id(packet.id); - KlassRef[] allLoadedClasses = context.getAllLoadedClasses(); - reply.writeInt(allLoadedClasses.length); + Set allLoadedClasses = context.getAllLoadedClasses(); + reply.writeInt(allLoadedClasses.size()); for (KlassRef klass : allLoadedClasses) { reply.writeByte(TypeTag.getKind(klass)); @@ -121,7 +122,7 @@ static CommandResult createReply(Packet packet, JDWPContext context, DebuggerCon reply.writeString(klass.getTypeAsString()); reply.writeInt(klass.getStatus()); } - controller.fine(() -> "Loaded classes: " + allLoadedClasses.length); + controller.fine(() -> "Loaded classes: " + allLoadedClasses.size()); return new CommandResult(reply); } @@ -438,8 +439,8 @@ static class ALL_CLASSES_WITH_GENERIC { static CommandResult createReply(Packet packet, JDWPContext context) { PacketStream reply = new PacketStream().replyPacket().id(packet.id); - KlassRef[] allLoadedClasses = context.getAllLoadedClasses(); - reply.writeInt(allLoadedClasses.length); + Set allLoadedClasses = context.getAllLoadedClasses(); + reply.writeInt(allLoadedClasses.size()); for (KlassRef klass : allLoadedClasses) { reply.writeByte(TypeTag.getKind(klass)); @@ -2659,7 +2660,7 @@ static CommandResult createReply(Packet packet, JDWPContext context) { if (classLoader == null) { return new CommandResult(reply); } - List klasses = context.getInitiatedClasses(classLoader); + Set klasses = context.getInitiatedClasses(classLoader); reply.writeInt(klasses.size()); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/cds/Reader.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/cds/Reader.java index 5bf60ed7a58d..7d4d1128bc72 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/cds/Reader.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/cds/Reader.java @@ -464,7 +464,7 @@ private void skipGuestClass() { Symbol elementalTypeSymbol = espressoContext.getTypes().getElementalType(typeSymbol); if (TypeSymbols.isArray(typeSymbol) && TypeSymbols.isPrimitive(elementalTypeSymbol)) { Klass elemental = meta.resolvePrimitive(elementalTypeSymbol); - klass = elemental.getArrayClass(TypeSymbols.getArrayDimensions(typeSymbol)); + klass = elemental.getArrayKlass(TypeSymbols.getArrayDimensions(typeSymbol)); } else { klass = meta.loadKlassOrNull(typeSymbol, StaticObject.NULL, StaticObject.NULL); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistries.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistries.java index 6f70212b9f19..1c553826fca3 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistries.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistries.java @@ -25,7 +25,10 @@ import static com.oracle.truffle.espresso.impl.LoadingConstraints.INVALID_LOADER_ID; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.WeakHashMap; @@ -190,7 +193,7 @@ public Klass findLoadedClass(Symbol type, @JavaType(ClassLoader.class) Sta if (elemental == null) { return null; } - return elemental.getArrayClass(TypeSymbols.getArrayDimensions(type)); + return elemental.getArrayKlass(TypeSymbols.getArrayDimensions(type)); } ClassRegistry registry = getClassRegistry(classLoader); @@ -199,16 +202,44 @@ public Klass findLoadedClass(Symbol type, @JavaType(ClassLoader.class) Sta } @TruffleBoundary - public List getLoadedClassesByLoader(StaticObject classLoader) { + public Set getLoadedClassesByLoader(StaticObject classLoader, boolean includeHidden) { if (classLoader == StaticObject.NULL) { - ArrayList result = new ArrayList<>(bootClassRegistry.classes.size()); + Set result = new HashSet<>(); for (RegistryEntry value : bootClassRegistry.classes.values()) { result.add(value.klass()); } + if (includeHidden) { + addAllHiddenKlasses(bootClassRegistry, result); + } + // include array classes + result.addAll(getLoadedArrayClasses(result)); + // include primitive array classes, but not the primitive classes themselves + result.addAll(getLoadedArrayClasses(Arrays.asList(context.getMeta().PRIMITIVE_KLASSES))); return result; } ClassRegistry classRegistry = getClassRegistry(classLoader); - return classRegistry == null ? Collections.emptyList() : classRegistry.getLoadedKlasses(); + if (classRegistry == null) { + return Collections.emptySet(); + } + Set result = classRegistry.getLoadedKlasses(); + if (includeHidden) { + addAllHiddenKlasses(classRegistry, result); + } + + // include loaded array classes + result.addAll(getLoadedArrayClasses(result)); + return result; + } + + private static void addAllHiddenKlasses(ClassRegistry registry, Set result) { + synchronized (registry.getStrongHiddenClassRegistrationLock()) { + if (registry.strongHiddenKlasses != null) { + result.addAll(registry.strongHiddenKlasses); + } + if (registry.getHiddenKlasses() != null) { + result.addAll(registry.getHiddenKlasses()); + } + } } @TruffleBoundary @@ -234,21 +265,29 @@ public Klass[] findLoadedClassAny(Symbol type) { } @TruffleBoundary - public List getAllLoadedClasses() { - ArrayList list = new ArrayList<>(); - // add classes from boot registry - for (RegistryEntry entry : bootClassRegistry.classes.values()) { - list.add(entry.klass()); - } + public Set getAllLoadedClasses() { + // first add classes from boot registry + HashSet set = new HashSet<>(getLoadedClassesByLoader(StaticObject.NULL, true)); + // add classes from all other registries synchronized (weakClassLoaderSet) { for (StaticObject classLoader : weakClassLoaderSet) { - for (RegistryEntry entry : getClassRegistry(classLoader).classes.values()) { - list.add(entry.klass()); - } + set.addAll(getLoadedClassesByLoader(classLoader, true)); } } - return list; + return set; + } + + private static Set getLoadedArrayClasses(Collection elementalKlasses) { + Set result = new HashSet<>(); + for (Klass elementalKlass : elementalKlasses) { + ArrayKlass arrayKlass = elementalKlass.getArrayKlass(false); + while (arrayKlass != null) { + result.add(arrayKlass); + arrayKlass = arrayKlass.getArrayKlass(false); + } + } + return result; } public ModuleRef[] getAllModuleRefs() { @@ -298,7 +337,7 @@ public Klass loadKlass(Symbol type, @JavaType(ClassLoader.class) StaticObj if (elemental == null) { return null; } - return elemental.getArrayClass(TypeSymbols.getArrayDimensions(type)); + return elemental.getArrayKlass(TypeSymbols.getArrayDimensions(type)); } ClassRegistry registry = getClassRegistry(classLoader); return registry.loadKlass(context, type, protectionDomain); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistry.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistry.java index d17dce089afc..3abe68c965c9 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistry.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistry.java @@ -24,8 +24,11 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.List; +import java.util.Collections; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -281,13 +284,19 @@ public byte[] getRetransformBytes(Klass klass) { * reclaimed, while not appearing in the actual registry. This field simply keeps those hidden * classes strongly reachable from the class registry. */ - private volatile Collection strongHiddenKlasses = null; + volatile Collection strongHiddenKlasses = null; - private Object getStrongHiddenClassRegistrationLock() { + /** + * Hidden classes must be reachable until they're unloaded, because JDWP and JVMTI must be able + * to query all classes. + */ + private volatile WeakHashMap hiddenKlasses = null; + + Object getStrongHiddenClassRegistrationLock() { return this; } - private void registerStrongHiddenClass(Klass klass) { + private void registerStrongHiddenKlass(Klass klass) { synchronized (getStrongHiddenClassRegistrationLock()) { if (strongHiddenKlasses == null) { strongHiddenKlasses = new ArrayList<>(); @@ -296,6 +305,19 @@ private void registerStrongHiddenClass(Klass klass) { } } + private void registerHiddenKlass(Klass klass) { + synchronized (getStrongHiddenClassRegistrationLock()) { + if (hiddenKlasses == null) { + hiddenKlasses = new WeakHashMap<>(); + } + hiddenKlasses.put(klass, null); + } + } + + public Set getHiddenKlasses() { + return hiddenKlasses != null ? hiddenKlasses.keySet() : Collections.emptySet(); + } + protected ClassRegistry(long loaderID, ArchivedRegistryData archivedData) { this.loaderID = loaderID; if (archivedData != null) { @@ -332,7 +354,7 @@ Klass loadKlass(EspressoContext context, Symbol type, StaticObject protect if (elemental == null) { return null; } - return elemental.getArrayClass(TypeSymbols.getArrayDimensions(type)); + return elemental.getArrayKlass(TypeSymbols.getArrayDimensions(type)); } loadKlassCountInc(); @@ -373,8 +395,8 @@ Klass loadKlass(EspressoContext context, Symbol type, StaticObject protect public abstract @JavaType(ClassLoader.class) StaticObject getClassLoader(); @TruffleBoundary - public List getLoadedKlasses() { - ArrayList klasses = new ArrayList<>(classes.size()); + Set getLoadedKlasses() { + HashSet klasses = new HashSet<>(classes.size()); for (ClassRegistries.RegistryEntry entry : classes.values()) { klasses.add(entry.klass()); } @@ -388,7 +410,7 @@ public Klass findLoadedKlass(ClassLoadingEnv env, Symbol type) { if (elementalKlass == null) { return null; } - return elementalKlass.getArrayClass(TypeSymbols.getArrayDimensions(type)); + return elementalKlass.getArrayKlass(TypeSymbols.getArrayDimensions(type)); } ClassRegistries.RegistryEntry entry = classes.get(type); if (entry == null) { @@ -456,7 +478,9 @@ public ObjectKlass defineKlass(EspressoContext context, Symbol typeOrNull, if (info.addedToRegistry()) { registerKlass(klass, type, beforeRetransformBytes); } else if (info.isStrongHidden()) { - registerStrongHiddenClass(klass); + registerStrongHiddenKlass(klass); + } else { + registerHiddenKlass(klass); } return klass; } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Klass.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Klass.java index 8e35ec9355ad..405175d1a9ad 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Klass.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Klass.java @@ -945,18 +945,22 @@ private boolean checkTypeName(@JavaType(String.class) StaticObject computedTypeN /** * Gets the array class type representing an array with elements of this type. * - * This method is equivalent to {@link Klass#getArrayClass()}. + * This method is equivalent to {@link Klass#getArrayKlass()}. */ public final ArrayKlass array() { - return getArrayClass(); + return getArrayKlass(); } /** * Gets the array class type representing an array with elements of this type. */ - public final ArrayKlass getArrayClass() { + public final ArrayKlass getArrayKlass() { + return getArrayKlass(true); + } + + public final ArrayKlass getArrayKlass(boolean create) { ArrayKlass result = this.arrayKlass; - if (result == null) { + if (result == null && create) { CompilerDirectives.transferToInterpreterAndInvalidate(); result = createArrayKlass(); } @@ -972,10 +976,13 @@ private synchronized ArrayKlass createArrayKlass() { return result; } - @Override - public ArrayKlass getArrayClass(int dimensions) { + public ArrayKlass getArrayKlass(int dimensions) { + return getArrayKlass(dimensions, true); + } + + private ArrayKlass getArrayKlass(int dimensions, boolean create) { assert dimensions > 0; - ArrayKlass array = array(); + ArrayKlass array = getArrayKlass(create); // Careful with of impossible void[]. if (array == null) { @@ -983,11 +990,19 @@ public ArrayKlass getArrayClass(int dimensions) { } for (int i = 1; i < dimensions; ++i) { - array = array.getArrayClass(); + array = array.getArrayKlass(create); + if (array == null) { + return null; + } } return array; } + @Override + public ArrayKlass getArrayClassNoCreate(int dimensions) { + return getArrayKlass(dimensions, false); + } + @Override public final boolean equals(Object that) { return this == that; @@ -1346,7 +1361,7 @@ public StaticObject allocateReferenceArray(int length, IntFunction for (int i = 0; i < array.length; ++i) { array[i] = generator.apply(i); } - return meta.getAllocator().wrapArrayAs(getArrayClass(), array); + return meta.getAllocator().wrapArrayAs(getArrayKlass(), array); } // region Lookup diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jvmci/JVMCIUtils.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jvmci/JVMCIUtils.java index 93925b244b13..ae315e610762 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jvmci/JVMCIUtils.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jvmci/JVMCIUtils.java @@ -69,7 +69,7 @@ public static Klass findObjectType(Symbol symbol, ObjectKlass accessingKla if (elemental == null) { return null; } - return elemental.getArrayClass(TypeSymbols.getArrayDimensions(symbol)); + return elemental.getArrayKlass(TypeSymbols.getArrayDimensions(symbol)); } else { return findInstanceType(symbol, accessingKlass, resolve, meta); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java index 7715a132ca8d..93972fd31b04 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java @@ -2987,7 +2987,7 @@ public Klass resolveSymbolOrNull(Symbol type, @JavaType(ClassLoader.class) if (elemental == null) { return null; } - return elemental.getArrayClass(TypeSymbols.getArrayDimensions(type)); + return elemental.getArrayKlass(TypeSymbols.getArrayDimensions(type)); } return loadKlassOrNull(type, classLoader, protectionDomain); } @@ -3007,7 +3007,7 @@ public Klass resolveSymbolOrFail(Symbol type, @JavaType(ClassLoader.class) } if (TypeSymbols.isArray(type)) { Klass elemental = resolveSymbolOrFail(getTypes().getElementalType(type), classLoader, protectionDomain); - return elemental.getArrayClass(TypeSymbols.getArrayDimensions(type)); + return elemental.getArrayKlass(TypeSymbols.getArrayDimensions(type)); } return loadKlassOrFail(type, classLoader, protectionDomain); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java index daf5a9d71a16..0470673722f2 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java @@ -351,7 +351,7 @@ public void onKlassDefined(ObjectKlass objectKlass) { // do a one-time look up of all currently loaded // classes for this loader and fill in the map - List loadedKlasses = classRegistry.getLoadedKlasses(); + Set loadedKlasses = context.getRegistries().getLoadedClassesByLoader(klass.getDefiningClassLoader(), false); for (Klass loadedKlass : loadedKlasses) { if (loadedKlass instanceof ObjectKlass objectKlass) { Matcher matcher = ANON_INNER_CLASS_PATTERN.matcher(loadedKlass.getNameAsString()); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/GuestAllocator.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/GuestAllocator.java index 95d0edb8836c..18cb1d3fbab7 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/GuestAllocator.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/GuestAllocator.java @@ -245,7 +245,7 @@ public StaticObject createNewReferenceArray(Klass componentKlass, int length) { assert AllocationChecks.canAllocateNewArray(length); StaticObject[] arr = new StaticObject[length]; Arrays.fill(arr, StaticObject.NULL); - return wrapArrayAs(componentKlass.getArrayClass(), arr); + return wrapArrayAs(componentKlass.getArrayKlass(), arr); } /** diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java index 260c188e5417..87e01b6afd47 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java @@ -26,6 +26,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -194,21 +195,21 @@ public KlassRef[] findLoadedClass(String slashName) { // primitive switch (componentRawName) { case "I": - return new KlassRef[]{context.getMeta()._int.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._int.getArrayClassNoCreate(dimensions)}; case "Z": - return new KlassRef[]{context.getMeta()._boolean.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._boolean.getArrayClassNoCreate(dimensions)}; case "S": - return new KlassRef[]{context.getMeta()._short.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._short.getArrayClassNoCreate(dimensions)}; case "C": - return new KlassRef[]{context.getMeta()._char.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._char.getArrayClassNoCreate(dimensions)}; case "B": - return new KlassRef[]{context.getMeta()._byte.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._byte.getArrayClassNoCreate(dimensions)}; case "J": - return new KlassRef[]{context.getMeta()._long.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._long.getArrayClassNoCreate(dimensions)}; case "D": - return new KlassRef[]{context.getMeta()._double.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._double.getArrayClassNoCreate(dimensions)}; case "F": - return new KlassRef[]{context.getMeta()._float.getArrayClass(dimensions)}; + return new KlassRef[]{context.getMeta()._float.getArrayClassNoCreate(dimensions)}; default: throw new RuntimeException("invalid primitive component type " + componentRawName); } @@ -217,11 +218,14 @@ public KlassRef[] findLoadedClass(String slashName) { String componentType = componentRawName.substring(1, componentRawName.length() - 1); Symbol type = context.getTypes().fromClassGetName(componentType); KlassRef[] klassRefs = context.getRegistries().findLoadedClassAny(type); - KlassRef[] result = new KlassRef[klassRefs.length]; - for (int i = 0; i < klassRefs.length; i++) { - result[i] = klassRefs[i].getArrayClass(dimensions); + List result = new ArrayList<>(); + for (KlassRef klassRef : klassRefs) { + KlassRef array = klassRef.getArrayClassNoCreate(dimensions); + if (array != null) { + result.add(array); + } } - return result; + return result.toArray(new KlassRef[0]); } } else { // regular type @@ -231,19 +235,20 @@ public KlassRef[] findLoadedClass(String slashName) { } @Override - public KlassRef[] getAllLoadedClasses() { - return context.getRegistries().getAllLoadedClasses().toArray(new KlassRef[0]); + public Set getAllLoadedClasses() { + return context.getRegistries().getAllLoadedClasses(); } @Override - public List getInitiatedClasses(Object classLoader) { - return context.getRegistries().getLoadedClassesByLoader((StaticObject) classLoader); + public Set getInitiatedClasses(Object classLoader) { + return context.getRegistries().getLoadedClassesByLoader((StaticObject) classLoader, false); } @Override public boolean isValidClassLoader(Object object) { if (object instanceof StaticObject loader) { - return InterpreterToVM.instanceOf(loader, context.getMeta().java_lang_ClassLoader); + // boot loader is StaticObject.NULL + return StaticObject.isNull(loader) || InterpreterToVM.instanceOf(loader, context.getMeta().java_lang_ClassLoader); } return false; } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/jvmci/Target_com_oracle_truffle_espresso_jvmci_meta_EspressoResolvedArrayType.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/jvmci/Target_com_oracle_truffle_espresso_jvmci_meta_EspressoResolvedArrayType.java index 31fd9d45f414..28d931991a80 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/jvmci/Target_com_oracle_truffle_espresso_jvmci_meta_EspressoResolvedArrayType.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/jvmci/Target_com_oracle_truffle_espresso_jvmci_meta_EspressoResolvedArrayType.java @@ -47,7 +47,7 @@ private Target_com_oracle_truffle_espresso_jvmci_meta_EspressoResolvedArrayType( throw meta.throwIllegalArgumentExceptionBoundary(); } Klass baseKlass = base.getMirrorKlass(meta); - ArrayKlass arrayKlass = baseKlass.getArrayClass(dimensionsDelta); + ArrayKlass arrayKlass = baseKlass.getArrayKlass(dimensionsDelta); return arrayKlass.mirror(); } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_java_lang_reflect_Array.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_java_lang_reflect_Array.java index 598fe8b8c30c..de6339d35bf7 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_java_lang_reflect_Array.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_java_lang_reflect_Array.java @@ -148,7 +148,7 @@ static StaticObject newArrayImpl(@JavaType(Class.class) StaticObject componentTy if (dimensions.length == 1) { return meta.getAllocator().createNewMultiArray(component, dimensions); } - return meta.getAllocator().createNewMultiArray(component.getArrayClass(dimensions.length - 1), dimensions); + return meta.getAllocator().createNewMultiArray(component.getArrayKlass(dimensions.length - 1), dimensions); } @Substitution diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_sun_instrument_InstrumentationImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_sun_instrument_InstrumentationImpl.java index 5c944980af76..6e0ac52507f7 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_sun_instrument_InstrumentationImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/standard/Target_sun_instrument_InstrumentationImpl.java @@ -23,7 +23,7 @@ package com.oracle.truffle.espresso.substitutions.standard; import java.util.ArrayList; -import java.util.List; +import java.util.Set; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.espresso.EspressoLanguage; @@ -166,15 +166,16 @@ public static boolean isModifiableClass0( @SuppressWarnings("unused") long agentId, @JavaType(ClassLoader.class) StaticObject loader, @Inject EspressoContext context) { - List initiatedKlasses = context.getRegistries().getClassRegistry(loader).getLoadedKlasses(); + Set initiatedKlasses = context.getRegistries().getLoadedClassesByLoader(loader, false); return toGuestClassArray(context, initiatedKlasses); } @TruffleBoundary - private static StaticObject toGuestClassArray(EspressoContext context, List initiatedKlasses) { + private static StaticObject toGuestClassArray(EspressoContext context, Set initiatedKlasses) { StaticObject[] guestKlasses = new StaticObject[initiatedKlasses.size()]; - for (int i = 0; i < initiatedKlasses.size(); i++) { - guestKlasses[i] = initiatedKlasses.get(i).mirror(); + int i = 0; + for (Klass initiatedKlass : initiatedKlasses) { + guestKlasses[i++] = initiatedKlass.mirror(); } return StaticObject.wrap(guestKlasses, context.getMeta()); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/Management.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/Management.java index 7d7eaab4b816..afeff111f91d 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/Management.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/Management.java @@ -844,7 +844,7 @@ public void GetThreadAllocatedMemory( public @JavaType(Thread[].class) StaticObject FindDeadlocks(boolean objectMonitorsOnly, @Inject Meta meta) { if (!objectMonitorsOnly) { getLogger().warning(() -> "Calling unimplemented Management.FindDeadlocks(false)"); - return StaticObject.createArray(meta.java_lang_Thread.getArrayClass(), StaticObject.EMPTY_ARRAY, getContext()); + return StaticObject.createArray(meta.java_lang_Thread.getArrayKlass(), StaticObject.EMPTY_ARRAY, getContext()); } Thread initiatingThread = Thread.currentThread(); EspressoThreadRegistry threadRegistry = getContext().getEspressoEnv().getThreadRegistry(); @@ -858,7 +858,7 @@ public void GetThreadAllocatedMemory( } }, future); assert action.results != null; - return StaticObject.createArray(meta.java_lang_Thread.getArrayClass(), action.results, getContext()); + return StaticObject.createArray(meta.java_lang_Thread.getArrayKlass(), action.results, getContext()); } private static class FindDeadLocksAction extends ThreadLocalAction { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java index 184030d61094..660a1a090d6a 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java @@ -584,7 +584,7 @@ public static void JVM_GC() { packageNames.add(meta.toGuestString(s)); } }); - return StaticObject.createArray(meta.java_lang_String.getArrayClass(), packageNames.toArray(StaticObject.EMPTY_ARRAY), getContext()); + return StaticObject.createArray(meta.java_lang_String.getArrayKlass(), packageNames.toArray(StaticObject.EMPTY_ARRAY), getContext()); } @VmImpl @@ -3486,7 +3486,7 @@ public int JNI_GetCreatedJavaVMs(@Pointer TruffleObject vmBufPtr, int bufLen, @P if (numThreads < threads.length) { threads = Arrays.copyOf(threads, numThreads); } - return getMeta().getAllocator().wrapArrayAs(getMeta().java_lang_Thread.getArrayClass(), threads); + return getMeta().getAllocator().wrapArrayAs(getMeta().java_lang_Thread.getArrayKlass(), threads); } // endregion threads