Mercurial Hosting > luan
changeset 1400:221eedb0f54e
fix inner class gc bug
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 13 Sep 2019 05:05:51 -0600 |
parents | 38a1c1b4279a |
children | ef1620aa99cb |
files | src/luan/LuanClosure.java src/luan/LuanException.java src/luan/host/WebHandler.java src/luan/impl/LuanParser.java src/luan/lib/webserver/handlers/DomainHandler.java src/luan/modules/http/LuanDomainHandler.java src/luan/modules/http/LuanHandler.java |
diffstat | 7 files changed, 160 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/LuanClosure.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/LuanClosure.java Fri Sep 13 05:05:51 2019 -0600 @@ -8,9 +8,9 @@ public boolean javaOk; public final String sourceName; - public LuanClosure(Luan luan,int nUpValues,boolean javaOk,String sourceName) throws LuanException { + public LuanClosure(Luan luan,Pointer[] upValues,boolean javaOk,String sourceName) throws LuanException { super(luan); - this.upValues = new Pointer[nUpValues]; + this.upValues = upValues; this.javaOk = javaOk; this.sourceName = sourceName; } @@ -21,7 +21,7 @@ super.completeClone(dc,cloner); } - @Override public final Object call(Object[] args) throws LuanException { + @Override public final Object call(Object... args) throws LuanException { Luan luan = luan(); luan.push(this); try {
--- a/src/luan/LuanException.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/LuanException.java Fri Sep 13 05:05:51 2019 -0600 @@ -86,11 +86,23 @@ return list; } - public static String toString(StackTraceElement ste) { + public static String toLuanString(StackTraceElement ste) { + int line = ste.getLineNumber(); + String method = ste.getMethodName(); + boolean hasMethod = !method.equals("doCall"); + if( hasMethod ) { + int i = method.indexOf('$'); + if( i != -1 ) { + int n = Integer.parseInt(method.substring(i+1)); + line -= n; + method = method.substring(0,i); + if( method.equals("_") ) + hasMethod = false; + } + } StringBuilder sb = new StringBuilder(); - sb.append( ste.getFileName() ).append( " line " ).append( ste.getLineNumber() ); - String method = ste.getMethodName(); - if( !method.equals("doCall") ) + sb.append( ste.getFileName() ).append( " line " ).append( line ); + if( hasMethod ) sb.append( " in function '" ).append( method.substring(1) ).append( "'" ); return sb.toString(); } @@ -99,7 +111,7 @@ StringBuilder sb = new StringBuilder(); sb.append( getMessage() ); for( StackTraceElement ste : justLuan(getStackTrace()) ) { - sb.append( "\n\t" ).append( toString(ste) ); + sb.append( "\n\t" ).append( toLuanString(ste) ); } return sb; } @@ -111,13 +123,7 @@ sb.append( "\nCaused by: " ).append( getJavaStackTraceString(cause) ); return sb.toString(); } -/* - public static String currentSource() { - LuanException ex = new LuanException("currentSource"); - List<StackTraceElement> st = ex.justLuan(ex.getStackTrace()); - return st.isEmpty() ? null : st.get(0).getFileName(); - } -*/ + @Override public void printStackTrace(PrintStream s) { s.print("Luan: "); s.println(luanStackTrace());
--- a/src/luan/host/WebHandler.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/host/WebHandler.java Fri Sep 13 05:05:51 2019 -0600 @@ -24,7 +24,7 @@ private static final DomainHandler.Factory factory = new DomainHandler.Factory() { public Handler newHandler(String domain) { File dir = new File(sitesDir,domain); - if( !dir.exists() /* && !recover(dir) */ ) + if( !dir.exists() ) return null; String dirStr = dir.toString(); @@ -34,7 +34,7 @@ Luan luan = new Luan(); Log4j.newLoggerRepository(luan); initLuan(luan,dirStr,domain); - return new LuanHandler(luan); + return new LuanHandler(luan,domain); } }; @@ -59,26 +59,6 @@ return luanHandler.call_rpc(fnName,args); } -/* - private static boolean recover(File dir) { - File backups = new File(dir.getParentFile().getParentFile(),"backups"); - if( !backups.exists() ) - return false; - String name = dir.getName(); - File from = null; - for( File backup : backups.listFiles() ) { - File d = new File(backup,"current/"+name); - if( d.exists() && (from==null || from.lastModified() < d.lastModified()) ) - from = d; - } - if( from == null ) - return false; - if( !from.renameTo(dir) ) - throw new RuntimeException("couldn't rename "+from+" to "+dir); - logger.info("recovered "+name+" from "+from); - return true; - } -*/ private static void initLuan(Luan luan,String dir,String domain) { security(luan,dir); try {
--- a/src/luan/impl/LuanParser.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/impl/LuanParser.java Fri Sep 13 05:05:51 2019 -0600 @@ -89,11 +89,11 @@ this.i = i; this.value = value; } - +/* String init() { return "upValues[" + i + "] = " + value + "; "; } - +*/ @Override public Expr exp() { Expr exp = new Expr(Val.SINGLE,false); exp.add( new Object() { @@ -168,6 +168,10 @@ } + private static AtomicInteger classCounter = new AtomicInteger(); + private int innerCounter = 0; + private final List<Inner> inners = new ArrayList<Inner>(); + private Frame frame; private final Parser parser; private final Stmts top; @@ -225,36 +229,29 @@ return t; } - private Class newFnClass(Stmts stmt) { - return toFnClass( stmt, frame.upValueSymbols ); + private Expr newFnExp(Stmts stmt,String name) { + String className = "INNER" + ++innerCounter; + Inner inner = new Inner( stmt, name, className ); + inners.add(inner); + return inner.toInnerFnExp( frame.upValueSymbols ); +// return toFnExp( stmt, frame.upValueSymbols, name ); } - private Expr newFnExp(Stmts stmt,String name) { - return toFnExp( stmt, frame.upValueSymbols, name ); - } -/* - Class Expression() throws ParseException { - Spaces(); - parser.begin(); - Expr expr = ExprZ(); - if( expr != null && parser.endOfInput() ) { - top.add( "return " ); - top.addAll( expr ); - top.add( "; " ); - top.hasReturn = true; - return parser.success(newFnClass(top)); - } - return parser.failure(null); - } -*/ Class RequiredModule() throws ParseException { GetRequiredModule(); - return newFnClass(top); + String className = "EXP" + classCounter.incrementAndGet(); + String classCode = toFnString( top, frame.upValueSymbols, className, inners ); + try { + return LuanJavaCompiler.compile("luan.impl."+className,parser.sourceName,classCode); + } catch(ClassNotFoundException e) { + throw new RuntimeException(e); + } } String RequiredModuleSource() throws ParseException { GetRequiredModule(); - return toFnString( top, frame.upValueSymbols ); + String className = "EXP" + classCounter.incrementAndGet(); + return toFnString( top, frame.upValueSymbols, className, inners ); } void GetRequiredModule() throws ParseException { @@ -729,7 +726,7 @@ private Stmts ExpressionsStmt() throws ParseException { parser.begin(); - Expr exp = ExprZ(); + Expr exp = Expression(); if( exp != null && exp.isStmt ) { Stmts stmt = new Stmts(); if( exp.valType==Val.SINGLE ) { @@ -755,10 +752,10 @@ private Expr RequiredExpr() throws ParseException { parser.begin(); - return parser.success(required(ExprZ(),"Bad expression")); + return parser.success(required(Expression(),"Bad expression")); } - private Expr ExprZ() throws ParseException { + private Expr Expression() throws ParseException { return OrExpr(); } @@ -1175,7 +1172,7 @@ return parser.success(newExp); } parser.rollback(); - Expr exprs = ExprZ(); + Expr exprs = Expression(); if( exprs != null ) { return parser.success(exprs); } @@ -1381,7 +1378,7 @@ private boolean ExpList(List<Expr> builder) throws ParseException { parser.begin(); - Expr exp = ExprZ(); + Expr exp = Expression(); if( exp==null ) return parser.failure(); exp.addNewLines(); @@ -1872,8 +1869,6 @@ } - private static AtomicInteger classCounter = new AtomicInteger(); - private enum Val { SINGLE, ARRAY } private class Expr extends ParseList { @@ -1956,27 +1951,11 @@ boolean hasReturn = false; } - private Class toFnClass(Stmts stmts,List<UpSym> upValueSymbols) { - String className = "EXP" + classCounter.incrementAndGet(); - String classCode = toFnString(stmts,upValueSymbols,className); - try { -//System.out.println(parser.sourceName); -//System.out.println(classCode); - return LuanJavaCompiler.compile("luan.impl."+className,parser.sourceName,classCode); - } catch(ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - private String toFnString(Stmts stmts,List<UpSym> upValueSymbols) { - String className = "EXP" + classCounter.incrementAndGet(); - return toFnString(stmts,upValueSymbols,className); - } - - private String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className) { + private static String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className,List<Inner> inners) { if( !stmts.hasReturn ) stmts.add( "\nreturn LuanFunction.NOTHING;" ); - return "" + StringBuilder sb = new StringBuilder(); + sb.append( "" +"package luan.impl; " +"import luan.LuanClosure; " +"import luan.Luan; " @@ -1986,8 +1965,7 @@ +"public class " + className +" extends LuanClosure { " +"public "+className+"(Luan luan,boolean javaOk,String sourceName) throws LuanException { " - +"super(luan,"+upValueSymbols.size()+",javaOk,sourceName); " - + init(upValueSymbols) + +"super(luan,"+toUpValues(upValueSymbols)+",javaOk,sourceName); " +"} " +"@Override public Object doCall(Luan luan,Object[] args) throws LuanException { " @@ -1995,11 +1973,87 @@ +"Object t; " +"Object[] a; " + stmts - +"\n} " + +"\n}\n" + ); + for( Inner inner : inners ) { + sb.append( '\n' ); + sb.append( inner.toInnerFnString(lines(sb.toString())) + '\n' ); + } + sb.append( "" +"}\n" - ; + ); + return sb.toString(); } + private class Inner { + private final Stmts stmts; + private final String name; + private final String className; + private final int lines; + private final int endLine; + + Inner(Stmts stmts,String name,String className) { + this.stmts = stmts; + this.name = name; + this.className = className; + + stmts.addNewLines(); + if( !stmts.hasReturn ) + stmts.add( "return LuanFunction.NOTHING; " ); + this.lines = lines( stmts.toString() ); + this.endLine = lines( parser.textFrom(0) ); + } + + Expr toInnerFnExp(List<UpSym> upValueSymbols) { + StringBuilder sb = new StringBuilder(); + sb.append( + "new "+className+"(luan(),"+toUpValues(upValueSymbols)+",javaOk,sourceName)" + ); + for( int i=0; i<lines; i++ ) { + sb.append('\n'); + } + + Expr exp = new Expr(Val.SINGLE,false); + exp.add( sb.toString() ); + return exp; + } + + String toInnerFnString(int line) { + int diff = line + lines - endLine; + String name = this.name!=null ? this.name : ""; + name += "$" + diff; + //name += "_" + lines + "_" + endLine + "_" + line; + StringBuilder sb = new StringBuilder(); + sb.append( "" + +"private static class " + className +" extends LuanClosure { " + +className+"(Luan luan,Pointer[] upValues,boolean javaOk,String sourceName) throws LuanException { " + +"super(luan,upValues,javaOk,sourceName); " + +"} " + +"@Override public Object doCall(Luan luan,Object[] args) throws LuanException { " + +"return _" + name + "(luan,args); " + +"} " + +"private Object _" + name + "(Luan luan,Object[] args) throws LuanException { " + +"final Pointer[] parentUpValues = upValues; " + +"Object t; " + +"Object[] a; " + + stmts + +"} " + +"} " + ); + return sb.toString(); + } + } + + private static int lines(String s) { + int lines = 0; + final int n = s.length(); + for( int i=0; i<n; i++ ) { + if( s.charAt(i) == '\n' ) + lines++; + } + return lines; + } +/* private Expr toFnExp(Stmts stmt,List<UpSym> upValueSymbols,String name) { stmt.addNewLines(); if( !stmt.hasReturn ) @@ -2039,5 +2093,15 @@ } return sb.toString(); } +*/ + private static String toUpValues(List<UpSym> upValueSymbols) { + StringBuilder sb = new StringBuilder(); + sb.append( "new Pointer[]{ " ); + for( UpSym upSym : upValueSymbols ) { + sb.append( upSym.value + ", " ); + } + sb.append( "}" ); + return sb.toString(); + } }
--- a/src/luan/lib/webserver/handlers/DomainHandler.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/lib/webserver/handlers/DomainHandler.java Fri Sep 13 05:05:51 2019 -0600 @@ -3,6 +3,7 @@ import java.io.Closeable; import java.io.IOException; import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.lang.ref.SoftReference; import java.lang.ref.ReferenceQueue; import java.util.Map; @@ -31,7 +32,7 @@ private final ReferenceQueue<Ref> queue = new ReferenceQueue<Ref>(); - private class MyReference extends SoftReference<Ref> { + private class MyReference extends WeakReference<Ref> { private Handler handler; private MyReference(Ref r) {
--- a/src/luan/modules/http/LuanDomainHandler.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/modules/http/LuanDomainHandler.java Fri Sep 13 05:05:51 2019 -0600 @@ -24,7 +24,7 @@ @Override public Handler newHandler(String domain) { Luan luan = newLuan(domain); - return new LuanHandler(luan); + return new LuanHandler(luan,domain); } protected void newLoggerRepository(Luan luan) {
--- a/src/luan/modules/http/LuanHandler.java Wed Sep 11 16:28:38 2019 -0600 +++ b/src/luan/modules/http/LuanHandler.java Fri Sep 13 05:05:51 2019 -0600 @@ -13,6 +13,7 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import luan.lib.logging.Logger; +import luan.lib.logging.LoggerFactory; import luan.lib.webserver.Request; import luan.lib.webserver.Response; import luan.lib.webserver.Status; @@ -31,8 +32,11 @@ public final class LuanHandler implements Handler, Luan.OnClose { + private static final Logger sysLogger = LoggerFactory.getLogger(LuanHandler.class); + private final Luan luanInit; - private final Logger logger; + private final String domain; + private final Logger luanLogger; private final ReadWriteLock rwLock = new ReentrantReadWriteLock(); private final List<Reference<Closeable>> onClose = new ArrayList<Reference<Closeable>>(); private volatile Luan currentLuan; @@ -51,9 +55,10 @@ } } - public LuanHandler(Luan luanInit) { + public LuanHandler(Luan luanInit,String domain) { this.luanInit = luanInit; - this.logger = LuanLogger.getLogger(luanInit,LuanHandler.class.getName()); + this.domain = domain; + this.luanLogger = luanInit.getLogger(LuanHandler.class); try { LuanTable Http = (LuanTable)luanInit.require("luan:http/Http.luan"); if( Http.get("reset_luan") == null ) @@ -64,6 +69,11 @@ throw new RuntimeException(e); } currentLuan = newLuan(); + sysLogger.info("new "+domain); + } + + protected void finalize() throws Throwable { + sysLogger.info("gc "+domain); } private Luan newLuan() { @@ -78,7 +88,7 @@ } catch(LuanException e) { //e.printStackTrace(); String err = e.getLuanStackTraceString(); - logger.error(err); + luanLogger.error(err); } return luan; } @@ -107,7 +117,7 @@ return service(request,notFound); } catch(LuanException e) { String err = e.getLuanStackTraceString(); - logger.error(err+"\n"+request.rawHead.trim()+"\n"); + luanLogger.error(err+"\n"+request.rawHead.trim()+"\n"); String msg = "Internel Server Error\n\n" + err; return Response.errorResponse( Status.INTERNAL_SERVER_ERROR, msg ); } finally { @@ -130,7 +140,7 @@ try { c.close(); } catch(IOException e) { - logger.error(c.toString(),e); + luanLogger.error(c.toString(),e); } } }