MessageAsmMethodBoost优化

This commit is contained in:
redkale
2024-08-13 11:25:14 +08:00
parent f694b617cf
commit cb9b57a04c
7 changed files with 60 additions and 85 deletions

View File

@@ -153,7 +153,7 @@ public abstract class AsmMethodBoost<T> {
} }
protected MethodVisitor createMethodVisitor( protected MethodVisitor createMethodVisitor(
ClassWriter cw, Method method, AsmNewMethod newMethod, int newMethodAcc, AsmMethodBean methodBean) { ClassWriter cw, Method method, AsmNewMethod newMethod, AsmMethodBean methodBean) {
return new MethodDebugVisitor(cw.visitMethod( return new MethodDebugVisitor(cw.visitMethod(
getAcc(method, newMethod), getAcc(method, newMethod),
getNowMethodName(method, newMethod), getNowMethodName(method, newMethod),
@@ -162,7 +162,7 @@ public abstract class AsmMethodBoost<T> {
getMethodExceptions(method, methodBean))); getMethodExceptions(method, methodBean)));
} }
protected int getAcc(Method method, AsmNewMethod newMethod) { protected final int getAcc(Method method, AsmNewMethod newMethod) {
if (newMethod != null) { if (newMethod != null) {
return ACC_PRIVATE; return ACC_PRIVATE;
} }

View File

@@ -193,8 +193,9 @@ public class MethodDebugVisitor extends MethodVisitor {
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
visitor.visitLocalVariable(name, desc, signature, start, end, index); visitor.visitLocalVariable(name, desc, signature, start, end, index);
if (debug) { if (debug) {
System.out.println("mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", \"" + signature String s = signature == null ? null : ("\"" + signature + "\"");
+ "\", null, null, " + index + ");"); System.out.println(
"mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", " + s + ", null, null, " + index + ");");
} }
} }

View File

@@ -104,7 +104,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
final AsmMethodBean methodBean = getMethodBean(method); final AsmMethodBean methodBean = getMethodBean(method);
{ // 定义一个新方法调用 this.rsMethodName { // 定义一个新方法调用 this.rsMethodName
final String cacheDynDesc = Type.getDescriptor(DynForCached.class); final String cacheDynDesc = Type.getDescriptor(DynForCached.class);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, ACC_PRIVATE, methodBean); final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, methodBean);
// mv.setDebug(true); // mv.setDebug(true);
AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true); AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName); av.visit("dynField", dynFieldName);

View File

@@ -72,7 +72,7 @@ public class LockedAsmMethodBoost extends AsmMethodBoost {
{ // 定义一个新方法调用 this.rsMethodName { // 定义一个新方法调用 this.rsMethodName
final AsmMethodBean methodBean = getMethodBean(method); final AsmMethodBean methodBean = getMethodBean(method);
final String lockDynDesc = Type.getDescriptor(DynForLocked.class); final String lockDynDesc = Type.getDescriptor(DynForLocked.class);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, ACC_PRIVATE, methodBean); final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, methodBean);
// mv.setDebug(true); // mv.setDebug(true);
Label l0 = new Label(); Label l0 = new Label();
mv.visitLabel(l0); mv.visitLabel(l0);

View File

@@ -24,8 +24,6 @@ import org.redkale.mq.MessageConsumer;
@Repeatable(DynForMessaged.DynForMessageds.class) @Repeatable(DynForMessaged.DynForMessageds.class)
public @interface DynForMessaged { public @interface DynForMessaged {
String dynField();
Class<? extends MessageConsumer> consumer(); Class<? extends MessageConsumer> consumer();
@Inherited @Inherited

View File

@@ -4,7 +4,6 @@
package org.redkale.mq.spi; package org.redkale.mq.spi;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@@ -44,6 +43,7 @@ import static org.redkale.asm.Opcodes.POP;
import static org.redkale.asm.Opcodes.PUTFIELD; import static org.redkale.asm.Opcodes.PUTFIELD;
import static org.redkale.asm.Opcodes.RETURN; import static org.redkale.asm.Opcodes.RETURN;
import static org.redkale.asm.Opcodes.V11; import static org.redkale.asm.Opcodes.V11;
import org.redkale.convert.Convert;
import org.redkale.convert.ConvertFactory; import org.redkale.convert.ConvertFactory;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.mq.MessageConext; import org.redkale.mq.MessageConext;
@@ -101,9 +101,9 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
if (!LoadMode.matches(remote, messaged.mode())) { if (!LoadMode.matches(remote, messaged.mode())) {
return newMethod; return newMethod;
} }
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { if (Modifier.isStatic(method.getModifiers())) {
throw new RedkaleException( throw new RedkaleException(
"@" + Messaged.class.getSimpleName() + " cannot on final or static method, but on " + method); "@" + Messaged.class.getSimpleName() + " cannot on static method, but on " + method);
} }
if (Modifier.isProtected(method.getModifiers()) && Modifier.isFinal(method.getModifiers())) { if (Modifier.isProtected(method.getModifiers()) && Modifier.isFinal(method.getModifiers())) {
throw new RedkaleException( throw new RedkaleException(
@@ -138,16 +138,36 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
+ MessageConext.class.getSimpleName() + " parameter type, but on " + method); + MessageConext.class.getSimpleName() + " parameter type, but on " + method);
} }
} }
ConvertFactory factory = Convert convert = ConvertFactory.findConvert(messaged.convertType());
ConvertFactory.findConvert(messaged.convertType()).getFactory(); convert.getFactory().loadDecoder(messageType);
factory.loadDecoder(messageType); if (Modifier.isProtected(method.getModifiers())) {
createMessageMethod(cw, method, serviceImplClass, filterAnns, newMethod);
}
createInnerConsumer(cw, method, paramKind, TypeToken.typeToClass(messageType), messaged, newDynName, newMethod); createInnerConsumer(cw, method, paramKind, TypeToken.typeToClass(messageType), messaged, newDynName, newMethod);
return newMethod; return newMethod;
} }
private void createMessageMethod(
ClassWriter cw, Method method, Class serviceImplClass, List filterAnns, AsmNewMethod newMethod) {
final String serviceName = serviceImplClass.getName().replace('.', '/');
final AsmMethodBean methodBean = getMethodBean(method);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, methodBean);
visitRawAnnotation(method, newMethod, mv, Messaged.class, filterAnns);
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
List<Integer> insns = visitVarInsnParamTypes(mv, method, 0);
String methodDesc = org.redkale.asm.Type.getMethodDescriptor(method);
mv.visitMethodInsn(INVOKESPECIAL, serviceName, method.getName(), methodDesc, false);
visitInsnReturn(mv, method, l0, insns, methodBean);
int max = method.getParameterCount() + 1;
mv.visitMaxs(max, max);
mv.visitEnd();
}
// paramKind: 1:单个MessageType; 2: MessageConext & MessageType; 3: MessageType & MessageConext; // paramKind: 1:单个MessageType; 2: MessageConext & MessageType; 3: MessageType & MessageConext;
private void createInnerConsumer( private void createInnerConsumer(
ClassWriter parentCW, ClassWriter pcw,
Method method, Method method,
int paramKind, int paramKind,
Class msgType, Class msgType,
@@ -176,7 +196,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
genericMsgTypeDesc = methodSignature.substring(1, methodSignature.lastIndexOf(')')); // 获取()中的值 genericMsgTypeDesc = methodSignature.substring(1, methodSignature.lastIndexOf(')')); // 获取()中的值
} }
parentCW.visitInnerClass(innerFullName, newDynName, innerClassName, ACC_PUBLIC + ACC_STATIC); pcw.visitInnerClass(innerFullName, newDynName, innerClassName, ACC_PUBLIC + ACC_STATIC);
MethodVisitor mv; MethodVisitor mv;
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
@@ -339,55 +359,22 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
RedkaleClassLoader.putReflectionPublicConstructors(clazz, clzName); RedkaleClassLoader.putReflectionPublicConstructors(clazz, clzName);
AnnotationVisitor av2 = AnnotationVisitor av2 =
av1.visitAnnotation(null, org.redkale.asm.Type.getDescriptor(DynForMessaged.class)); av1.visitAnnotation(null, org.redkale.asm.Type.getDescriptor(DynForMessaged.class));
av2.visit("dynField", getFieldName(innerFullName));
av2.visit("consumer", org.redkale.asm.Type.getType("L" + innerFullName + ";")); av2.visit("consumer", org.redkale.asm.Type.getType("L" + innerFullName + ";"));
av2.visitEnd(); av2.visitEnd();
}); });
av1.visitEnd(); av1.visitEnd();
av0.visitEnd(); av0.visitEnd();
String consumerDesc = org.redkale.asm.Type.getDescriptor(MessageConsumer.class);
consumerBytes.forEach((innerFullName, bytes) -> {
FieldVisitor fv = cw.visitField(ACC_PRIVATE, getFieldName(innerFullName), consumerDesc, null, null);
fv.visitEnd();
});
} }
} }
@Override
public void doConstructorMethod(
DynBytesClassLoader classLoader,
ClassWriter cw,
MethodVisitor mv,
String newDynName,
String fieldPrefix,
boolean remote) {
if (remote || Utility.isEmpty(consumerBytes)) {
return;
}
String consumerDesc = org.redkale.asm.Type.getDescriptor(MessageConsumer.class);
consumerBytes.forEach((innerFullName, bytes) -> {
mv.visitVarInsn(ALOAD, 0);
mv.visitTypeInsn(NEW, innerFullName);
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, innerFullName, "<init>", "(L" + newDynName + ";)V", false);
mv.visitFieldInsn(PUTFIELD, newDynName, getFieldName(innerFullName), consumerDesc);
});
}
@Override @Override
public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, Object service) { public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, Object service) {
DynForMessaged[] dyns = service.getClass().getAnnotationsByType(DynForMessaged.class); DynForMessaged[] dyns = service.getClass().getAnnotationsByType(DynForMessaged.class);
if (Utility.isNotEmpty(dyns)) { if (Utility.isNotEmpty(dyns)) {
try { try {
for (DynForMessaged item : dyns) { for (DynForMessaged item : dyns) {
// Class<? extends MessageConsumer> clazz = item.value(); Class<? extends MessageConsumer> clazz = item.consumer();
// MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service); MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service);
String fieldName = item.dynField();
Field field = service.getClass().getDeclaredField(fieldName);
RedkaleClassLoader.putReflectionField(service.getClass().getName(), field);
field.setAccessible(true);
MessageConsumer consumer = (MessageConsumer) field.get(service);
messageEngine.addMessageConsumer(consumer); messageEngine.addMessageConsumer(consumer);
} }
} catch (Exception e) { } catch (Exception e) {
@@ -395,9 +382,4 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
} }
} }
} }
private String getFieldName(String innerFullName) {
String simpleClassName = innerFullName.substring(innerFullName.lastIndexOf('$') + 1);
return "_dyn" + simpleClassName;
}
} }

View File

@@ -486,7 +486,7 @@ public abstract class Sncp {
* 创建Service的本地模式Class * 创建Service的本地模式Class
* *
* @param <T> Service子类 * @param <T> Service子类
* @param classLoader ClassLoader * @param dynLoader DynBytesClassLoader
* @param name 资源名 * @param name 资源名
* @param serviceImplClass Service类 * @param serviceImplClass Service类
* @param methodBoost 方法扩展 * @param methodBoost 方法扩展
@@ -532,8 +532,9 @@ public abstract class Sncp {
} }
if (methodBoost == null) { // 加强动态时不能重复加载 if (methodBoost == null) { // 加强动态时不能重复加载
try { try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); final String newDynClass = newDynName.replace('/', '.');
return (Class<T>) (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz); Class clz = RedkaleClassLoader.findDynClass(newDynClass);
return (Class<T>) (clz == null ? dynLoader.loadClass(newDynClass) : clz);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
// do nothing // do nothing
} catch (Throwable t) { } catch (Throwable t) {
@@ -603,27 +604,18 @@ public abstract class Sncp {
} }
cw.visitEnd(); cw.visitEnd();
byte[] bytes = cw.toByteArray(); byte[] bytes = cw.toByteArray();
Class<?> newClazz = null; final String newDynClass = newDynName.replace('/', '.');
if (methodBoost != null) { Class<?> newClazz = dynLoader.loadClass(newDynClass, bytes);
try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); RedkaleClassLoader.putDynClass(newDynClass, bytes, newClazz);
newClazz = (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz); RedkaleClassLoader.putReflectionPublicClasses(newDynClass);
} catch (Throwable t) { RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynClass);
// do nothing
}
}
if (newClazz == null) {
newClazz = dynLoader.loadClass(newDynName.replace('/', '.'), bytes);
}
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
RedkaleClassLoader.putReflectionPublicClasses(newDynName.replace('/', '.'));
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
try { try {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); RedkaleClassLoader.putReflectionField(newDynClass, c);
c = newClazz.getDeclaredField(FIELDPREFIX + "_mq"); c = newClazz.getDeclaredField(FIELDPREFIX + "_mq");
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); RedkaleClassLoader.putReflectionField(newDynClass, c);
} catch (Exception e) { } catch (Exception e) {
// do nothing // do nothing
} }
@@ -965,8 +957,9 @@ public abstract class Sncp {
newDynName += "_" + (normal ? name : hash(name)); newDynName += "_" + (normal ? name : hash(name));
} }
try { try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); final String newDynClass = newDynName.replace('/', '.');
Class newClazz = clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz; Class clz = RedkaleClassLoader.findDynClass(newDynClass);
Class newClazz = clz == null ? dynLoader.loadClass(newDynClass) : clz;
T service = (T) newClazz.getDeclaredConstructor().newInstance(); T service = (T) newClazz.getDeclaredConstructor().newInstance();
{ {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
@@ -1246,29 +1239,30 @@ public abstract class Sncp {
} }
cw.visitEnd(); cw.visitEnd();
byte[] bytes = cw.toByteArray(); byte[] bytes = cw.toByteArray();
Class<?> newClazz = dynLoader.loadClass(newDynName.replace('/', '.'), bytes); final String newDynClass = newDynName.replace('/', '.');
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); Class<?> newClazz = dynLoader.loadClass(newDynClass, bytes);
RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynName.replace('/', '.')); RedkaleClassLoader.putDynClass(newDynClass, bytes, newClazz);
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynClass);
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynClass);
try { try {
T service = (T) newClazz.getDeclaredConstructor().newInstance(); T service = (T) newClazz.getDeclaredConstructor().newInstance();
{ {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
c.setAccessible(true); c.setAccessible(true);
c.set(service, conf); c.set(service, conf);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); RedkaleClassLoader.putReflectionField(newDynClass, c);
} }
{ {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_mq"); Field c = newClazz.getDeclaredField(FIELDPREFIX + "_mq");
c.setAccessible(true); c.setAccessible(true);
c.set(service, agent == null ? null : agent.getName()); c.set(service, agent == null ? null : agent.getName());
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); RedkaleClassLoader.putReflectionField(newDynClass, c);
} }
{ {
Field c = newClazz.getDeclaredField(FIELDPREFIX + "_sncp"); Field c = newClazz.getDeclaredField(FIELDPREFIX + "_sncp");
c.setAccessible(true); c.setAccessible(true);
c.set(service, info); c.set(service, info);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); RedkaleClassLoader.putReflectionField(newDynClass, c);
} }
if (methodBoost != null) { if (methodBoost != null) {
// 必须用servcie的ClassLoader 因为service是动态ClassLoader会与doMethod里的动态ClassLoader不一致 // 必须用servcie的ClassLoader 因为service是动态ClassLoader会与doMethod里的动态ClassLoader不一致