This is an automated email from the ASF dual-hosted git repository. samt pushed a commit to branch cassandra-4.1 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit 28759d8bbc16daf45ca07ee27b4a8dfedc8cf92b Author: David Capwell <[email protected]> AuthorDate: Tue Dec 13 13:37:40 2022 -0800 CEP-10: Simulator Java11 Support (backport to cassandra-4.1) patch by David Capwell; reviewed by Benedict Elliott Smith, Ekaterina Dimitrova for CASSANDRA-17178 backported to 4.1 in CASSANDRA-19935 --- CHANGES.txt | 1 + .../cassandra/simulator/asm/ClassTransformer.java | 51 +++++++++++++++++++++- .../cassandra/simulator/asm/InterceptAgent.java | 6 ++- .../cassandra/simulator/asm/InterceptClasses.java | 1 + .../org/apache/cassandra/simulator/asm/Utils.java | 8 ++++ 5 files changed, 64 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6d6da13c10..bcb9dec299 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.1.8 + * Backport Java 11 support for Simulator (CASSANDRA-17178/CASSANDRA-19935) * Equality check for Paxos.Electorate should not depend on collection types (CASSANDRA-19935) * Fix race condition in DecayingEstimatedHistogramReservoir during rescale (CASSANDRA-19365) Merged from 4.0: diff --git a/test/simulator/asm/org/apache/cassandra/simulator/asm/ClassTransformer.java b/test/simulator/asm/org/apache/cassandra/simulator/asm/ClassTransformer.java index 6e6b0d30de..778e44c808 100644 --- a/test/simulator/asm/org/apache/cassandra/simulator/asm/ClassTransformer.java +++ b/test/simulator/asm/org/apache/cassandra/simulator/asm/ClassTransformer.java @@ -110,6 +110,8 @@ class ClassTransformer extends ClassVisitor implements MethodWriterSink private final EnumSet<Flag> flags; private final Consumer<String> dependentTypes; + private boolean updateVisibility = false; + ClassTransformer(int api, String className, EnumSet<Flag> flags, Consumer<String> dependentTypes) { this(api, new ClassWriter(0), className, flags, null, null, null, null, dependentTypes); @@ -137,12 +139,58 @@ class ClassTransformer extends ClassVisitor implements MethodWriterSink this.methodLogger = MethodLogger.log(api, className); } + public void setUpdateVisibility(boolean updateVisibility) + { + this.updateVisibility = updateVisibility; + } + + /** + * Java 11 changed the way that classes defined in the same source file get access to private state (see https://openjdk.org/jeps/181), + * rather than trying to adapt to this, this method attempts to make the field/method/class public so that access + * is not restricted. + */ + private int makePublic(int access) + { + if (!updateVisibility) + return access; + // leave non-user created methods/fields/etc. alone + if (contains(access, Opcodes.ACC_BRIDGE) || contains(access, Opcodes.ACC_SYNTHETIC)) + return access; + if (contains(access, Opcodes.ACC_PRIVATE)) + { + access &= ~Opcodes.ACC_PRIVATE; + access |= Opcodes.ACC_PUBLIC; + } + else if (contains(access, Opcodes.ACC_PROTECTED)) + { + access &= ~Opcodes.ACC_PROTECTED; + access |= Opcodes.ACC_PUBLIC; + } + else if (!contains(access, Opcodes.ACC_PUBLIC)) // package-protected + { + access |= Opcodes.ACC_PUBLIC; + } + return access; + } + + private static boolean contains(int value, int mask) + { + return (value & mask) != 0; + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) + { + super.visit(version, makePublic(access), name, signature, superName, interfaces); + + } + @Override public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { if (dependentTypes != null) Utils.visitIfRefType(descriptor, dependentTypes); - return super.visitField(access, name, descriptor, signature, value); + return super.visitField(makePublic(access), name, descriptor, signature, value); } @Override @@ -176,6 +224,7 @@ class ClassTransformer extends ClassVisitor implements MethodWriterSink isToString = true; } + access = makePublic(access); MethodVisitor visitor; if (flags.contains(MONITORS) && (access & Opcodes.ACC_SYNCHRONIZED) != 0) { diff --git a/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptAgent.java b/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptAgent.java index 87cfab0f6f..ffa9b180e5 100644 --- a/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptAgent.java +++ b/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptAgent.java @@ -296,12 +296,14 @@ public class InterceptAgent visitor.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", false); visitor.visitFieldInsn(GETSTATIC, "java/util/concurrent/ThreadLocalRandom", "SEED", "J"); visitor.visitMethodInsn(INVOKESTATIC, "org/apache/cassandra/simulator/systems/InterceptorOfSystemMethods$Global", "randomSeed", "()J", false); - visitor.visitMethodInsn(INVOKEVIRTUAL, "sun/misc/Unsafe", "putLong", "(Ljava/lang/Object;JJ)V", false); + + String unsafeClass = Utils.descriptorToClassName(unsafeDescriptor); + visitor.visitMethodInsn(INVOKEVIRTUAL, unsafeClass, "putLong", "(Ljava/lang/Object;JJ)V", false); visitor.visitFieldInsn(GETSTATIC, "java/util/concurrent/ThreadLocalRandom", unsafeFieldName, unsafeDescriptor); visitor.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", false); visitor.visitFieldInsn(GETSTATIC, "java/util/concurrent/ThreadLocalRandom", "PROBE", "J"); visitor.visitLdcInsn(0); - visitor.visitMethodInsn(INVOKEVIRTUAL, "sun/misc/Unsafe", "putInt", "(Ljava/lang/Object;JI)V", false); + visitor.visitMethodInsn(INVOKEVIRTUAL, unsafeClass, "putInt", "(Ljava/lang/Object;JI)V", false); visitor.visitInsn(RETURN); visitor.visitLabel(new Label()); visitor.visitMaxs(6, 1); diff --git a/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptClasses.java b/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptClasses.java index a57074db27..473cc27032 100644 --- a/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptClasses.java +++ b/test/simulator/asm/org/apache/cassandra/simulator/asm/InterceptClasses.java @@ -246,6 +246,7 @@ public class InterceptClasses implements BiFunction<String, byte[], byte[]> } ClassTransformer transformer = new ClassTransformer(api, internalName, flags, monitorDelayChance, new NemesisGenerator(api, internalName, nemesisChance), nemesisFieldSelector, hashcode, dependentTypes); + transformer.setUpdateVisibility(true); transformer.readAndTransform(input); if (!transformer.isTransformed()) diff --git a/test/simulator/asm/org/apache/cassandra/simulator/asm/Utils.java b/test/simulator/asm/org/apache/cassandra/simulator/asm/Utils.java index be2ef6c5d8..d710ffe417 100644 --- a/test/simulator/asm/org/apache/cassandra/simulator/asm/Utils.java +++ b/test/simulator/asm/org/apache/cassandra/simulator/asm/Utils.java @@ -287,4 +287,12 @@ public class Utils forEach.accept(descriptor.substring(i + 1, descriptor.length() - 1)); } } + + public static String descriptorToClassName(String desc) + { + // samples: "Ljdk/internal/misc/Unsafe;", "Lsun/misc/Unsafe;" + if (!(desc.startsWith("L") && desc.endsWith(";"))) + throw new IllegalArgumentException("Unable to parse descriptor: " + desc); + return desc.substring(1, desc.length() - 1); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
