Revision: 4695
          http://sourceforge.net/p/vexi/code/4695
Author:   mkpg2
Date:     2014-05-10 14:21:51 +0000 (Sat, 10 May 2014)
Log Message:
-----------
Devl Memory Mode. 
- show trapholders as well as objects (potential alternative source of leak)
- improve leak path formatting significantly
-- removed majority of unnecessary java noise in leak path trace
-- show variable names in leak path trace

Modified Paths:
--------------
    branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/JSUX.java
    
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/RTScopeInfo.java
    
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/ScopeInfoManager.java
    
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/GCUtil.java
    
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/Memory.java
    
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memoryhist/MemoryHist.java
    branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp
    branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Instr.java
    branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java
    
branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/parse/Parser.java
    branches/vexi3/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp

Modified: 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/JSUX.java
===================================================================
--- branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/JSUX.java   
2014-05-10 14:07:32 UTC (rev 4694)
+++ branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/JSUX.java   
2014-05-10 14:21:51 UTC (rev 4695)
@@ -10,4 +10,18 @@
           }
           return i;
        }
+       
+       
+       static public Integer scopeLookup(Scope scope, Object var){
+               try{
+                       for(int i=scope.base+scope.vars.length-1; i>=0; i--){
+                               if(var==scope.get(i)){
+                                       return i;
+                               }
+                       }
+               }catch(JSExn e){
+                       throw new Error(e);
+               }
+               return null;
+       }
 }

Modified: 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/RTScopeInfo.java
===================================================================
--- 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/RTScopeInfo.java
    2014-05-10 14:07:32 UTC (rev 4694)
+++ 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/RTScopeInfo.java
    2014-05-10 14:21:51 UTC (rev 4695)
@@ -12,9 +12,9 @@
        
        static public class Map{
        /** Scope to RuntimeScopeInfo*/
-       static private HashMap scopeToRTSI = new HashMap(10);
+       static private java.util.Map scopeToRTSI = new HashMap(10);
        /*<String,ScopeInfo>*/
-       static private HashMap scopeInfos = new HashMap();
+       static private java.util.Map<String,ScopeInfo> scopeInfos = new 
HashMap();
        
        
 
@@ -44,7 +44,9 @@
                        return (ScopeInfo) scopeInfos.get(sikey);
        }
 
-
+       static public ScopeInfo getScopeInfo(JSFunction func) {
+                       return scopeInfos.get(sikey(func.f, 0));
+               }
     }
 
        RTScopeInfo(Function f,  int pc){

Modified: 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/ScopeInfoManager.java
===================================================================
--- 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/ScopeInfoManager.java
       2014-05-10 14:07:32 UTC (rev 4694)
+++ 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/ibex/js/ScopeInfoManager.java
       2014-05-10 14:21:51 UTC (rev 4695)
@@ -1,6 +1,7 @@
 package org.ibex.js;
 
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.Vector;
 
 import org.ibex.js.parse.ByteCodes;
@@ -276,21 +277,21 @@
        }*/
        
        
-       
-       
        // Returns key (name) from value (scopeslot)
-       static String reverseLookupScopeInfo(ScopeInfo si, int slot){
-//             Iterator I = si.mapping.keySet().iterator();
-//             while(I.hasNext()){
-//                     
-//                     String vn = (String) I.next();
-//                     ScopeEntry entry = (ScopeEntry) si.mapping.get(vn);
-//                     if(entry.slot.i == slot){
-//                             return  vn ;
-//                     }
-//             }
-//             return "? (" + slot + ")";
-               return "? (Lookip not currently supported)";
+       static public String reverseLookupScopeInfo(ScopeInfo si, int slot){
+               while(si!=null){
+                       Iterator I = si.mapping.keySet().iterator();
+                       while(I.hasNext()){
+                               
+                               String vn = (String) I.next();
+                               ScopeEntry entry = (ScopeEntry) 
si.mapping.get(vn);
+                               if(((JSNumber)entry.slot).toInt32() == slot){
+                                       return  vn ;
+                               }
+                       }
+                       si  = si.parent;                         
+               }
+               return "? (" + slot + ")";
        }
        
        // Get previous NEWSCOPE (scope corresponding to pc) 

Modified: 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/GCUtil.java
===================================================================
--- 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/GCUtil.java
  2014-05-10 14:07:32 UTC (rev 4694)
+++ 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/GCUtil.java
  2014-05-10 14:21:51 UTC (rev 4695)
@@ -20,26 +20,23 @@
 import java.util.*;
 
 import org.ibex.js.*;
+import org.ibex.js.JS.TrapHolder;
+import org.ibex.js.parse.Parser.ScopeInfo;
+import org.vexi.core.Box;
+import org.vexi.util.BasicTree;
 import org.vexi.util.Log;
 import org.netbeans.insane.scanner.*;
 /**
  * 
  */
 public abstract class GCUtil {
-    
-    
-    /** Assert GC. Tries to GC ref's referent.
-     * @param text the text to show when test fails.
-     * @param ref the referent to object that
-     * should be GCed
-     */
-    public static void assertGC(String text, java.lang.ref.Reference ref) {
-        Log.warn("GCUtil", "Making sure of GC, this may take a while ..."); 
+    static public boolean ensurecGC(java.lang.ref.Reference ref){
+       Log.warn("GCUtil", "Making sure of GC, this may take a while ..."); 
        ArrayList alloc = new ArrayList ();
         int size = 100000;
         for (int i = 0; i < 50; i++) {
-            if (ref.get() == null) {
-                return;
+            if (ref!=null && ref.get() == null) {
+                return true;
             }
             System.gc();
             System.runFinalization();
@@ -56,9 +53,20 @@
             }
         }
         alloc = null;
-        Log.warn("GCUtil", "Reference not GC'd. Processing heap now, this may 
also take a while ..."); 
-        throw new AssertionError(text + ":\n" + findRefsFromRoot(ref.get()));
+        return false;
     }
+    
+    /** Assert GC. Tries to GC ref's referent.
+     * @param text the text to show when test fails.
+     * @param ref the referent to object that
+     * should be GCed
+     */
+    public static void assertGC(String text, java.lang.ref.Reference ref) {
+       if(!ensurecGC(ref)){
+            Log.warn("GCUtil", "Reference not GC'd. Processing heap now, this 
may also take a while ..."); 
+            throw new AssertionError(text + ":\n" + 
findRefsFromRoot(ref.get()));              
+       }
+    }
 
     private static String findRefsFromRoot(final Object target) {
         final Map objects = new IdentityHashMap();
@@ -105,28 +113,110 @@
             return "Not found!!!";
         }
     }
-        /** BFS scan of incomming refs*/
-    private static String  findRoots(Map objects, Object obj) {
-        class PathElement {
-            private Entry item;
-            private PathElement next; 
-            public PathElement(Entry item, PathElement next) {
-                this.item = item;
-                this.next = next;
-            }
-            
-            public Entry getItem() {
-                return item;
-            }
-            public String toString() {
-                if (next == null) {
-                    return item.toString();
-                } else {
-                    return item.toString() + "->\n" + next.toString();
-                }
-            }
+   
+    
+    
+    static class PathElement {
+        Entry entry;
+        PathElement next; 
+        public PathElement(Entry entry, PathElement next) {
+            this.entry = entry;
+            this.next = next;
         }
+        public Object getObject() {
+            return entry.get();
+        }
+        public Entry getItem() {
+            return entry;
+        }
+        public String toString() {
+            return format(this);
+        }
+    }
+    
+    static private String objectClass(Object obj){
+       if(obj instanceof JS.TrapHolder){
+               return "(TrapHolder)";                  
+       }else if(obj instanceof JS){
+               return "(JS)";
+       }else{
+               return "(Java)";
+       }
+    }
+    
+    static private String formatInner(Object obj){
+       if(obj instanceof JS.TrapHolder){
+               JS.TrapHolder th = (JS.TrapHolder)obj;
+               return format(th.target())+" . "+th.key()+" ++= 
"+format(th.function());                        
+       }else if(obj instanceof JS){
+               JS js = (JS)obj;
+               try {
+                               return JSON.marshal(js).coerceToString();
+                       } catch (JSExn e) {
+                               return obj.toString() + " (Could not stringify: 
"+e.getMessage()+")";
+                       }
+       }else{
+               return obj.toString();
+       }
+    }
+    
+    static private String format(Object obj){
+       String r = "";
+       if(Memory.get(obj)!=null)
+               r+= Memory.get(obj).firstLine() + ":"; // JS object
+       r+= formatInner(obj);
+        return r;
+    }
+    
+    
+    static public String formatLine(PathElement e){
+       String r = "\n"+objectClass(e.getObject())+" "+format(e.getObject());
+       if(e.next!=null){
+               PathElement next = e.next;
+               // UGLY this is unavoidably implementation specific, 
+               // and may break if the JS.Obj implementation is changed
+               if(e.next.next!=null && e.next.next.next!=null && 
e.next.next.next.next!=null && 
+                          e.getObject() instanceof JS.Obj && 
+                          e.next.getObject() instanceof Map && 
+                          e.next.next.next.getObject() instanceof Map.Entry){
+                               
+                          
+                               Map.Entry me =  
(Map.Entry)e.next.next.next.getObject();
+                               Object v = me.getValue();
+                               boolean th = v instanceof TrapHolder;
+                               r+="\n    "+(th?"++= ":".")+me.getKey();
+                               next = e.next.next.next.next;           
+               }else if(e.next.next!=null && e.next.next.next!=null &&
+                               e.getObject() instanceof Box &&
+                               e.next.getObject() instanceof BasicTree){
+                       Box child = (Box)e.next.next.next.getObject();
+                       r+="\n    ["+child.getIndexInParent()+"]";
+                       next = e.next.next.next;
+               }else if(e.next.next!=null && e.next.next.next!=null &&
+                               e.getObject() instanceof JSFunction &&
+                               e.next.getObject() instanceof Scope){
+                       JSFunction func = (JSFunction)e.getObject();
+                       Scope scope = (Scope)e.next.getObject(); 
+                       Object variable = e.next.next.next.getObject();
+                       Integer j = JSUX.scopeLookup(scope, variable);
+                       if(j!=null){
+                               ScopeInfo si = 
RTScopeInfo.Map.getScopeInfo(func);
+                               String varname = 
ScopeInfoManager.reverseLookupScopeInfo(si, j);
+                               r+="\n    var "+varname;
+                               next = e.next.next.next;
+                       }
+                       
+               }
+               
+               r+=formatLine(next);
+       }
+       return r;
+    }
+    
+    /** BFS scan of incomming refs*/
+    static private String  findRoots(Map objects, Object obj) {
 
+
         Set visited = new HashSet();
         Entry fin = (Entry)objects.get(obj);
         assert(fin!=null);
@@ -141,7 +231,7 @@
             Iterator it = act.getItem().staticRefs();
             if (it.hasNext()) {
                 Field fld = (Field)it.next();
-                return fld + "-> (from static)\n" + act;
+                return "(Static Root) "+format(fld)+ formatLine(act);
             }
             
             // follow incomming
@@ -174,6 +264,8 @@
             stat = EMPTY;
         }
         
+        public Object get(){ return obj; }
+       
         void addOut(Object o) {
             out = append(out, o);
         }
@@ -205,25 +297,6 @@
             ret[origLen] = add;
             return ret;
         }
-        
-        public String toString() {
-               String r = "";
-               if(Memory.get(obj)!=null)
-                       r+= Memory.get(obj).firstLine() + ":"; // JS object
-               else
-                       r+= "    "; // non-JS object
-               
-               if(obj instanceof JS){
-                       try {
-                                       return 
r+=JSON.marshal((JS)obj).coerceToString() + " JS";
-                               } catch (JSExn e) {
-                                       return r+=obj.toString() + " (Could not 
stringify: "+e.getMessage()+")";
-                               }
-               }else{
-                       r+=obj.toString() + " java";
-               }
-            return r;
-               //return obj.getClass().getName() + "@" + 
Integer.toHexString(System.identityHashCode(obj));
-        }
+
     }
 }

Modified: 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/Memory.java
===================================================================
--- 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/Memory.java
  2014-05-10 14:07:32 UTC (rev 4694)
+++ 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memory/Memory.java
  2014-05-10 14:21:51 UTC (rev 4695)
@@ -20,85 +20,135 @@
 import org.ibex.js.JS;
 import org.ibex.js.JSExn;
 import org.ibex.js.JSU;
+import org.ibex.js.RTScopeInfo;
+import org.ibex.js.parse.Parser.ScopeInfo;
 import org.ibex.util.Basket;
 import org.vexi.util.Log;
 
 // FIXME - move devl js implementation out of here
-public class Memory extends JS.Immutable implements Instr.Memory {
+public class Memory extends JS.Immutable implements Instr.Memory, 
Instr.Compilation {
        
        static int counter = 0;
        
        static class Marker extends JS.Obj{ 
                final int id = counter++;
-               public void finalize(){ Log.warn(Memory.class, "*** 
MARKER("+id+" finalized ***"); }
+               int references = 1;
+               public void finalize(){ Log.warn(Memory.class, "*** 
MARKER("+id+") finalized ***"); }
        }
-       static Marker MARKER = new Marker();
-       static Reference MARKER_REF;
+       //static Marker MARKER = new Marker();
+       static Reference MARKER_REF = new SoftReference(null);
        
        public Memory() {
                Instr.devl = this;
                Instr.memory = this;
+               Instr.compilation = this;
                new Panel().go();
        }
        
+       public Marker getMarker(){
+               Marker marker = (Marker)MARKER_REF.get();
+               if(marker==null){
+                       marker = new Marker();
+                       MARKER_REF = new SoftReference(marker);
+                       Log.warn(Memory.class, "*** MARKER("+marker.id+") set 
***");
+               }else{
+                       Log.warn(Memory.class, "*** MARKER("+marker.id+") 
reused "+(++marker.references)+" time(s) ***");                                 
                      
+               }
+               return marker;
+       }
+       
        public JS get(JS key_) throws JSExn {
                String key = JSU.toString(key_);
                if("MARKER".equals(key)){
-                       if(MARKER == null) 
-                               return null;
-                       Marker r = MARKER;
-                       MARKER_REF = new SoftReference(MARKER);
-                       MARKER = null;
-                       Log.warn(Memory.class, "*** MARKER("+r.id+") set ***");
-                       return r;
+                       return getMarker();
+               }else if("MARKER_SINGLEUSE".equals(key)){
+                       if(MARKER_REF.get()!=null) return null;
+                       return getMarker();
                }
                return null;
        }
 
        public void assertCollection(){
-               if(MARKER != null) Log.warn(Memory.class, "MARKER has not been 
set yet");
-               else{
-                       try{
-                               GCUtil.assertGC("MARKER not collected", 
MARKER_REF);
-                       }finally{
-                               MARKER = new Marker();
-                       }
-               }
+               GCUtil.assertGC("MARKER not referenced", MARKER_REF);           
        }
        
-       public void dumpStacks(){
 
-               System.err.println();
-               System.err.println("*** Object creation report");
-               System.err.println("Unique stacks:" + stackToCount.size());
-               System.err.println("Top 15");
-               List l = new ArrayList(stackToCount.keySet());
-               Collections.sort(l, new Comparator(){
-                       public int compare(Object sa, Object sb) {
-                               int ca = 
((Integer)stackToCount.get(sa)).intValue();
-                               int cb = 
((Integer)stackToCount.get(sb)).intValue();
-                               if(ca==cb) return 0;
-                               if(ca>cb) return -1;
-                               return 1;
+       
+    
+    ////////
+    // MEMORY LEAK TRACKING
+    /////
+       static class BookKeeper<O>{
+               final String name;
+           final private Map<Integer,ObjInfo> hashToObjInfo = new HashMap();
+           final private Map stackToCount = new HashMap();
+           public BookKeeper(String name) {
+                       this.name = name;
+               }
+           
+           synchronized void clear(){
+               hashToObjInfo.clear();
+               stackToCount.clear();
+           }
+           
+           synchronized ObjInfo register(O o, String title){
+                       Integer hash = System.identityHashCode(o);
+                       ObjInfo oi = objInfo(o,title);
+               hashToObjInfo.put(hash, oi);
+               
+               Integer c = (Integer)stackToCount.get(oi.bt);
+                       if(c==null) stackToCount.put(oi.bt,1);
+                       else {
+                               stackToCount.put(oi.bt,c.intValue()+1);
                        }
-                       
-               });
+                       return oi;
+           }
+           
+               synchronized void unregister(O o){
+                       Integer hash =System.identityHashCode(o);
+                       ObjInfo oi = (ObjInfo)hashToObjInfo.get(hash);
+                       if(oi!=null){
+                       Integer c = (Integer)stackToCount.get(oi.bt);
+                               if(c.intValue()==1) stackToCount.remove(oi.bt);
+                               else stackToCount.put(oi.bt,new 
Integer(c.intValue()-1));
+                       }
+               }
                
-               for(int i=0;i<15; i++){
-                       Object s = l.get(i);
-                       System.err.println(stackToCount.get(s));
-                       System.err.println(s);
+           
+               public ObjInfo get(Object o){
+                       Integer hash =  System.identityHashCode(o);
+                   return (ObjInfo) hashToObjInfo.get(hash);
+               }
+               
+               public void dumpStacks(){
+                       System.err.println();
+                       System.err.println("*** "+name+" creation report");
+                       System.err.println("Unique stacks:" + 
stackToCount.size());
+                       System.err.println("Top 15");
+                       List l = new ArrayList(stackToCount.keySet());
+                       Collections.sort(l, new Comparator(){
+                               public int compare(Object sa, Object sb) {
+                                       int ca = 
((Integer)stackToCount.get(sa)).intValue();
+                                       int cb = 
((Integer)stackToCount.get(sb)).intValue();
+                                       if(ca==cb) return 0;
+                                       if(ca>cb) return -1;
+                                       return 1;
+                               }
+                               
+                       });
                        
+//                     int n = Math.min(stackToCount.size(), 15);
+                       for(int i=0;i<stackToCount.size(); i++){
+                               Object s = l.get(i);
+                               System.err.println(stackToCount.get(s));
+                               System.err.println(s);
+                               
+                       }
                }
        }
        
-    
-    ////////
-    // MEMORY LEAK TRACKING
-    /////
-    static private Map hashToObjInfo = new HashMap();
-    static private Map stackToCount = new HashMap();
-    
+       static final BookKeeper objects = new BookKeeper("Object");
+       static final BookKeeper trapholders = new BookKeeper("TrapHolder");
        
        static class ObjInfo{
                final String bt; // the backtrace when it is created
@@ -106,58 +156,38 @@
                String firstLine(){ return bt.split("\\n")[0]; }
        }
 
-    static private boolean doesOverrideHashCode(Object o){
-               try {
-                       java.lang.reflect.Method m = 
o.getClass().getMethod("hashCode", new Class[]{});
-                       Class declaring = m.getDeclaringClass();
-                       if(Object.class!=declaring)
-                               return false;
-                       return true;
-               } catch (Exception e) {
-                       throw new RuntimeException(e);
-               }
-    }
     
        static public ObjInfo get(Object o){
-               if(!doesOverrideHashCode(o))
-                       return null;
-                       
-               Integer hash = new Integer(o.hashCode());
-           return (ObjInfo) hashToObjInfo.get(hash);
+               return (ObjInfo) objects.get(o);
        }
     
+       
        synchronized public void register(JS o){
                if(!(o instanceof JSExn.Obj)){
-                       if(!doesOverrideHashCode(o))
-                               throw new RuntimeException("Cannot register 
objects with overridden hashcodes " + o.getClass().getName());
-
-                       Integer hash = new Integer(o.hashCode());
-                       ObjInfo oi = objInfo();
-               hashToObjInfo.put(hash, oi);
-               
-               Integer c = (Integer)stackToCount.get(oi.bt);
-                       if(c==null) stackToCount.put(oi.bt,new Integer(1));
-                       else stackToCount.put(oi.bt,new 
Integer(c.intValue()+1));
+                       objects.register(o, o.getClass().getName());
+                       
                }
        }
                
        synchronized public void unregister(JS o){
                if(!(o instanceof JSExn.Obj)){
-                       Integer hash = new Integer(o.hashCode());
-                       ObjInfo oi = (ObjInfo) hashToObjInfo.remove(hash);
-
-                       Integer c = (Integer)stackToCount.get(oi.bt);
-                       if(c.intValue()==1) stackToCount.remove(oi.bt);
-                       else stackToCount.put(oi.bt,new 
Integer(c.intValue()-1));
+                       objects.unregister(o);
                }
        }
     
+       public void register(JS.TrapHolder o){
+               trapholders.register(o, o.function().coerceToString());
+       }
+       public void unregister(JS.TrapHolder o){
+               trapholders.unregister(o);
+       }
     
-    static public ObjInfo objInfo(){
+    static public ObjInfo objInfo(Object o, String title){
        Basket.List bt = JSU.backtrace();
-       StringBuffer b = new StringBuffer(512);
+       StringBuilder b = new StringBuilder(512);
+       b.append(title);
        for(int i=0; i<bt.size(); i++){
-               if(i!=0) b.append("\n");
+               b.append("\n");
                b.append(bt.get(i));
        }
        return new ObjInfo(b.toString());
@@ -178,15 +208,17 @@
                        JButton button1 = new JButton("Restart collection");
                        button1.addActionListener(new ActionListener(){
                                public void actionPerformed(ActionEvent e) {
-                                       // TODO
+                                       objects.clear();
+                                       trapholders.clear();
                                }
                        });
-                       button1.setEnabled(false);
+//                     button1.setEnabled(false);
                        
                        JButton button2 = new JButton("Dump Stacks");
                        button2.addActionListener(new ActionListener(){
                                public void actionPerformed(ActionEvent e) {
-                                       dumpStacks();
+                                       objects.dumpStacks();
+                                       trapholders.dumpStacks();
                                }
                        });
                        
@@ -209,7 +241,7 @@
                        JButton button4 = new JButton("GC");
                        button4.addActionListener(new ActionListener(){
                                public void actionPerformed(ActionEvent e) {
-                           System.gc();
+                                       GCUtil.ensurecGC(null);
                            System.runFinalization();
                                }
                        });
@@ -224,7 +256,7 @@
                        JButton button6 = new JButton("Reset MARKER");
                        button6.addActionListener(new ActionListener(){
                                public void actionPerformed(ActionEvent e) {
-                                       MARKER=new Marker();
+                                       MARKER_REF.clear();
                                }
                        });
                        
@@ -238,4 +270,8 @@
                        frame.setVisible(true);
                }
        }
+       
+       public void putScopeInfo(ScopeInfo si) {
+               RTScopeInfo.Map.put(si);
+       }
 }

Modified: 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memoryhist/MemoryHist.java
===================================================================
--- 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memoryhist/MemoryHist.java
  2014-05-10 14:07:32 UTC (rev 4694)
+++ 
branches/vexi3/org.vexi-core.devtools/src/main/java/org/vexi/instrument/memoryhist/MemoryHist.java
  2014-05-10 14:21:51 UTC (rev 4695)
@@ -9,7 +9,13 @@
 
 import org.ibex.js.*;
 
-// FIXME - move devl js implementation out of here
+// MEMORY HIST
+// This is really for vexi core development. Not debugging a particular vexi
+// program. 
+//
+// Shows a  histogram of object numbers vs their size in terms of properties 
and traps.
+// From this we can decide how better to implement Objects (i.e. which cases 
need
+// optimising for)
 public class MemoryHist extends JS.Immutable implements Instr.Memory {
 
        
@@ -18,36 +24,19 @@
                new Panel().go();
        }
     
-    ////////
-    // MEMORY LEAK TRACKING
-    /////
     static private Map hashToObj = new HashMap();
 
-    static private boolean doesOverrideHashCode(Object o){
-               try {
-                       java.lang.reflect.Method m = 
o.getClass().getMethod("hashCode", new Class[]{});
-                       Class declaring = m.getDeclaringClass();
-                       if(Object.class!=declaring)
-                               return false;
-                       return true;
-               } catch (Exception e) {
-                       throw new RuntimeException(e);
-               }
-    }
-   
+
        synchronized public void register(JS o){
                if(!(o instanceof JSExn.Obj)){
-                       if(!doesOverrideHashCode(o))
-                               throw new RuntimeException("Cannot register 
objects with overridden hashcodes " + o.getClass().getName());
-
-                       Integer hash = new Integer(o.hashCode());
+                       Integer hash = System.identityHashCode(o);
                hashToObj.put(hash, o);
                }
        }
                
        synchronized public void unregister(JS o){
                if(!(o instanceof JSExn.Obj)){
-                       Integer hash = new Integer(o.hashCode());
+                       Integer hash = System.identityHashCode(o);
                        hashToObj.remove(hash);
 
                }
@@ -132,4 +121,10 @@
                        frame.setVisible(true);
                }
        }
+       
+       
+       public void register(JS.TrapHolder o){}
+       public void unregister(JS.TrapHolder o){}
+
+       public JS getMarker() { return null; }
 }

Modified: branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp
===================================================================
--- branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp        
2014-05-10 14:07:32 UTC (rev 4694)
+++ branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp        
2014-05-10 14:21:51 UTC (rev 4695)
@@ -361,6 +361,9 @@
 
 
     // Instance Methods 
/////////////////////////////////////////////////////////////////////
+    // FIX not right. Really we want the constructor to be showing, and it 
does by default
+    // if it exists, but need to consider the case if a template is not 
present (or indeed
+    // if that should be possible).
     public String coerceToString() { return "box$" + 
Integer.toHexString(hashCode()); }
     
     // FEATURE: use cx2/cy2 format
@@ -3074,7 +3077,7 @@
     private final void insertNode(int p, Box b) { if (bt == null) bt = new 
BasicTree(); bt.insertNode(p,b); }
 
     // self
-    private final int getIndexInParent() { return parent == null ? 0 : 
parent.indexNode(this); }
+    public final int getIndexInParent() { return parent == null ? 0 : 
parent.indexNode(this); }
     public boolean hasParent() { return parent!=null; }
 
 

Modified: 
branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Instr.java
===================================================================
--- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Instr.java     
2014-05-10 14:07:32 UTC (rev 4694)
+++ branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Instr.java     
2014-05-10 14:21:51 UTC (rev 4695)
@@ -7,6 +7,7 @@
        static public JS devl;
        
        static public Interpreter interpreter;
+       static public Compilation compilation;
        static public Debug debug;
        static public Memory memory;
        
@@ -21,6 +22,14 @@
                public void handle(org.ibex.js.Interpreter interpreter);
        }
        
+       static public interface Compilation{
+               /**     Called from the parser. Preserves local variable name 
information 
+                * 
+                * @param si           - ScopeInfo, maps scope slots to 
variable names
+                */
+               public abstract void putScopeInfo(ScopeInfo si);
+       }
+       
        /**
         * Provides a link for hooking in a debugger. For the implementation 
see org.vexi.debug.
         * <br>
@@ -31,13 +40,9 @@
         *
         */
 
-       static public interface Debug extends Interpreter {
+       static public interface Debug extends Interpreter,Compilation {
                
-               /**     Called from the parser. Preserves local variable name 
information 
-                * 
-                * @param si           - ScopeInfo, maps scope slots to 
variable names
-                */
-               public abstract void putScopeInfo(ScopeInfo si);
+
                
                ////
                // Thread stuff
@@ -55,6 +60,10 @@
        static public interface Memory {
                public void register(JS o);
                public void unregister(JS o);
+               
+               public void register(JS.TrapHolder o);
+               public void unregister(JS.TrapHolder o);
+               public JS getMarker();
        }
        
 

Modified: branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java
===================================================================
--- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java       
2014-05-10 14:07:32 UTC (rev 4694)
+++ branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java       
2014-05-10 14:21:51 UTC (rev 4695)
@@ -163,7 +163,7 @@
         return false;
     }
     
-    static public JS constructorsOf(JS arg){
+    static public JSArray constructorsOf(JS arg){
        JSArray r = new JSArray();
        if(!(arg instanceof JS.Obj)) return r;
        for(ConstructorList l = ((JS.Obj)arg).constructors;l!=null;l=l.next){
@@ -338,8 +338,8 @@
     
     /** lets us put multi-level get/put/call keys all in the same method */
     static public class Sub extends JS.Obj {
-        final JS main;
-        final JS key;
+        final public JS main;
+        final public JS key;
         public Sub(JS main, JS key) { 
                this.main = main;
                this.key = key; 
@@ -353,6 +353,10 @@
         public JS callMethod(JS this_, JS method, JS[] args) throws JSExn {
             return main.callMethod(this_, JSU.S(JSU.toString(this.key) + "." + 
JSU.toString(method)), args);
         }
+        
+        @Override public String coerceToString() {
+               return main.coerceToString()+"."+key;
+        }
     }
     
 

Modified: 
branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/parse/Parser.java
===================================================================
--- 
branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/parse/Parser.java  
    2014-05-10 14:07:32 UTC (rev 4694)
+++ 
branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/parse/Parser.java  
    2014-05-10 14:21:51 UTC (rev 4695)
@@ -9,6 +9,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.ibex.js.Instr;
 import org.ibex.util.Basket;
 import org.ibex.util.SourceException;
 import org.ibex.util.Vec;
@@ -169,12 +170,15 @@
     // Local variable management
     Basket.Array scopeStack = new Basket.Array();
     static public class ScopeInfo {
+       final public ScopeInfo parent;
         int base;
         int end;
         int newScopeInsn;
         public Map mapping = new HashMap();
         
-        ScopeInfo(){}
+        ScopeInfo(ScopeInfo parent){
+               this.parent = parent;
+        }
         // For the debugger.
         // When debuggin it is necessary to keep ScopeInfo as it is required 
to recover variable 
         //names (from the scope slot integer). At runtime the information we 
have is the base and the end.
@@ -185,6 +189,14 @@
         public Function jsfunc;  // JSFunc which it belongs to
         public int pc;             // pc where scope was created
 
+               public void init(Function b, int i) {
+               jsfunc = b;
+               pc = i;
+               if(Instr.compilation!=null){
+                       Instr.compilation.putScopeInfo(this);
+               }
+               }
+
     }
     
     //JS declaree = null;
@@ -225,7 +237,7 @@
     }
     void scopePush(Function b) {
         ScopeInfo prev = (ScopeInfo) scopeStack.peek();
-        ScopeInfo si = new ScopeInfo();
+        ScopeInfo si = new ScopeInfo(prev);
         si.base = prev.end;
         si.end = si.base;
         si.newScopeInsn = b.size;
@@ -233,8 +245,7 @@
         b.add(parserLine, NEWSCOPE);
         
         // Add info required for hashing ScopeInfo uniquely
-        si.jsfunc = b;
-        si.pc = b.size-1;
+        si.init(b, b.size-1);
         
     }
     void scopePop(Function b) {
@@ -282,7 +293,7 @@
     public Function parseScript() throws IOException{
        Function ret = new Function(sourceName, line);
         scopeStack.clear();
-        ScopeInfo si = new ScopeInfo();
+        ScopeInfo si = new ScopeInfo(null);
         si.jsfunc = ret;
         scopeStack.push(si);
         scopePush(ret);

Modified: branches/vexi3/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp
===================================================================
--- branches/vexi3/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp  
2014-05-10 14:07:32 UTC (rev 4694)
+++ branches/vexi3/org.vexi-library.js/src/main/jpp/org/ibex/js/JS.jpp  
2014-05-10 14:21:51 UTC (rev 4695)
@@ -1165,7 +1165,17 @@
     static final public class TrapHolder implements Trap {
         private final JS target, key, function;
         private Trap next;
-        public TrapHolder(JS t, JS k, JS f, Trap n) { target = t; key = k; 
function = f; next = n; }
+        public TrapHolder(JS t, JS k, JS f, Trap n) { 
+               target = t; key = k; function = f; next = n; 
+            if (Instr.memory!=null) {
+                Instr.memory.register(this);
+            }
+        }
+        protected void finalize() throws Throwable {
+            if (Instr.memory!=null) {
+                Instr.memory.unregister(this);
+            } 
+        }
         public JS key() { return key; }
         public JS target() { return target; }
         public JS function() { return function; }

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to