You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kato-commits@incubator.apache.org by sp...@apache.org on 2009/05/15 15:02:05 UTC

svn commit: r775173 - in /incubator/kato: branches/experimental/PyJVMTI/ branches/experimental/PyJVMTI/kato/ trunk/org.apache.kato.jvmti/src/org/apache/kato/jvmti/reader/

Author: spoole
Date: Fri May 15 15:02:05 2009
New Revision: 775173

URL: http://svn.apache.org/viewvc?rev=775173&view=rev
Log:
more updates to jvmti demo to support the kato api

Modified:
    incubator/kato/branches/experimental/PyJVMTI/kato/BinDump.py
    incubator/kato/branches/experimental/PyJVMTI/kato/Dump.py
    incubator/kato/branches/experimental/PyJVMTI/kato/JClass.py
    incubator/kato/branches/experimental/PyJVMTI/kato/JThread.py
    incubator/kato/branches/experimental/PyJVMTI/kato/JThreadGroup.py
    incubator/kato/branches/experimental/PyJVMTI/kato/PauseJVM.java
    incubator/kato/branches/experimental/PyJVMTI/kato/console.py
    incubator/kato/branches/experimental/PyJVMTI/pyjvmti.c
    incubator/kato/branches/experimental/PyJVMTI/pyjvmti.h
    incubator/kato/trunk/org.apache.kato.jvmti/src/org/apache/kato/jvmti/reader/BinReader.java

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/BinDump.py
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/BinDump.py?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/BinDump.py (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/BinDump.py Fri May 15 15:02:05 2009
@@ -13,6 +13,8 @@
  #******************************************************************************"
 import kato.Dump as Dump
 import kato.JField as JField
+import kato.JThreadGroup as JThreadGroup
+
 import struct
 
 class BinDump(Dump.Dump):
@@ -40,34 +42,76 @@
         recordType=struct.pack("!hi",100,count)
         self.output.write(recordType)
         
+    def startThreadGroupSave(self,count):
+        
+        # write a thread group meta record
+        recordType=struct.pack("!hi",300,count)
+        self.output.write(recordType)
+            
+    def saveThreadGroup(self,group):
+        '''
+        Save a thread group
+        '''
+        parentgroup=group.parentThreadGroupID;
+        if parentgroup==None : parentgroup=0
+        
+        header=struct.pack("!hiihh",301,group.threadid,parentgroup,group.maxpriority,group.isdaemon)
+        self.output.write(header)
+        self.writeName(group.name)
+        
+        # now write its kids...
+        
         
     def saveThread(self,thread):
         '''
         Save a single Jthread
         '''
-        header=struct.pack("!hihhi",101,thread.threadid,thread.priority,thread.isDaemon,thread.threadGroupID)
+        monitors=thread.ownedMonitorIDs
+        monlength=len(monitors)
+        
+        stacktrace=thread.stacktrace
+        tracelen=len(stacktrace)
+        
+        header=struct.pack("!hihhiiii",101,thread.threadid,thread.priority,thread.isDaemon,thread.threadGroupID,thread.contendedMonitor,monlength,tracelen)
         self.output.write(header)
         namelength=struct.pack("!i",len(thread.name))
         self.output.write(namelength)
         self.output.write(thread.name)
         
-        monitors=thread.ownedMonitorIDs;
-        monlength=len(monitors)
+        
         if monlength > 0 :
-            saveMonitors(monitors)
+            self.saveMonitors(monlength,monitors)
+
+        if tracelen > 0 :
+            self.saveStackTrace(tracelen,stacktrace)
        
         print "saved " , thread.name 
        
-    def saveMonitiors(self,list):
+    def saveMonitors(self,count,list):
         
-        header=struct.pack("!hi",102,len(list))
+        print "monitors=",count
+        header=struct.pack("!hi",102,count)
         self.output.write(header)
         
         for monitor in list :
             header=struct.pack("!i",monitor)
             self.output.write(header)
+    
             
+    def saveStackTrace(self,count,list):
         
+        print "stacktrace=",count
+        header=struct.pack("!hi",103,count)
+        self.output.write(header)
+        
+        for frame in list :
+            a=frame[0]
+            b=frame[1]
+            if a==None : a=-1
+            if b==None:  b= -1
+            header=struct.pack("!ii",a,b)
+            self.output.write(header)
+               
             
     def startClassSave(self,count):
         
@@ -93,7 +137,7 @@
         Save a single JClass
         '''
          
-        header=struct.pack("!hiihhhhh",201,clazz.classid,clazz.superclass,clazz.status,clazz.modifiers,len(clazz.fields),len(clazz.interfaces),len(clazz.methods))
+        header=struct.pack("!hiiihhhhh",201,clazz.classid,clazz.superclass,clazz.classloader,clazz.status,clazz.modifiers,len(clazz.fields),len(clazz.interfaces),len(clazz.methods))
         self.output.write(header)
         namelength=struct.pack("!i",len(clazz.signature))
         self.output.write(namelength)

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/Dump.py
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/Dump.py?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/Dump.py (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/Dump.py Fri May 15 15:02:05 2009
@@ -29,12 +29,14 @@
  #******************************************************************************"
 import jvmti
 import kato.JThread as JThread
+import kato.JThreadGroup as JThreadGroup
 import kato.JClass as JClass
 
 class Dump(object):
     
     includeThreads=True
     includeClasses=True
+    includeTopThreadGroups=True
 
     
     '''
@@ -66,7 +68,12 @@
         '''
         Save a single Jthread
         '''
-       
+        
+    def saveThreadGroup(self,threadgroup):
+        '''
+        Save a single JthreadGroup
+        '''
+        
     def saveClass(self,clazz):
         '''
         Save a single JClass
@@ -87,16 +94,41 @@
             self.saveClass(q) 
             
         self.endClassSave();
+        
+    def saveThreadGroups(self,groups):
+         
+        '''
+        Save Thread Groups - given a list of group ids 
+        will call saveThreadGroup repeatedly with a newly constructed
+        JThreadGroup instance
+        ''' 
+        self.startThreadGroupSave(len(groups))
+        
+        for g in groups :
+            q=JThreadGroup.JThreadGroup(g)
+            self.saveThreadGroup(q) 
             
+        self.endThreadGroupSave();
+               
     def startThreadSave(self,count):
         '''
         called before threads are saved
         '''   
-    
+        
+    def startThreadGroupSave(self,count):
+        '''
+        called before threadgroups are saved
+        '''
+           
     def endThreadSave(self):
         '''
         called just after threads are saved
         '''   
+        
+    def endThreadGroupSave(self):
+        '''
+        called just after threadgroups are saved
+        '''   
     def startClassSave(self,count):
         '''
         called before classes are saved
@@ -136,6 +168,9 @@
         saved=self.saveAllClasses()
         print "saved",saved,"classes"
         
+        saved=self.saveAllThreadGroups()
+        print "saved",saved,"thread groups"
+        
         self.close()
     
     def saveAllThreads(self):
@@ -158,6 +193,17 @@
         classes=jvmti.getLoadedClasses()
         
         self.saveClasses(classes);   
-        return len(classes)            
-       
+        return len(classes)
+                
+    def saveAllThreadGroups(self):
+        '''
+        Save thredgroups to dump if includeTopThreadGroups is true
+        '''
+        
+        if self.includeTopThreadGroups==False :  return 0
+        
+        groups=jvmti.getTopThreadGroups()
+        
+        self.saveThreadGroups(groups);   
+        return len(groups)      
   
\ No newline at end of file

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/JClass.py
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/JClass.py?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/JClass.py (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/JClass.py Fri May 15 15:02:05 2009
@@ -20,6 +20,8 @@
     '''
     classid=0
     superclassid=-2
+    classloaderid=-2
+    
     statusValue=None
     sig=None
     sourcefile=None
@@ -58,6 +60,12 @@
 
         return self.statusValue
     
+    @property 
+    def classloader(self):
+        if self.classloaderid==-2 :
+            self.classloaderid=jvmti.getClassLoader(self.classid)
+        return self.classloaderid;
+        
     @property
     def signature(self):
         self.fill();

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/JThread.py
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/JThread.py?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/JThread.py (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/JThread.py Fri May 15 15:02:05 2009
@@ -26,6 +26,7 @@
     info=None
     threadid=0;
     monitors=None
+    stackframes=None
     hasContendedMonitor=None
     contendedMonitorID=None
     
@@ -63,6 +64,21 @@
         self.fill()
         return self.info[4]
           
+    @property 
+    def stacktrace(self):
+        '''
+        Returns a list of tuples where first entry is method id and second is location id
+        '''
+        if self.stackframes==None :
+            count=jvmti.getFrameCount(self.threadid)
+            if count > 0 :
+                self.stackframes=jvmti.getStackTrace(self.threadid,0,count)
+            else :
+                 self.stackframes=[]
+            
+        return self.stackframes    
+            
+            
     @property
     def ownedMonitorIDs(self):
         if self.monitors==None :

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/JThreadGroup.py
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/JThreadGroup.py?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/JThreadGroup.py (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/JThreadGroup.py Fri May 15 15:02:05 2009
@@ -28,21 +28,25 @@
         
     def fill(self):
         
-       if info==None :
-           info=jvmti.getThreadGroupInfo(threadid)
-       
+       if self.info==None :
+           self.info=jvmti.getThreadGroupInfo(self.threadid)
+           
+    @property
     def parentThreadGroupID(self):
-        fill()
-        return info[0]
+        self.fill()
+        return self.info[0]
     
+    @property
     def name(self):
-        fill()
-        return info[1]
+        self.fill()
+        return self.info[1]
     
+    @property
     def maxpriority(self):
-        fill()
-        return info[2]
-       
+        self.fill()
+        return self.info[2]
+    
+    @property   
     def isdaemon(self):
-        fill()
-        return info[3]
+        self.fill()
+        return self.info[3]

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/PauseJVM.java
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/PauseJVM.java?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/PauseJVM.java (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/PauseJVM.java Fri May 15 15:02:05 2009
@@ -15,16 +15,45 @@
 package kato;
 
 
+
+
 public class PauseJVM {
 
 	private static int classint=100;
+	
 	public static final int constantint=200;
 	/**
 	 * @param args
 	 */
-	public static void main(String[] args) {
 	
+	public static void main(String[] args) {
+		
+			
+			
+			PauseJVM jvm=new PauseJVM();
+			jvm.execute(args);
+		}
+		
+	public  void execute(String[] args) {
+		
+		
+		SyncObject sync=new SyncObject();
+		
+		WaitingThread w=new WaitingThread(sync);
+		w.start();
+		
+		try {
+			Thread.sleep(1000);
+		} catch (InterruptedException e) {
+
+			
+		}
+		
+		w=new WaitingThread(sync);
+		w.start();
+		
 		long me=1000000;
+		
 		try {
 			Thread.sleep(me);
 		} catch (InterruptedException e) {
@@ -35,4 +64,31 @@
 
 	}
 
+	class WaitingThread extends Thread {
+		
+		SyncObject sync=null;
+		public WaitingThread(SyncObject sync) {
+			this.sync=sync;
+		}
+		public void run() {
+			sync.enter();
+			
+		}
+	}
+	
+	class SyncObject {
+		
+		public synchronized void enter() {
+			long me=1000000;
+			
+			try {
+				Thread.sleep(me);
+			} catch (InterruptedException e) {
+
+				e.printStackTrace();
+			}
+			
+			
+		}
+	}
 }

Modified: incubator/kato/branches/experimental/PyJVMTI/kato/console.py
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/kato/console.py?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/kato/console.py (original)
+++ incubator/kato/branches/experimental/PyJVMTI/kato/console.py Fri May 15 15:02:05 2009
@@ -95,6 +95,11 @@
             except TypeError as (errno):
                     json.dump([depth,"n/a"],output) 
        
+def classloaders():
+    '''
+    List class loaders..
+    '''
+    
     
 def threads():
     """

Modified: incubator/kato/branches/experimental/PyJVMTI/pyjvmti.c
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/pyjvmti.c?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/pyjvmti.c (original)
+++ incubator/kato/branches/experimental/PyJVMTI/pyjvmti.c Fri May 15 15:02:05 2009
@@ -90,6 +90,14 @@
 			 		return list;\
 
 
+
+JNICALL myjvmtiHeapObjectCallback(jlong class_tag,
+     jlong size,
+     jlong* tag_ptr,
+     void* user_data) {
+	printf("called...");
+}
+
 static char * getErrorMessage(jvmtiError err,char *usrmsg) {
 
 		char *msg=NULL;
@@ -777,10 +785,40 @@
 	getList(GetClassFields,jfieldID,"Get Class Fields")
 }
 
+static PyObject *  jvmti_getClassLoader(PyObject *self, PyObject *args) {
+	getValue(GetClassLoader,jclass,"i","Get Class Loader")
+}
+
 static PyObject *  jvmti_getImplementedInterfaces(PyObject *self, PyObject *args) {
 	getList(GetImplementedInterfaces,jclass,"Get Implemented Interfaces")
 }
 
+static PyObject *  jvmti_iterateOverInstancesOfClass(PyObject *self, PyObject *args) {
+
+
+	CHECK_VALID();
+			// get required class
+			int classID=0;
+
+			PyArg_ParseTuple(args, "i", &classID);
+
+			jclass classj=(jclass)classID;
+
+			PyObject* list= PyList_New(100);
+
+			jvmtiHeapObjectCallback callback=&myjvmtiHeapObjectCallback;
+
+			jvmtiError err=(*jvmtiptr)->IterateOverInstancesOfClass(jvmtiptr,classj,
+					JVMTI_HEAP_OBJECT_EITHER, callback,(void*)list);
+
+			CHECK_OK("iterate over instances of class");
+
+			 return list;
+
+
+}
+
+
 
 static PyMethodDef  JvmtiMethods[] = {
 
@@ -810,6 +848,7 @@
      {"getClassLoaderClasses",jvmti_getClassLoaderClasses, METH_VARARGS,   "Get ClassLoader classes"},
      {"getImplementedInterfaces", jvmti_getImplementedInterfaces, METH_VARARGS,   "Get Implemented Interfaces."},
      {"getSuperClass",        jvmti_getSuperClass, METH_VARARGS,   "Get Superclass."},
+     {"getClassLoader",       jvmti_getClassLoader, METH_VARARGS,   "Get Class Loader."},
      {"getFieldName",        jvmti_getFieldName, METH_VARARGS,   "Get Field Name."},
 
      {NULL, NULL, 0, NULL}        /* Sentinel */

Modified: incubator/kato/branches/experimental/PyJVMTI/pyjvmti.h
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/PyJVMTI/pyjvmti.h?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/branches/experimental/PyJVMTI/pyjvmti.h (original)
+++ incubator/kato/branches/experimental/PyJVMTI/pyjvmti.h Fri May 15 15:02:05 2009
@@ -68,6 +68,7 @@
 static PyObject *jvmti_getImplementedInterfaces(PyObject *self, PyObject *args);
 static PyObject *jvmti_getSuperClass(PyObject *self, PyObject *args);
 static PyObject *jvmti_getFieldName(PyObject *self, PyObject *args);
+static PyObject *jvmti_getClassLoader(PyObject *self, PyObject *args);
 
 void runScript(void);
 void startPython(void);

Modified: incubator/kato/trunk/org.apache.kato.jvmti/src/org/apache/kato/jvmti/reader/BinReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato.jvmti/src/org/apache/kato/jvmti/reader/BinReader.java?rev=775173&r1=775172&r2=775173&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato.jvmti/src/org/apache/kato/jvmti/reader/BinReader.java (original)
+++ incubator/kato/trunk/org.apache.kato.jvmti/src/org/apache/kato/jvmti/reader/BinReader.java Fri May 15 15:02:05 2009
@@ -34,6 +34,9 @@
 import org.apache.kato.java.JavaClass;
 import org.apache.kato.java.JavaClassLoader;
 import org.apache.kato.java.JavaField;
+import org.apache.kato.java.JavaLocation;
+import org.apache.kato.java.JavaMethod;
+import org.apache.kato.java.JavaMonitor;
 import org.apache.kato.java.JavaObject;
 import org.apache.kato.java.JavaStackFrame;
 import org.apache.kato.java.JavaThread;
@@ -44,8 +47,12 @@
 	private static final int MAX_MINOR=0;
 	private static final int MAX_MOD=1;
 	
+	
 	private Map<Integer,JavaThread> threadMap=new HashMap<Integer,JavaThread>();
 	private Map<Integer,JavaClass>  classMap=new HashMap<Integer,JavaClass>();
+	private Map<Integer,JavaClassLoader> loadersMap=new HashMap<Integer,JavaClassLoader>();
+	private Map<Integer,JavaMonitor> monitorsMap=new HashMap<Integer,JavaMonitor>();
+	private Map<Integer,JavaMethod>  methodMap=new HashMap<Integer,JavaMethod>();
 	FileImageInputStream in=null;
 	
 	 
@@ -89,6 +96,9 @@
 			case 200 :  // class list
 				readClasses();
 				break;
+			case 300 :   // thread groups
+				readThreadGroups();
+				break;
 			default  :  error("record group "+recordGroup+" is not understood");
 			}
 		}
@@ -96,6 +106,30 @@
 			;
 		}
 	}
+	private void readThreadGroups() throws IOException {
+		// start of assuming at byte 2 of the record group
+		// for ThreadGroups thats just a count...
+		int count=in.readInt();
+		trace("reading "+count+" threadgroup records");
+		
+		for(int i=0;i<count;i++) {
+			readThreadGroup();
+		}
+		
+		
+	}
+	private void readThreadGroup() throws IOException {
+		int id=in.readShort();
+		if(id!=301) error("unexpected threadgroup record id of "+id);
+		
+		int groupid=in.readInt();
+		int parentGroupID=in.readInt();
+		short maxpriority=in.readShort();
+		short daemon=in.readShort();
+		String name=readName();
+		  
+		
+	}
 	private void readClasses() throws IOException {
 		// start of assuming at byte 2 of the record group
 		// for Classes thats just a count...
@@ -112,9 +146,12 @@
 		// header must be 201
 		int id=in.readShort();
 		if(id!=201) error("unexpected class record id of "+id);
-		JClass c=new JClass();
-	    c.classid=in.readInt();
+		int classid=in.readInt();
+		JClass c=getClass(classid);
 	    c.superclassid=in.readInt();
+	    int classloaderid=in.readInt();
+	    JClassLoader loader=getLoader(classloaderid);
+	    loader.addClass(c);
 	    c.status=in.readShort();
 	    c.modifiers=in.readShort();
 	    c.fieldCount=in.readShort();
@@ -132,10 +169,50 @@
 		if(c.fieldCount>0) {
 			readFields(c);
 		}
+		
+		
 		trace("read class - name ="+c.classSig);
 		classMap.put(c.classid, c);
 	}
 	
+	private JMonitor getMonitor(int monitorid) {
+		if(monitorid==0) return null;
+		JMonitor m=(JMonitor) monitorsMap.get(monitorid);
+		if(m==null) {
+			m=new JMonitor();
+			monitorsMap.put(monitorid,m);
+		}
+		return m;
+	}
+	private JClass getClass(int id) {
+		if(id==0) return null;
+		JClass m=(JClass) classMap.get(id);
+		if(m==null) {
+			m=new JClass();
+			m.classid=id;
+			classMap.put(id,m);
+		}
+		return m;
+	}
+	private JMethod getMethod(int methodid) {
+		if(methodid==0) return null;
+		JMethod m=(JMethod) methodMap.get(methodid);
+		if(m==null) {
+			m=new JMethod();
+			methodMap.put(methodid,m);
+		}
+		return m;
+		
+	}
+	private JClassLoader getLoader(int classloaderid) {
+		
+		JClassLoader loader=(JClassLoader) loadersMap.get(classloaderid);
+		if(loader==null) {
+			loader=new JClassLoader();
+			loadersMap.put(classloaderid, loader);
+		}
+		return loader;
+	}
 	private String readName() throws IOException {
 		int   nameLength=in.readInt();
 		if(nameLength>0) {
@@ -186,16 +263,66 @@
 		t.priority=in.readShort();
 		t.daemon=in.readShort();
 		t.groupID=in.readInt();
-		int   nameLength=in.readInt();
-		t.threadName=null;
-		if(nameLength>0) {
-			byte name[]=new byte[nameLength];
-			in.readFully(name);
-			t.threadName=new String(name);
-		}
+		int contendedMonitor=in.readInt();
+		t.contendedMonitor=getMonitor(contendedMonitor);
+		if(t.contendedMonitor!=null) {
+			t.contendedMonitor.addWaiter(t);
+		}
+		int monitorCount=in.readInt();
+		int stackCount=in.readInt();
+		t.threadName=readName();
 		
 		trace("read thread - name ="+t.threadName);
 		threadMap.put(t.id, t);
+		
+		// read monitors...
+		if(monitorCount>0) {
+			readMonitors(t,monitorCount);
+		}
+		
+		if(stackCount>0) {
+			readStackTrace(t,stackCount);
+		}
+	}
+	
+	private void readStackTrace(JThread t, int stacklength) throws IOException {
+		int id=in.readShort();
+		if(id!=103) error("unexpected stack frame record id of "+id);
+		int count=in.readInt();
+		trace("reading "+count+" stack trace");
+		for(int i=0;i<count;i++) {
+			readStackTraceEntry(t);
+		}
+		
+	}
+	
+	private void readStackTraceEntry(JThread t) throws IOException {
+		
+		int methodid=in.readInt();
+		int location=in.readInt();
+		
+		JLocation loc=new JLocation();
+		loc.method=getMethod(methodid);
+		
+		JStackFrame frame=new JStackFrame();
+		frame.location=loc;
+		t.addStackFrame(frame);
+		
+	}
+	private void readMonitors(JThread t, int monitorCount) throws IOException {
+		int id=in.readShort();
+		if(id!=102) error("unexpected monitor record id of "+id);
+		int count=in.readInt();
+		for(int i=0;i<count;i++) {
+			readMonitor(t);
+		}
+	}
+	private void readMonitor(JThread t) throws IOException {
+		
+		int id=in.readInt();
+		JMonitor mon=getMonitor(id);
+		t.addMonitor(mon);
+		
 	}
 	private void trace(String msg) {
 		System.out.println(msg);
@@ -212,19 +339,90 @@
 		
 	}
 	
+	public Iterator getThreadIterator() {
+		return threadMap.values().iterator();
+	}
+	
+	
+	class JMonitor implements JavaMonitor {
+
+		List<JavaThread> waiters=new LinkedList<JavaThread>();
+		@Override
+		public Iterator getEnterWaiters() {
+			
+			return waiters.iterator();
+		}
+
+		private void addWaiter(JThread t) {
+			waiters.add(t);
+			
+		}
+
+		@Override
+		public ImagePointer getID() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public String getName() throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public Iterator getNotifyWaiters() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public JavaObject getObject() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public JavaThread getOwner() throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+		
+	}
 	class JThread implements JavaThread{
+		public JMonitor contendedMonitor=null;
 		int id=0;
 		short priority=0;
 		short daemon=0;
 		int   groupID=0;
 		String threadName=null;
-		List<JavaStackFrame> frames=new LinkedList<JavaStackFrame>();
+		
+		private List<JavaMonitor> monitors=null;
+		private List<JavaStackFrame> frames=new LinkedList<JavaStackFrame>();
+		
+		
 		@Override
 		public ImageThread getImageThread() throws CorruptDataException,
 				DataUnavailable {
 			
 				throw new DataUnavailable();
 		}
+		
+		private void addMonitor(JMonitor mon) {
+			if(monitors==null) {
+				monitors=new LinkedList<JavaMonitor>();
+				
+			}
+			
+			monitors.add(mon);
+			
+			
+		}
+		private void addStackFrame(JStackFrame frame) {
+			frames.add(frame);
+			
+			
+		}
 		@Override
 		public ImagePointer getJNIEnv() throws CorruptDataException {
 			
@@ -256,14 +454,50 @@
 		}
 		@Override
 		public int getState() throws CorruptDataException {
-			// TODO Auto-generated method stub
+			
 			return 0;
 		}
 	}
 	
+	class JClassLoader implements JavaClassLoader {
+
+		private List<JavaClass> classes=null;
+		
+		@Override
+		public JavaClass findClass(String name) throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		private void addClass(JClass c) {
+			if(classes==null) classes=new LinkedList<JavaClass>();
+			classes.add(c);
+			
+		}
+
+		@Override
+		public Iterator getCachedClasses() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public Iterator getDefinedClasses() {
+			if(classes==null) classes=new LinkedList<JavaClass>();
+			return classes.iterator();
+		}
+
+		@Override
+		public JavaObject getObject() throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+		
+	}
 	class JClass implements JavaClass{
 		   int classid=0;
 		   int superclassid=0;
+		   JClassLoader classloader=null;
 		    short status=0;
 		    short modifiers=0;
 		    short fieldCount=0;
@@ -273,8 +507,8 @@
 			String classSig=null;
 			@Override
 			public JavaClassLoader getClassLoader() throws CorruptDataException {
-				// TODO Auto-generated method stub
-				return null;
+				
+				return classloader;
 			}
 			@Override
 			public JavaClass getComponentType() throws CorruptDataException {
@@ -449,7 +683,112 @@
 		
 	}
 
-	public Iterator getThreadIterator() {
-		return threadMap.values().iterator();
+	class JStackFrame implements JavaStackFrame {
+
+		private JLocation location=null;
+		@Override
+		public ImagePointer getBasePointer() throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public Iterator getHeapRoots() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public JavaLocation getLocation() throws CorruptDataException {
+			
+				return location;
+		}
+		
+	}
+	
+	class JLocation implements JavaLocation {
+
+		private JMethod method=null;
+		String filename=null;
+		
+		@Override
+		public ImagePointer getAddress() throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public int getCompilationLevel() throws CorruptDataException {
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		@Override
+		public String getFilename() throws DataUnavailable,
+				CorruptDataException {
+			
+			return filename;
+		}
+
+		@Override
+		public int getLineNumber() throws DataUnavailable, CorruptDataException {
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		@Override
+		public JavaMethod getMethod() throws CorruptDataException {
+			return method;
+		}
+		
+	}
+	
+	class JMethod implements JavaMethod {
+
+		
+		private String name=null;
+		private String signature=null;
+		private int mods=0;
+		private JClass parent=null;
+		
+		
+		public JMethod() {
+			
+		}
+		
+		@Override
+		public Iterator getBytecodeSections() {
+		
+			return null;
+		}
+
+		@Override
+		public Iterator getCompiledSections() {
+			return null;
+		}
+
+		@Override
+		public JavaClass getDeclaringClass() throws CorruptDataException,
+				DataUnavailable {
+			
+			return parent;
+		}
+
+		@Override
+		public int getModifiers() throws CorruptDataException {
+			
+			return mods;
+		}
+
+		@Override
+		public String getName() throws CorruptDataException {
+			return name;
+		}
+
+		@Override
+		public String getSignature() throws CorruptDataException {
+			return signature;
+		}
+		
 	}
 }