]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java
Simupedia tuning
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / runtime / RuntimeModule.java
index 5ae73c41240700f44662e1b70f6851487752b290..2e35427cdcda7014e7bacd12cb10c6c7de9312fa 100644 (file)
@@ -3,9 +3,15 @@ package org.simantics.scl.compiler.runtime;
 import java.io.OutputStreamWriter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.commons.ClassRemapper;
+import org.objectweb.asm.commons.Remapper;
 import org.simantics.scl.compiler.constants.Constant;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
@@ -16,6 +22,7 @@ import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 import org.simantics.scl.compiler.internal.decompilation.DecompilerFactory;
 import org.simantics.scl.compiler.internal.decompilation.IDecompiler;
+import org.simantics.scl.compiler.module.ConcreteModule;
 import org.simantics.scl.compiler.module.Module;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.top.ValueNotFound;
@@ -28,7 +35,7 @@ public class RuntimeModule {
     private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeModule.class);
     
     public static final boolean VALIDATE_CLASS_NAMES = true;
-    public static final boolean TRACE_CLASS_CREATION = false;
+    public static final boolean TRACE_CLASS_CREATION = true;
     
     Module module;
     ModuleClassLoader classLoader;
@@ -123,7 +130,8 @@ public class RuntimeModule {
         }
         
         private Class<?> getClass(String name) throws ClassNotFoundException {
-            //System.out.println("getClass " + name);
+            
+            System.out.println(moduleName + ":getClass " + name);
             
             // If the class is not generated from SCL, use parent class loader
             if(!name.startsWith(SCL_PACKAGE_PREFIX)) {
@@ -160,6 +168,22 @@ public class RuntimeModule {
             }
         }
         
+//        protected Class<?> loadClass(String name, boolean resolve)
+//                throws ClassNotFoundException
+//            {
+//                synchronized (getClassLoadingLock(name)) {
+//                    // First, check if the class has already been loaded
+//                    Class<?> c = findLoadedClass(name);
+//                    if (c == null) {
+//                        c = getClass(name);
+//                    }
+//                    if (resolve) {
+//                        resolveClass(c);
+//                    }
+//                    return c;
+//                }
+//            }
+        
         @Override
         public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
             Class<?> clazz = getClass(name);
@@ -168,6 +192,11 @@ public class RuntimeModule {
             return clazz;
         }
         
+        @Override
+        public Class<?> loadClass(String name) throws ClassNotFoundException {
+            return super.loadClass(name);
+        }
+        
         public Module getModule(String moduleName) {
             //System.out.println("ModuleClassLoader.getModule(" + moduleName + ")");
             if(moduleName.equals(this.moduleName))
@@ -285,4 +314,105 @@ public class RuntimeModule {
         classLoader = null;
         classBuilder = null;
     }
+    
+    public class ClassNameRecordingRemapper extends Remapper {
+
+        private final Set<? super String> classNames;
+
+        public ClassNameRecordingRemapper(Set<? super String> classNames) {
+            this.classNames = classNames;
+        }
+        
+        @Override
+        public String map(String typeName) {
+            classNames.add(typeName);
+            return super.map(typeName);
+        }
+        
+        @Override
+        public String mapDesc(String desc) {
+            //classNames.add(desc);
+            return super.mapDesc(desc);
+        }
+        @Override
+        public String mapFieldName(String owner, String name, String desc) {
+            return super.mapFieldName(owner, name, desc);
+        }
+        @Override
+        public String mapInvokeDynamicMethodName(String name, String desc) {
+            // TODO Auto-generated method stub
+            return super.mapInvokeDynamicMethodName(name, desc);
+        }
+        @Override
+        public String mapMethodDesc(String desc) {
+            //classNames.add(desc);
+            return super.mapMethodDesc(desc);
+        }
+        @Override
+        public String mapMethodName(String owner, String name, String desc) {
+            // TODO Auto-generated method stub
+            return super.mapMethodName(owner, name, desc);
+        }
+        @Override
+        public String mapSignature(String signature, boolean typeSignature) {
+            //classNames.add(signature);
+            return super.mapSignature(signature, typeSignature);
+        }
+        @Override
+        public String mapType(String type) {
+            classNames.add(type);
+            return super.mapType(type);
+        }
+        @Override
+        public String[] mapTypes(String[] types) {
+            for(String type : types)
+                classNames.add(type);
+            // TODO Auto-generated method stub
+            return super.mapTypes(types);
+        }
+        @Override
+        public Object mapValue(Object value) {
+            //classNames.add(value.toString());
+            // TODO Auto-generated method stub
+            return super.mapValue(value);
+        }
+    }
+    
+    public Set<String> classReferences(String className) {
+        try {
+            HashSet<String> referencedClasses = new HashSet<>();
+            ClassNameRecordingRemapper m = new ClassNameRecordingRemapper(referencedClasses);
+            ClassReader cr = new ClassReader(module.getClass(className));
+            int ASM5 = 5 << 16 | 0 << 8 | 0;
+            //TraceClassVisitor tcv = new TraceClassVisitor(null, new PrintWriter(System.err));
+            ClassVisitor cv1 = new ClassVisitor(ASM5) {};
+            ClassVisitor cv = new ClassRemapper(cv1, m);
+            cr.accept(cv, ClassReader.SKIP_DEBUG);
+            System.err.println(className + " refs: " + referencedClasses);
+            return referencedClasses;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+    
+    public void loadReferences() {
+        ConcreteModule cm = (ConcreteModule)module;
+        try {
+            for(String className : cm.getClasses().keySet()) {
+                Set<String> refs = classReferences(className);
+                for(String s : refs) {
+                    String internalName = s.replace('/', '.');
+                    try {
+                        classLoader.loadClass(internalName);
+                    } catch (Throwable e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+    }
+
 }
\ No newline at end of file