修复ASM的BIPUSH问题,RestWebSocket增加maxconns文件配置功能

This commit is contained in:
Redkale
2017-11-10 11:01:58 +08:00
parent 2c13224fcc
commit 9af8c863b1
7 changed files with 130 additions and 90 deletions

View File

@@ -304,32 +304,28 @@ public final class Rest {
fv.visitEnd();
}
}
{ //构造函数
{ //_DynWebSocketServlet构造函数
mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "()V", false);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(Type.getObjectType(newDynName + "$" + newDynWebSokcetSimpleName + "Message"));
mv.visitFieldInsn(PUTFIELD, newDynName, "messageTextType", "Ljava/lang/reflect/Type;");
mv.visitVarInsn(ALOAD, 0);
if (rws.liveinterval() < 6) {
mv.visitInsn(ICONST_0 + rws.liveinterval());
} else {
mv.visitIntInsn(BIPUSH, rws.liveinterval());
}
pushInt(mv, rws.liveinterval());
mv.visitFieldInsn(PUTFIELD, newDynName, "liveinterval", "I");
mv.visitVarInsn(ALOAD, 0);
if (rws.maxconns()< 6) {
mv.visitInsn(ICONST_0 + rws.maxconns());
} else {
mv.visitIntInsn(BIPUSH, rws.maxconns());
}
pushInt(mv, rws.maxconns());
mv.visitFieldInsn(PUTFIELD, newDynName, "maxconns", "I");
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(rws.single() ? ICONST_1 : ICONST_0);
mv.visitFieldInsn(PUTFIELD, newDynName, "single", "Z");
mv.visitInsn(RETURN);
mv.visitMaxs(2, 1);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
{ //createWebSocket 方法
@@ -1295,11 +1291,7 @@ public final class Rest {
} else {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, REST_PARAMTYPES_FIELD_NAME, "[[Ljava/lang/reflect/Type;");
if (entry.methodidx <= 5) { //方法下标
mv.visitInsn(ICONST_0 + entry.methodidx);
} else {
mv.visitIntInsn(BIPUSH, entry.methodidx);
}
pushInt(mv, entry.methodidx);//方法下标
mv.visitInsn(AALOAD);
int paramidx = 0;
for (int i = 0; i < params.length; i++) {
@@ -1308,11 +1300,7 @@ public final class Rest {
break;
}
}
if (paramidx <= 5) { //参数下标
mv.visitInsn(ICONST_0 + paramidx);
} else {
mv.visitIntInsn(BIPUSH, paramidx);
}
pushInt(mv, paramidx); //参数下标
mv.visitInsn(AALOAD);
}
mv.visitLdcInsn(pname);
@@ -1677,6 +1665,30 @@ public final class Rest {
return true;
}
private static void pushInt(AsmMethodVisitor mv, int num) {
if (num < 6) {
mv.visitInsn(ICONST_0 + num);
} else if (num <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, num);
} else if (num <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, num);
} else {
mv.visitLdcInsn(num);
}
}
private static void pushInt(MethodVisitor mv, int num) {
if (num < 6) {
mv.visitInsn(ICONST_0 + num);
} else if (num <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, num);
} else if (num <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, num);
} else {
mv.visitLdcInsn(num);
}
}
private static class RestClassLoader extends ClassLoader {
public RestClassLoader(ClassLoader parent) {

View File

@@ -15,6 +15,7 @@ import java.util.logging.*;
import java.util.stream.*;
import org.redkale.convert.Convert;
import static org.redkale.net.http.WebSocket.RETCODE_GROUP_EMPTY;
import static org.redkale.net.http.WebSocketServlet.*;
import org.redkale.util.*;
/**
@@ -85,23 +86,24 @@ public class WebSocketEngine {
}
void init(AnyValue conf) {
final int interval = conf == null ? (liveinterval < 0 ? DEFAILT_LIVEINTERVAL : liveinterval) : conf.getIntValue("liveinterval", (liveinterval < 0 ? DEFAILT_LIVEINTERVAL : liveinterval));
if (interval <= 0) return;
AnyValue props = conf;
if (conf != null && conf.getAnyValue("properties") != null) props = conf.getAnyValue("properties");
this.liveinterval = props == null ? (liveinterval < 0 ? DEFAILT_LIVEINTERVAL : liveinterval) : props.getIntValue(WEBPARAM__LIVEINTERVAL, (liveinterval < 0 ? DEFAILT_LIVEINTERVAL : liveinterval));
if (liveinterval <= 0) return;
this.maxconns = props == null ? this.maxconns : props.getIntValue(WEBPARAM__MAXCONNS, this.maxconns);
if (scheduler != null) return;
this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
final Thread t = new Thread(r, engineid + "-WebSocket-LiveInterval-Thread");
t.setDaemon(true);
return t;
});
long delay = (interval - System.currentTimeMillis() / 1000 % interval) + index * 5;
final int intervalms = interval * 1000;
long delay = (liveinterval - System.currentTimeMillis() / 1000 % liveinterval) + index * 5;
final int intervalms = liveinterval * 1000;
scheduler.scheduleWithFixedDelay(() -> {
long now = System.currentTimeMillis();
getLocalWebSockets().stream().filter(x -> (now - x.getLastSendTime()) > intervalms).forEach(x -> x.sendPing());
}, delay, interval, TimeUnit.SECONDS);
if (logger.isLoggable(Level.FINE)) {
logger.fine(this.getClass().getSimpleName() + "(" + engineid + ")" + " start keeplive(delay:" + delay + ", maxconns:" + maxconns + ", interval:" + interval + "s) scheduler executor");
}
}, delay, liveinterval, TimeUnit.SECONDS);
logger.finest(this.getClass().getSimpleName() + "(" + engineid + ")" + " start keeplive(delay:" + delay + ", maxconns:" + maxconns + ", interval:" + liveinterval + "s) scheduler executor");
}
void destroy(AnyValue conf) {

View File

@@ -45,6 +45,9 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl
@Comment("WebScoket服务器给客户端进行ping操作的间隔时间, 单位: 秒")
public static final String WEBPARAM__LIVEINTERVAL = "liveinterval";
@Comment("WebScoket服务器最大连接数为0表示无限制")
public static final String WEBPARAM__MAXCONNS = "maxconns";
@Comment("WebScoket服务器给客户端进行ping操作的默认间隔时间, 单位: 秒")
public static final int DEFAILT_LIVEINTERVAL = 15;
@@ -107,6 +110,7 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl
this.node = new WebSocketNodeService();
if (logger.isLoggable(Level.WARNING)) logger.warning("Not found WebSocketNode, create a default value for " + getClass().getName());
}
//存在WebSocketServlet则此WebSocketNode必须是本地模式Service
this.node.localEngine = new WebSocketEngine("WebSocketEngine-" + addr.getHostString() + ":" + addr.getPort() + "-[" + resourceName() + "]", this.single, context, liveinterval, maxconns, this.node, this.sendConvert, logger);
this.node.init(conf);

View File

@@ -528,16 +528,8 @@ public abstract class Sncp {
mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
final int preparams = 3; //调用selfrunnable之前的参数个数; _client
if (index <= 5) { //第几个 SncpAction
mv.visitInsn(ICONST_0 + index);
} else {
mv.visitIntInsn(BIPUSH, index);
}
if (paramtypes.length + preparams <= 5) { //参数总数量
mv.visitInsn(ICONST_0 + paramtypes.length + preparams);
} else {
mv.visitIntInsn(BIPUSH, paramtypes.length + preparams);
}
pushInt(mv, index); //第几个 SncpAction
pushInt(mv, paramtypes.length + preparams); //参数总数量
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
@@ -564,11 +556,7 @@ public abstract class Sncp {
final Class pt = paramtypes[j];
mv.visitInsn(DUP);
insn++;
if (j <= 2) {
mv.visitInsn(ICONST_0 + j + 3);
} else {
mv.visitIntInsn(BIPUSH, j + 3);
}
pushInt(mv, j + 3);
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
@@ -596,16 +584,8 @@ public abstract class Sncp {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
if (index <= 5) { //第几个 SncpAction
mv.visitInsn(ICONST_0 + index);
} else {
mv.visitIntInsn(BIPUSH, index);
}
if (paramtypes.length + preparams <= 5) { //参数总数量
mv.visitInsn(ICONST_0 + paramtypes.length + preparams);
} else {
mv.visitIntInsn(BIPUSH, paramtypes.length + preparams);
}
pushInt(mv, index); //第几个 SncpAction
pushInt(mv, paramtypes.length + preparams); //参数总数量
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
@@ -632,11 +612,7 @@ public abstract class Sncp {
final Class pt = paramtypes[j];
mv.visitInsn(DUP);
insn++;
if (j <= 2) {
mv.visitInsn(ICONST_0 + j + 3);
} else {
mv.visitIntInsn(BIPUSH, j + 3);
}
pushInt(mv, j + 3);
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
@@ -1011,19 +987,11 @@ public abstract class Sncp {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
if (index <= 5) {
mv.visitInsn(ICONST_0 + index);
} else {
mv.visitIntInsn(BIPUSH, index);
}
pushInt(mv, index);
{ //传参数
int paramlen = entry.paramTypes.length;
if (paramlen <= 5) {
mv.visitInsn(ICONST_0 + paramlen);
} else {
mv.visitIntInsn(BIPUSH, paramlen);
}
pushInt(mv, paramlen);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
java.lang.reflect.Type[] paramtypes = entry.paramTypes;
int insn = 0;
@@ -1031,11 +999,7 @@ public abstract class Sncp {
final java.lang.reflect.Type pt = paramtypes[j];
mv.visitInsn(DUP);
insn++;
if (j <= 5) {
mv.visitInsn(ICONST_0 + j);
} else {
mv.visitIntInsn(BIPUSH, j);
}
pushInt(mv, j);
if (pt instanceof Class && ((Class) pt).isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
@@ -1118,4 +1082,28 @@ public abstract class Sncp {
}
}
private static void pushInt(AsmMethodVisitor mv, int num) {
if (num < 6) {
mv.visitInsn(ICONST_0 + num);
} else if (num <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, num);
} else if (num <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, num);
} else {
mv.visitLdcInsn(num);
}
}
private static void pushInt(MethodVisitor mv, int num) {
if (num < 6) {
mv.visitInsn(ICONST_0 + num);
} else if (num <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, num);
} else if (num <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, num);
} else {
mv.visitLdcInsn(num);
}
}
}

View File

@@ -384,10 +384,15 @@ public final class SncpDynServlet extends SncpServlet {
mv.visitFieldInsn(GETFIELD, newDynName, "convert", Type.getDescriptor(BsonConvert.class));
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;");
if (iconst > ICONST_5) {
mv.visitIntInsn(BIPUSH, intconst);
if (iconst < 6) {
mv.visitInsn(ICONST_0 + iconst);
} else if (iconst <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, iconst);
} else if (iconst <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, iconst);
} else {
mv.visitInsn(iconst); //
mv.visitLdcInsn(iconst);
}
mv.visitInsn(AALOAD);
mv.visitVarInsn(ALOAD, 1);
@@ -433,21 +438,30 @@ public final class SncpDynServlet extends SncpServlet {
}
if (boolReturnTypeFuture || handlerFuncIndex >= 0) { //调用SncpAsyncHandler.setParams(Object... params)
mv.visitVarInsn(ALOAD, 3);
if (paramClasses.length > 5) {
if (paramClasses.length < 6) {
mv.visitInsn(ICONST_0 + paramClasses.length);
} else if (paramClasses.length <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, paramClasses.length);
} else if (paramClasses.length <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, paramClasses.length);
} else {
mv.visitInsn(paramClasses.length + ICONST_0);
mv.visitLdcInsn(paramClasses.length);
}
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
int insn = 3; //action的参数个数
for (int j = 0; j < paramClasses.length; j++) {
final Class pt = paramClasses[j];
mv.visitInsn(DUP);
insn++;
if (j <= 5) {
if (j < 6) {
mv.visitInsn(ICONST_0 + j);
} else {
} else if (j <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, j);
} else if (j <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, j);
} else {
mv.visitLdcInsn(j);
}
if (pt.isPrimitive()) {
if (pt == long.class) {
@@ -499,10 +513,14 @@ public final class SncpDynServlet extends SncpServlet {
//------------------------- _callParameter 方法 --------------------------------
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
if (paramClasses.length <= 5) { //参数总数量
if (paramClasses.length < 6) { //参数总数量
mv.visitInsn(ICONST_0 + paramClasses.length);
} else {
} else if (paramClasses.length <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, paramClasses.length);
} else if (paramClasses.length <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, paramClasses.length);
} else {
mv.visitLdcInsn(paramClasses.length);
}
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
int insn = 3;//action的参数个数
@@ -510,10 +528,14 @@ public final class SncpDynServlet extends SncpServlet {
final Class pt = paramClasses[j];
mv.visitInsn(DUP);
insn++;
if (j <= 5) {
if (j < 6) {
mv.visitInsn(ICONST_0 + j);
} else {
} else if (j <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, j);
} else if (j <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, j);
} else {
mv.visitLdcInsn(j);
}
if (pt.isPrimitive()) {
if (pt == long.class) {

View File

@@ -84,7 +84,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
public void init(AnyValue conf) {
if (this.convert == null) this.convert = this.defaultConvert;
final CacheMemorySource self = this;
AnyValue prop = conf == null ? null : conf.getAnyValue("property");
AnyValue prop = conf == null ? null : conf.getAnyValue("properties");
if (prop != null) {
String storeValueStr = prop.getValue("value-type");
if (storeValueStr != null) {

View File

@@ -351,8 +351,12 @@ public interface Creator<T> {
mv.visitVarInsn(ALOAD, 1);
if (i < 6) {
mv.visitInsn(iconsts[i]);
} else {
} else if (i <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, i);
} else if (i <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, i);
} else {
mv.visitLdcInsn(i);
}
mv.visitInsn(AALOAD);
Label lab = new Label();
@@ -360,8 +364,12 @@ public interface Creator<T> {
mv.visitVarInsn(ALOAD, 1);
if (i < 6) {
mv.visitInsn(iconsts[i]);
} else {
} else if (i <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, i);
} else if (i <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, i);
} else {
mv.visitLdcInsn(i);
}
if (pt == int.class) {
mv.visitInsn(ICONST_0);
@@ -399,8 +407,12 @@ public interface Creator<T> {
mv.visitVarInsn(ALOAD, 1);
if (i < 6) {
mv.visitInsn(iconsts[i]);
} else {
} else if (i <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, i);
} else if (i <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, i);
} else {
mv.visitLdcInsn(i);
}
mv.visitInsn(AALOAD);
final Class ct = constructorParameters[i].getValue();