Skip to content

Commit

Permalink
Automatic merge of master into galahad
Browse files Browse the repository at this point in the history
  • Loading branch information
OracleLabsAutomation committed Jul 31, 2024
2 parents 07cc7c6 + d82a349 commit c5debee
Show file tree
Hide file tree
Showing 44 changed files with 2,024 additions and 332 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public void testIt() {
List<Field> externalValues = List.of(ObjectCopier.getField(BaseClass.class, "BASE_SINGLETON"),
ObjectCopier.getField(TestObject.class, "TEST_OBJECT_SINGLETON"));

String encoded = ObjectCopier.encode(root, externalValues);
String encoded = ObjectCopier.encode(new ObjectCopier.Encoder(externalValues), root);
if (DEBUG) {
System.out.printf("encoded:%n%s%n", encoded);
}
Expand All @@ -184,7 +184,7 @@ public void testIt() {
System.out.printf("root:%n%s%n", root);
System.out.printf("decoded:%n%s%n", decoded);
}
String reencoded = ObjectCopier.encode(decoded, externalValues);
String reencoded = ObjectCopier.encode(new ObjectCopier.Encoder(externalValues), decoded);
if (DEBUG) {
System.out.printf("reencoded:%n%s%n", reencoded);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,8 @@ protected boolean tryInvocationPlugin(CallTargetNode.InvokeKind invokeKind, Valu

/**
* To prevent this field being considered as an <i>externalValue</i> by
* {@link ObjectCopier#encode(Object, List)}, it must <b>not</b> be {@code final}.
* {@link ObjectCopier#encode(ObjectCopier.Encoder, Object)}, it must <b>not</b> be
* {@code final}.
*/
private static Map<Class<?>, SnippetResolvedJavaType> snippetTypes = new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;

import jdk.graal.compiler.core.common.spi.ForeignCallSignature;
Expand Down Expand Up @@ -89,7 +90,18 @@ public static void main(String[] args) throws Exception {
encodedObjects.put("encodedSnippets", encodedSnippets);
encodedObjects.put("foreignCallSignatures", foreignCallSignatures);

String encoded = ObjectCopier.encode(encodedObjects, externalValues);
ObjectCopier.Encoder encoder = new ObjectCopier.Encoder(externalValues) {
@Override
protected ClassInfo makeClassInfo(Class<?> declaringClass) {
ClassInfo ci = ClassInfo.of(declaringClass);
for (var f : ci.fields().values()) {
// Avoid problems with identity hash codes
GraalError.guarantee(!f.getName().toLowerCase(Locale.ROOT).contains("hash"), "Cannot serialize hash field: %s", f);
}
return ci;
}
};
String encoded = ObjectCopier.encode(encoder, encodedObjects);

Files.writeString(Path.of(args[0]), encoded);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -844,12 +844,12 @@ public int hashCode() {
private static final TimerKey SnippetTemplateCreationTime = DebugContext.timer("SnippetTemplateCreationTime");
private static final CounterKey SnippetTemplates = DebugContext.counter("SnippetTemplateCount");

static class Options {
public static class Options {
@Option(help = "Use a LRU cache for snippet templates.")//
public static final OptionKey<Boolean> UseSnippetTemplateCache = new OptionKey<>(true);

@Option(help = "")//
static final OptionKey<Integer> MaxTemplatesPerSnippet = new OptionKey<>(50);
public static final OptionKey<Integer> MaxTemplatesPerSnippet = new OptionKey<>(50);
}

/**
Expand Down Expand Up @@ -997,11 +997,11 @@ protected PhaseSuite<CoreProviders> createMidTierPostLoweringPhases() {
}
}

private static final class LRUCache<K, V> extends LinkedHashMap<K, V> {
public static final class LRUCache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
private final int maxCacheSize;

LRUCache(int initialCapacity, int maxCacheSize) {
public LRUCache(int initialCapacity, int maxCacheSize) {
super(initialCapacity, 0.75F, true);
this.maxCacheSize = maxCacheSize;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
Expand All @@ -56,6 +55,7 @@

import jdk.graal.compiler.core.common.FieldIntrospection;
import jdk.graal.compiler.debug.GraalError;
import jdk.graal.compiler.replacements.SnippetTemplate;
import jdk.internal.misc.Unsafe;

/**
Expand Down Expand Up @@ -92,7 +92,7 @@ public class ObjectCopier {
/**
* A builtin is specialized support for encoded and decoding values of specific types.
*/
abstract static class Builtin {
public abstract static class Builtin {
/**
* The primary type for this builtin.
*/
Expand Down Expand Up @@ -148,15 +148,15 @@ void makeChildIds(Encoder encoder, Object obj, ObjectPath objectPath) {
* Encodes the value of {@code obj} to a String that does not contain {@code '\n'} or
* {@code '\r'}.
*/
abstract String encode(Encoder encoder, Object obj);
protected abstract String encode(Encoder encoder, Object obj);

/**
* Decodes {@code encoded} to an object of a type handled by this builtin.
*
* @param encoding the non-default encoded used when encoded the object or null if the
* default encoded was used
*/
abstract Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded);
protected abstract Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded);

@Override
public String toString() {
Expand All @@ -182,12 +182,12 @@ static final class ClassBuiltin extends Builtin {
}

@Override
String encode(Encoder encoder, Object obj) {
protected String encode(Encoder encoder, Object obj) {
return ((Class<?>) obj).getName();
}

@Override
Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
protected Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
return switch (encoded) {
case "boolean" -> boolean.class;
case "byte" -> byte.class;
Expand Down Expand Up @@ -230,7 +230,7 @@ String encodingName(Object obj) {
}

@Override
String encode(Encoder encoder, Object obj) {
protected String encode(Encoder encoder, Object obj) {
String s = obj instanceof String ? (String) obj : new String((char[]) obj);
if ("escaped".equals(encodingName(s))) {
return s.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r");
Expand All @@ -239,7 +239,7 @@ String encode(Encoder encoder, Object obj) {
}

@Override
Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
protected Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
String s = encoded;
if (encoding != null) {
GraalError.guarantee(encoding.equals("escaped"), "Unknown encoded: %s", encoding);
Expand Down Expand Up @@ -270,13 +270,13 @@ static final class EnumBuiltin extends Builtin {
}

@Override
String encode(Encoder encoder, Object obj) {
protected String encode(Encoder encoder, Object obj) {
return ((Enum<?>) obj).name();
}

@SuppressWarnings({"unchecked", "rawtypes"})
@Override
Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
protected Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
return Enum.valueOf((Class) concreteType, encoded);
}
}
Expand All @@ -297,11 +297,13 @@ static final class HashMapBuiltin extends Builtin {
final Map<Class<?>, Supplier<?>> factories;

HashMapBuiltin() {
super(HashMap.class, IdentityHashMap.class, LinkedHashMap.class);
super(HashMap.class, IdentityHashMap.class, LinkedHashMap.class, SnippetTemplate.LRUCache.class);
int size = SnippetTemplate.Options.MaxTemplatesPerSnippet.getDefaultValue();
factories = Map.of(
HashMap.class, HashMap::new,
IdentityHashMap.class, IdentityHashMap::new,
LinkedHashMap.class, LinkedHashMap::new);
LinkedHashMap.class, LinkedHashMap::new,
SnippetTemplate.LRUCache.class, () -> new SnippetTemplate.LRUCache<>(size, size));
}

@Override
Expand All @@ -311,14 +313,14 @@ void makeChildIds(Encoder encoder, Object obj, ObjectPath objectPath) {
}

@Override
String encode(Encoder encoder, Object obj) {
protected String encode(Encoder encoder, Object obj) {
Map<?, ?> map = (Map<?, ?>) obj;
return encoder.encodeMap(new EconomicMapWrap<>(map));
}

@SuppressWarnings("unchecked")
@Override
Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
protected Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
Map<Object, Object> map = (Map<Object, Object>) factories.get(concreteType).get();
decoder.decodeMap(encoded, map::put);
return map;
Expand Down Expand Up @@ -350,12 +352,12 @@ void makeChildIds(Encoder encoder, Object obj, ObjectPath objectPath) {
}

@Override
String encode(Encoder encoder, Object obj) {
protected String encode(Encoder encoder, Object obj) {
return encoder.encodeMap((UnmodifiableEconomicMap<?, ?>) obj);
}

@Override
Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
protected Object decode(Decoder decoder, Class<?> concreteType, String encoding, String encoded) {
if (EconomicMap.class.isAssignableFrom(concreteType)) {
EconomicMap<Object, Object> map = EconomicMap.create();
decoder.decodeMap(encoded, map::put);
Expand All @@ -374,8 +376,8 @@ Object decode(Decoder decoder, Class<?> concreteType, String encoding, String en
* have the same name in which case the descriptor includes the qualified name of the
* class declaring the field as a prefix.
*/
record ClassInfo(Class<?> clazz, Map<String, Field> fields) {
static ClassInfo of(Class<?> declaringClass) {
public record ClassInfo(Class<?> clazz, Map<String, Field> fields) {
public static ClassInfo of(Class<?> declaringClass) {
Map<String, Field> fields = new HashMap<>();
for (Class<?> c = declaringClass; !c.equals(Object.class); c = c.getSuperclass()) {
for (Field f : c.getDeclaredFields()) {
Expand All @@ -387,9 +389,6 @@ static ClassInfo of(Class<?> declaringClass) {
}
Field conflict = fields.put(fieldDesc, f);
GraalError.guarantee(conflict == null, "Cannot support 2 fields with same name and declaring class: %s and %s", conflict, f);

// Try to avoid problems with identity hash codes
GraalError.guarantee(!f.getName().toLowerCase(Locale.ROOT).contains("hash"), "Cannot serialize hash field: %s", f);
}
}
}
Expand All @@ -403,7 +402,7 @@ static ClassInfo of(Class<?> declaringClass) {
final Map<Class<?>, Builtin> builtinClasses = new HashMap<>();
final Set<Class<?>> notBuiltins = new HashSet<>();

final void addBuiltin(Builtin builtin) {
protected final void addBuiltin(Builtin builtin) {
addBuiltin(builtin, builtin.clazz);
}

Expand Down Expand Up @@ -439,13 +438,9 @@ static String[] splitSpaceSeparatedElements(String elements) {
}

/**
* Encodes {@code root} to a String.
*
* @param externalValues static fields whose values should not be encoded but instead
* represented as a reference to the field
* Encodes {@code root} to a String using {@code encoder}.
*/
public static String encode(Object root, List<Field> externalValues) {
Encoder encoder = new Encoder(externalValues);
public static String encode(Encoder encoder, Object root) {
int rootId = encoder.makeId(root, ObjectPath.of("[root]")).id();
GraalError.guarantee(rootId == 1, "The root object should have id of 1, not %d", rootId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Expand All @@ -457,15 +452,19 @@ public static String encode(Object root, List<Field> externalValues) {

public static Object decode(String encoded, ClassLoader loader) {
Decoder decoder = new Decoder(loader);
return decode(decoder, encoded);
}

public static Object decode(Decoder decoder, String encoded) {
return decoder.decode(encoded);
}

static class Decoder extends ObjectCopier {
public static class Decoder extends ObjectCopier {

private final Map<Integer, Object> idToObject = new HashMap<>();
private final ClassLoader loader;

Decoder(ClassLoader loader) {
public Decoder(ClassLoader loader) {
this.loader = loader;
}

Expand Down Expand Up @@ -779,7 +778,7 @@ final Builtin getBuiltin(Class<?> clazz, boolean onlyCheck) {
return b;
}

static class Encoder extends ObjectCopier {
public static class Encoder extends ObjectCopier {

final Map<Object, ObjectID> objectToId = new IdentityHashMap<>();
final List<Object> objects = new ArrayList<>();
Expand All @@ -790,14 +789,25 @@ static class Encoder extends ObjectCopier {
*/
final Map<Object, Field> externalValues = new IdentityHashMap<>();

Encoder(List<Field> externalValues) {
public Encoder(List<Field> externalValues) {
objects.add(null);
objectToId.put(null, new ObjectID(0, null));
for (Field f : externalValues) {
addExternalValue(f);
}
}

/**
* Gets a {@link ClassInfo} for encoding the fields of {@code declaringClass}.
* <p>
* A subclass can override this to enforce encoding invariants on classes or fields.
*
* @throws GraalError if an invariant is violated
*/
protected ClassInfo makeClassInfo(Class<?> declaringClass) {
return ClassInfo.of(declaringClass);
}

private void addExternalValue(Field field) {
GraalError.guarantee(Modifier.isStatic(field.getModifiers()), "Field '%s' is not static. Only a static field can be used as known location for an instance.", field);
Object value = readField(field, null);
Expand All @@ -814,6 +824,10 @@ private void addExternalValue(Field field) {

}

public Map<Object, Field> getExternalValues() {
return externalValues;
}

private String encodeMap(UnmodifiableEconomicMap<?, ?> map) {
UnmodifiableMapCursor<?, ?> cursor = map.getEntries();
StringBuilder value = new StringBuilder();
Expand Down Expand Up @@ -858,8 +872,6 @@ ObjectID makeId(Object obj, ObjectPath objectPath) {
objectToId.put(field, id);
return id;
}
checkIllegalValue(Field.class, obj, objectPath, "Field type is used in object copying implementation");
checkIllegalValue(FieldIntrospection.class, obj, objectPath, "Graal metadata type cannot be copied");

objects.add(obj);
objectToId.put(obj, id);
Expand All @@ -871,6 +883,10 @@ ObjectID makeId(Object obj, ObjectPath objectPath) {
builtin.makeChildIds(this, obj, objectPath);
return id;
}

checkIllegalValue(Field.class, obj, objectPath, "Field type is used in object copying implementation");
checkIllegalValue(FieldIntrospection.class, obj, objectPath, "Graal metadata type cannot be copied");

if (clazz.isArray()) {
Class<?> componentType = clazz.getComponentType();
if (!componentType.isPrimitive()) {
Expand All @@ -885,7 +901,7 @@ ObjectID makeId(Object obj, ObjectPath objectPath) {
checkIllegalValue(LocationIdentity.class, obj, objectPath, "must come from a static field");
checkIllegalValue(HashSet.class, obj, objectPath, "hashes are typically not stable across VM executions");

ClassInfo classInfo = classInfos.computeIfAbsent(clazz, ClassInfo::of);
ClassInfo classInfo = classInfos.computeIfAbsent(clazz, this::makeClassInfo);
for (Field f : classInfo.fields().values()) {
makeId(f.getType(), objectPath.add(f.getName() + ":type"));
if (!f.getType().isPrimitive()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ public StandalonePointsToAnalysis(OptionValues options, AnalysisUniverse univers
public void cleanupAfterAnalysis() {
super.cleanupAfterAnalysis();
// No need to keep method graphs for standalone analysis.
universe.getMethods().forEach(m -> {
m.setAnalyzedGraph(null);
});
universe.getMethods().forEach(AnalysisMethod::clearAnalyzedGraph);
universe.getMethods().clear();
universe.getFields().clear();
addedClinits.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public final class AnalysisParsedGraph {
private final EncodedGraph encodedGraph;
private final boolean isIntrinsic;

private AnalysisParsedGraph(EncodedGraph encodedGraph, boolean isIntrinsic) {
public AnalysisParsedGraph(EncodedGraph encodedGraph, boolean isIntrinsic) {
this.isIntrinsic = isIntrinsic;
this.encodedGraph = encodedGraph;
}
Expand Down
Loading

0 comments on commit c5debee

Please sign in to comment.