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 mo...@apache.org on 2009/09/28 15:22:11 UTC

svn commit: r819582 - in /incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native: ./ include/

Author: monteith
Date: Mon Sep 28 15:22:07 2009
New Revision: 819582

URL: http://svn.apache.org/viewvc?rev=819582&view=rev
Log:
Merge and commit Paul Sobek's changes from KATO-9

Modified:
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addClass.c
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addField.c
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addObject.c
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addThreads.c
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/cjvmti.c
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addClass.h
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addField.h
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addObject.h
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addThreads.h
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/cjvmti.h
    incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/queue.c

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addClass.c
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addClass.c?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addClass.c (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addClass.c Mon Sep 28 15:22:07 2009
@@ -18,6 +18,9 @@
 #include "addField.h"
 #include "addObject.h"
 
+
+int addMethodDetails(jclass class);
+
 struct JClass * addClassDetails(jclass class) {
 	jint field_count;
 	jvmtiError err;
@@ -57,14 +60,14 @@
 		return NULL;
 	}
 	statusP = 0;
-	/// Try do something with this before the call...
-	
+	// Make a call to check for errors on this class
 	err = (*env)->GetClassStatus(env, class, &statusP);
 	if (err != JVMTI_ERROR_NONE){
 		printf("Class is not loaded \n");
 		return NULL;
 	}
-	//printf("Status %d \n", statusP);
+	
+	// Check class is valid before attempting to save any information about it.
 	(*env)->GetClassModifiers(env, class, &classMods);
 	//if (statusP == 0 || statusP & 8){
 	if (!(statusP == 7 || statusP == 16 || statusP == 32 || (statusP == 3 && (classMods & 0x0200 || classMods & 0x0400)))){
@@ -75,9 +78,10 @@
 	
 	err = (*env)->GetTag(env, class, &tag);
 	if (err != JVMTI_ERROR_NONE) {
-		printDepth--;
 		return NULL;
 	}
+
+	// Check if this has already been added, but as an object, not a class object.
 	classObject = 0;
 	if (tag!=0){
 		oldObj = (void *)tag;
@@ -89,14 +93,20 @@
 
 	
 
-	// Follow class hierarchy from the bottom up, reduces recursion which isn't currently prevented on classes, only object
+	
 	if (tag == 0 || classObject) {
 		FSEEK(variableFile, 0, SEEK_END);
+
+		// Follow class hierarchy from the bottom up, reduces recursion which isn't currently prevented on classes, only object
+
+		// Calculate bottom depth
 		superClazz = class;
 		while (superClazz != 0) {
 			level++;
 			superClazz = (*jniptr)->GetSuperclass(jniptr, superClazz);
 		}
+
+		// Work back up adding the class details.
 		superClazz = class;
 		while (level != 0) {
 			superClazz = class;
@@ -113,66 +123,71 @@
 			FSEEK(variableFile, 0, SEEK_END);
 		}
 
-		addClassDetails((*jniptr)->GetSuperclass(jniptr, class)); // Ensure we know everything about this class hierarchy before beginning
+
+		addClassDetails((*jniptr)->GetSuperclass(jniptr, class)); // Ensure we know everything about 
+		//this class hierarchy before beginning, should return immediately
+
+		// Begin writing class details
 		FSEEK(variableFile, 0, SEEK_END);
 		err = (*env)->GetClassSignature(env, class, &name_ptr, &genSig_ptr);
 		if (err != JVMTI_ERROR_NONE){
-			printf(" ERROR ! \n ");
+			(*env)->Deallocate(env, (unsigned char*)genSig_ptr);
+			(*env)->Deallocate(env, (unsigned char*)name_ptr);
+			printf(" Unexpected JVMTI error %d \n", err);
 			abort();
 		}
-		printfd("--- Not seen this class before, allocate %s ---\n", name_ptr);
+
 		tag = (long) (struct JClass *) calloc(1, sizeof(struct JClass));
+
 		if (tag == (long) NULL) {
-			printfd("--- Failed to malloc ---\n");
-			printDepth--;
+			printf("Failed to malloc class \n");
 			abort();
-			return NULL;
 		}
 		
 		err = (*env)->SetTag(env, class, tag);
-		Q_enqueue(&class, toDetag);
+
+		Q_enqueue(&class, toDetag); // Add to deallocate queue
+
 		jcls = (void *) tag;
-		if (classObject){
-			// TODO free old object memory!
+
+		if (classObject){ // If this was previously just an object copy object information and deallocate old object.
 			jcls->obj = (*oldObj);
 			free(oldObj);
 		}
 		jcls->positionInFile = FTELL(variableFile);
-		jcls->obj.isClass = 1;
+		jcls->obj.isClass = 1; // Indicates its a class object
 		staticsCount++;
 		
 		writeIDNoSize(CJVMTI_CLASS, variableFile);
 		writeJint(classMods, variableFile);
 		writeString(name_ptr, variableFile);
-		//printf(" %s \n", name_ptr);
-
 		sourceFileName = 0;
 		err = (*env)->GetSourceFileName(env, class, &sourceFileName);
 		if (err != JVMTI_ERROR_NONE || sourceFileName == 0) {
+			(*env)->Deallocate(env, (unsigned char*)sourceFileName);
 			writeString("NoSource", variableFile);
 		} else {
 			writeString(sourceFileName, variableFile);
 			(*env)->Deallocate(env, (unsigned char*)sourceFileName);
 		}
+
 		if (genSig_ptr != 0){
 			writeString(genSig_ptr, variableFile);
 			(*env)->Deallocate(env, (unsigned char*)genSig_ptr);
 		}else {
+			(*env)->Deallocate(env, (unsigned char*)genSig_ptr);
 			writeString(" ", variableFile);
 		}
 	} else {
-		jcls = (void *) tag;
-		printDepth--;
+		jcls = (void *) tag; // Already disocvered so return class.
 		return jcls;
 	}
 
 	err = (*env)->GetClassFields(env, class, &field_count, &fields);
 	if (err != JVMTI_ERROR_NONE) {
 		jcls->numInstanceFields = 0;
-		printDepth--;
-		printf(" No class fields \n");
+		printf("Unexpected JVMTI error %d \n", err);
 		abort();
-		return jcls;
 	}
 
 	addMethodDetails(class);
@@ -191,6 +206,7 @@
 		}
 	}
 	jcls->numStaticFields = staticFieldCount;
+
 	// malloc space for them..
 	jcls->numInstanceFields = instanceFieldCount;
 	jcls->instanceModifiers
@@ -203,16 +219,14 @@
 			* instanceFieldCount);
 
 	if (jcls->instanceFields == NULL) {
-		printfd("--- Malloc failed end Class details ---\n");
+		printf("Failed to malloc instance fields\n");
 		abort();
-		printDepth--;
-		return NULL;
 	}
 
 	writeIDNoSize(CJVMTI_CLASS_INSTANCE_FIELDS, variableFile);
 	writeJint(instanceFieldCount, variableFile);
 
-	// occupy struct with instance fields so we can save objects correctly and also write out to file
+	// occupy struct with instance fields so we can save objects correctly
 	countUp = 0;
 	for (i = 0; i < field_count; i++) {
 		(*env)->GetFieldModifiers(env, class, fields[i], &modifiers);
@@ -220,9 +234,8 @@
 			err = (*env)->GetFieldName(env, class, fields[i], &name_ptr,
 					&signature_ptr, &genSig_ptr);
 			if (err != JVMTI_ERROR_NONE) {
-				printf("Error getting field name \n");
+				printf("Error getting field name %d \n", err);
 				abort();
-				break;
 			}
 
 			writeJint(modifiers, variableFile);
@@ -235,7 +248,6 @@
 				writeString(genSig_ptr, variableFile);
 			}
 
-			printfd("Field %s type %s \n", name_ptr, signature_ptr);
 			instanceFieldCount--;
 			assert(instanceFieldCount > -1);
 			jcls->instanceFields[countUp] = fields[i];
@@ -253,17 +265,16 @@
 		}
 	}
 
+	// write out static field details, these only need saving to the dump file.
 	writeIDNoSize(CJVMTI_CLASS_STATIC_FIELDS, variableFile);
 	writeJint(staticFieldCount, variableFile);
-
-	// write out static field details
+	genSig_ptr = NULL;
 	for (i = 0; i < field_count; i++) {
 		(*env)->GetFieldModifiers(env, class, fields[i], &modifiers);
 		if ((modifiers & 0x0008)) {
 			err = (*env)->GetFieldName(env, class, fields[i], &name_ptr,
 					&signature_ptr, &genSig_ptr);
 			if (err != JVMTI_ERROR_NONE) {
-				printfd("Getting field name for class error %d\n", err);
 				break;
 			}
 
@@ -273,6 +284,7 @@
 			writeString(signature_ptr, variableFile);
 			if (genSig_ptr == 0) {
 				writeString(" ", variableFile);
+				(*env)->Deallocate(env, (unsigned char*)genSig_ptr);
 			} else {
 				writeString(genSig_ptr, variableFile);
 				(*env)->Deallocate(env, (unsigned char*)genSig_ptr);
@@ -282,9 +294,9 @@
 		}
 	}
 
-	jcls->staticFieldLoc = (FPOS_T *) malloc(sizeof(FPOS_T) * staticFieldCount); // References to static fields
 
 	// make space for all references in file.
+
 	fieldPos = FTELL(variableFile);
 	writeIDNoSize(CJVMTI_SUPERCLASS_FIELDS, variableFile);
 	fwrite(&waitingToBeWritten, sizeof(FPOS_T), 1, variableFile); // super class reference
@@ -311,6 +323,8 @@
 
 
 	FGETPOS(variableFile, &fieldPosCheck); //Alignment check for end
+	
+	// Follow references
 
 	FSEEK(variableFile, 0, SEEK_END);
 	jcls->superClass = addClassDetails((*jniptr)->GetSuperclass(jniptr, class));
@@ -334,17 +348,19 @@
 		fieldPos = FTELL(variableFile);
 		FSEEK(variableFile, 0, SEEK_END);
 	}
-	if (interfaceCount > 0)(*env)->Deallocate(env, (unsigned char*)interfaces);
+	(*env)->Deallocate(env, (unsigned char*)interfaces);
 	(*env)->Deallocate(env, (unsigned char*)fields);
 
 	jcls->staticFieldStart = fieldPos;
 	FSEEK(variableFile, 0, SEEK_END);
-	Q_enqueue(&class, qStaticFields);
+	Q_enqueue(&class, qStaticFields); // Add to class queue to resolve static field references
 	return jcls;
 }
 
-struct JClass * addStaticFields(jclass class) {
+// Resolves static field references
+struct JClass * getClassReferences(jclass class) {
 	FPOS_T fieldPos;
+	FPOS_T reference;
 	jfieldID * fields = NULL;
 	jint field_count;
 	int i;
@@ -360,17 +376,20 @@
 	if (jcls == NULL) {
 		return NULL;
 	}
-	if (jcls->filledIn) {
+	if (jcls->filledIn) {// Indicates references have already been resolved
 		return jcls;
 	}
+
 	staticFieldCount = jcls->numStaticFields;
 	FSEEK(variableFile, jcls->staticFieldStart, SEEK_SET);
+
 	writeIDNoSize(CJVMTI_CLASS_STATIC_FIELDS, variableFile);
 	fieldPos = FTELL(variableFile);
 	FSEEK(variableFile, 0, SEEK_END);
 	err = (*env)->GetClassFields(env, class, &field_count, &fields);
 	(*env)->GetClassLoader(env, class, &classloader);
-
+	
+	// Follow each reference, then save
 	for (i = 0; i < field_count; i++) {
 		err = (*env)->GetFieldName(env, class, fields[i], &name_ptr,
 				&signature_ptr, &genSig_ptr);
@@ -383,15 +402,14 @@
 		(*env)->GetFieldModifiers(env, class, fields[i], &modifiers);
 		if (modifiers & 0x0008) {
 			staticFieldCount--;
-
-			jcls->staticFieldLoc[staticFieldCount]
-					= addFieldValue(CJVMTI_STATIC_VAR, class, fields[i],
-							signature_ptr, 0, 0, 0);
+			reference = 0;
+			reference = addFieldValue(CJVMTI_STATIC_VAR, class, fields[i],
+							signature_ptr, 0, 0, 0, 0);
 			FSETPOS(variableFile, &fieldPos);
-			writeReference(jcls->staticFieldLoc[staticFieldCount], variableFile);
+			writeReference(reference, variableFile);
 
-			// check its adding a true reference
-			if (jcls->staticFieldLoc[staticFieldCount] == waitingToBeWritten) {
+			// check its added a true reference
+			if (reference == waitingToBeWritten) {
 				printf("Circular reference, abort \n");
 				abort();
 			}
@@ -402,13 +420,16 @@
 		(*env)->Deallocate(env, (unsigned char *) name_ptr);
 		(*env)->Deallocate(env, (unsigned char *) signature_ptr);
 		(*env)->Deallocate(env, (unsigned char *) genSig_ptr);
+		name_ptr = NULL;
+		signature_ptr = NULL;
+		genSig_ptr = NULL;
 	}
 
 	// write class loader details to file
 	
 	FSEEK(variableFile, 0, SEEK_END);
 	if (classloader != 0) {
-		jcls->classLoader = addObject(classloader)->positionInFile;
+		jcls->classLoader = addObject(classloader, 0)->positionInFile;
 	} else {
 		jcls->classLoader = CJVMTI_NULL_OBJECT;
 	}
@@ -419,7 +440,7 @@
 	FSEEK(variableFile, 0, SEEK_END);
 
 	printDepth--;
-	jcls->filledIn = 1;
+	jcls->filledIn = 1; // Indicate class has been resolved
 	staticsCount--;
 	(*env)->Deallocate(env, (unsigned char *)fields);
 	return jcls;
@@ -433,7 +454,7 @@
 
 int addMethodDetails(jclass class) {
 	jint method_count;
-	jmethodID * method_ptr;
+	jmethodID * method_ptr = NULL;
 	jvmtiError err;
 	char * mname = NULL;
 	char * msig = NULL;
@@ -448,6 +469,7 @@
 	writeIDNoSize(CJVMTI_METHOD, variableFile);
 	err = (*env)->GetClassMethods(env, class, &method_count, &method_ptr);
 	if (err != JVMTI_ERROR_NONE) {
+		(*env)->Deallocate(env, (unsigned char *) method_ptr);
 		method_count = 0;
 	}
 	writeJint(method_count, variableFile);
@@ -470,6 +492,7 @@
 			(*env)->Deallocate(env, (unsigned char *) mgenSig);
 		} else {
 			writeString(" ", variableFile);
+			(*env)->Deallocate(env, (unsigned char *) mgenSig);
 		}
 		mname = NULL;
 		msig = NULL;
@@ -502,7 +525,7 @@
 			
 			
 		}
-		if (err == JVMTI_ERROR_NONE && varCount > 0) (*env)->Deallocate(env, (unsigned char *) table);
+		(*env)->Deallocate(env, (unsigned char *) table);
 		table = NULL;
 
 		// Line number table
@@ -515,14 +538,14 @@
 				writeJint(lnt_ptr[i2].line_number, variableFile);
 				writeReference(lnt_ptr[i2].start_location, variableFile);
 			}
-			if (varCount > 0){
-				(*env)->Deallocate(env, (unsigned char *) lnt_ptr);
-			}
+			
 		}
+		(*env)->Deallocate(env, (unsigned char *) lnt_ptr);
+		lnt_ptr = NULL;
 
 	}
 
-	if (method_count > 0)(*env)->Deallocate(env, (unsigned char *) method_ptr);
+	(*env)->Deallocate(env, (unsigned char *) method_ptr);
 	return 1;
 }
 

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addField.c
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addField.c?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addField.c (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addField.c Mon Sep 28 15:22:07 2009
@@ -16,141 +16,156 @@
 #include "cjvmti.h"
 #include "addObject.h"
 #include "addClass.h"
-FPOS_T addFieldValue(int type, jobject obj, jfieldID field, char * signature,
-		jthread thread, jint depth, jint slot) {
 
-	// Primitives
+typedef union{
+	jbyte * bArray;
+	jchar * cArray;
+	jdouble * dArray;
+	jfloat * fArray;
+	jint * iArray;
+	jlong * jArray;
+	jshort * sArray;
+	jboolean * zArray;
+} primArrays;
+
+typedef union{
 	jbyte b;
 	jchar c;
 	jdouble d;
 	jfloat f;
 	jint i;
 	jlong j;
-	jobject l;
 	jshort s;
 	jboolean z;
+} primitives;
+
+// Saves a field to the dump file returning the position in the file it was saved to.
+// type indicates where the field value came from instance, local or static.
+FPOS_T addFieldValue(int type, jobject obj, jfieldID field, char * signature,
+		jthread thread, jint depth, jint slot, int referenceDepth) {
+
+	// Primitives
+	
+	primitives prim;
 
 	// Arrays
-	jbyte * bArray;
-	jchar * cArray;
-	jdouble * dArray;
-	jfloat * fArray;
-	jint * iArray;
-	jlong * jArray;
-	jshort * sArray;
-	jboolean * zArray;
+	
+	primArrays primArr;
+
 	int szArray;
+	int tempI;
 	jobject arrayElement;
-
+	jobject l = 0;
 	jboolean isCopy;
-
 	jvmtiError err;
 	int counter;
 	FPOS_T position = -1;
 	FPOS_T * arrayFields;
 	struct JClass * arrayType;
+		tempI = 0;
+		memset(&primArr, 0, sizeof(primArr));
+		memset(&prim, 0, sizeof(prim));
+
 	position = FTELL(variableFile);
 	switch (*signature) {
 	case 'B':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			b = (*jniptr)->GetByteField(jniptr, obj, field);
+			prim.b = (*jniptr)->GetByteField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalInt(env, thread, depth, slot, &i);
-			b = (jbyte) i;
+			err = (*env)->GetLocalInt(env, thread, depth, slot, &tempI);
+			prim.b = (jbyte) tempI;
 			break;
 		case CJVMTI_STATIC_VAR:
-			b = (*jniptr)->GetStaticByteField(jniptr, obj, field);
+			prim.b = (*jniptr)->GetStaticByteField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %d \n", type, *signature, b);
 		writeIDNoSize(CJVMTI_BYTE, variableFile);
-		fwrite(&b, sizeof(jbyte), 1, variableFile);
+		fwrite(&prim.b, sizeof(jbyte), 1, variableFile);
 		break;
 	case 'C':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			c = (*jniptr)->GetCharField(jniptr, obj, field);
+			prim.c = (*jniptr)->GetCharField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalInt(env, thread, depth, slot, &i);
-			c = (jchar) i;
+			err = (*env)->GetLocalInt(env, thread, depth, slot, &tempI);
+			prim.c = (jchar) tempI;
 			break;
 		case CJVMTI_STATIC_VAR:
-			c = (*jniptr)->GetStaticCharField(jniptr, obj, field);
+			prim.c = (*jniptr)->GetStaticCharField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %c \n", type, *signature, c);
 		writeIDNoSize(CJVMTI_CHAR, variableFile);
-		fwrite(&c, sizeof(jchar), 1, variableFile);
+		fwrite(&prim.c, sizeof(jchar), 1, variableFile);
 		break;
 	case 'D':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			d = (*jniptr)->GetDoubleField(jniptr, obj, field);
+			prim.d = (*jniptr)->GetDoubleField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalDouble(env, thread, depth, slot, &d);
+			err = (*env)->GetLocalDouble(env, thread, depth, slot, &prim.d);
 			break;
 		case CJVMTI_STATIC_VAR:
-			d = (*jniptr)->GetStaticDoubleField(jniptr, obj, field);
+			prim.d = (*jniptr)->GetStaticDoubleField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %f \n", type, *signature, d);
 		writeIDNoSize(CJVMTI_DOUBLE, variableFile);
-		fwrite(&d, sizeof(jdouble), 1, variableFile);
+		fwrite(&prim.d, sizeof(jdouble), 1, variableFile);
 		break;
 	case 'F':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			f = (*jniptr)->GetFloatField(jniptr, obj, field);
+			prim.f = (*jniptr)->GetFloatField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalFloat(env, thread, depth, slot, &f);
+			err = (*env)->GetLocalFloat(env, thread, depth, slot, &prim.f);
 			break;
 		case CJVMTI_STATIC_VAR:
-			f = (*jniptr)->GetStaticFloatField(jniptr, obj, field);
+			prim.f = (*jniptr)->GetStaticFloatField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %f \n", type, *signature, f);
 		writeIDNoSize(CJVMTI_FLOAT, variableFile);
-		fwrite(&f, sizeof(jfloat), 1, variableFile);
+		fwrite(&prim.f, sizeof(jfloat), 1, variableFile);
 
 		break;
 	case 'I':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			i = (*jniptr)->GetIntField(jniptr, obj, field);
+			prim.i = (*jniptr)->GetIntField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalInt(env, thread, depth, slot, &i);
+			err = (*env)->GetLocalInt(env, thread, depth, slot, &prim.i);
 			break;
 		case CJVMTI_STATIC_VAR:
-			i = (*jniptr)->GetStaticIntField(jniptr, obj, field);
+			prim.i = (*jniptr)->GetStaticIntField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %d \n", type, *signature, i);
 		writeIDNoSize(CJVMTI_INT, variableFile);
-		fwrite(&i, sizeof(jint), 1, variableFile);
+		fwrite(&prim.i, sizeof(jint), 1, variableFile);
 		break;
 	case 'J':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			j = (*jniptr)->GetLongField(jniptr, obj, field);
+			prim.j = (*jniptr)->GetLongField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalLong(env, thread, depth, slot, &j);
+			err = (*env)->GetLocalLong(env, thread, depth, slot, &prim.j);
 			break;
 		case CJVMTI_STATIC_VAR:
-			j = (*jniptr)->GetStaticLongField(jniptr, obj, field);
+			prim.j = (*jniptr)->GetStaticLongField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %ld \n", type, *signature, j);
 		writeIDNoSize(CJVMTI_LONG, variableFile);
-		fwrite(&j, sizeof(jlong), 1, variableFile);
+		fwrite(&prim.j, sizeof(jlong), 1, variableFile);
 		break;
 	case 'L':
+		if (maxReferenceDepth != 0 && maxReferenceDepth <= referenceDepth){
+			writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
+			break;
+		}
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
 			l = (*jniptr)->GetObjectField(jniptr, obj, field);
@@ -158,7 +173,7 @@
 		case CJVMTI_LOCAL_VAR:
 			err = (*env)->GetLocalObject(env, thread, depth, slot, &l);
 			if (err != JVMTI_ERROR_NONE) {
-				printfd("error %d\n", err);
+				printf("Error getting local object %d\n", err);
 			}
 			break;
 		case CJVMTI_STATIC_VAR:
@@ -169,65 +184,57 @@
 		}
 
 		if (l != 0) {
-			printfd("Type %d %s %d\n", type, signature, l);
-			position = addObject(l)->positionInFile;
-			printfd("Position %lld \n", position);
+			position = addObject(l, referenceDepth+1)->positionInFile;
 		} else {
-			printfd(
-					"Null Object, need to standardise how to represent this..\n");
 			writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 		}
 		break;
 	case 'S':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			s = (*jniptr)->GetShortField(jniptr, obj, field);
+			prim.s = (*jniptr)->GetShortField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalInt(env, thread, depth, slot, &i);
-			s = (jshort) i;
+			err = (*env)->GetLocalInt(env, thread, depth, slot, &tempI);
+			prim.s = (jshort) tempI;
 			break;
 		case CJVMTI_STATIC_VAR:
-			s = (*jniptr)->GetStaticShortField(jniptr, obj, field);
+			prim.s = (*jniptr)->GetStaticShortField(jniptr, obj, field);
 			break;
 		}
-		printfd("Type %d %c %hd \n", type, *signature, s);
 		writeIDNoSize(CJVMTI_SHORT, variableFile);
-		fwrite(&s, sizeof(jshort), 1, variableFile);
+		fwrite(&prim.s, sizeof(jshort), 1, variableFile);
 		break;
 	case 'Z':
 		switch (type) {
 		case CJVMTI_INSTANCE_VAR:
-			z = (*jniptr)->GetBooleanField(jniptr, obj, field);
+			prim.z = (*jniptr)->GetBooleanField(jniptr, obj, field);
 			break;
 		case CJVMTI_LOCAL_VAR:
-			err = (*env)->GetLocalInt(env, thread, depth, slot, &i);
-			z = (jboolean) i;
+			err = (*env)->GetLocalInt(env, thread, depth, slot, &tempI);
+			prim.z = (jboolean) tempI;
 			break;
 		case CJVMTI_STATIC_VAR:
-			z = (*jniptr)->GetStaticBooleanField(jniptr, obj, field);
+			prim.z = (*jniptr)->GetStaticBooleanField(jniptr, obj, field);
 			break;
 		}
-		if (z) {
-			printfd("Type %d %c true \n", type, *signature);
-		} else {
-			printfd("Type %d %c false \n", type, *signature);
-		}
 		writeIDNoSize(CJVMTI_BOOLEAN, variableFile);
-		fwrite(&z, sizeof(jboolean), 1, variableFile);
+		fwrite(&prim.z, sizeof(jboolean), 1, variableFile);
 
 		break;
 	case '[':
 		signature++;
 		if ((*signature == 'L') || (*signature == '[')) {
+			if (maxReferenceDepth != 0 && maxReferenceDepth <= referenceDepth){
+				writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
+				break;
+			}
 			switch (type) {
 			case CJVMTI_INSTANCE_VAR:
 				l = (*jniptr)->GetObjectField(jniptr, obj, field);
 				break;
 			case CJVMTI_LOCAL_VAR:
 				err = (*env)->GetLocalObject(env, thread, depth, slot, &l);
-				if (err != JVMTI_ERROR_NONE)
-					printfd("Error %d \n", err);
 				break;
 			case CJVMTI_STATIC_VAR:
 				l = (*jniptr)->GetStaticObjectField(jniptr, obj, field);
@@ -237,7 +244,6 @@
 				break;
 			}
 			if (l == 0) {
-				printfd("NULL array\n");
 				writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 			} else {
 				FSEEK(variableFile, 0, SEEK_END);
@@ -246,24 +252,29 @@
 				szArray = (*jniptr)->GetArrayLength(jniptr, l);
 				arrayFields = NULL;
 				if (szArray > 0) {
+					// Save field references in memory
 					arrayFields = malloc(sizeof(FPOS_T) * szArray);
 					for (counter = 0; counter < szArray; counter++) {
 						FSEEK(variableFile, 0, SEEK_END);
 						arrayElement = (*jniptr)->GetObjectArrayElement(jniptr,
 								l, counter);
 						if (arrayElement == 0) {
-							printfd("Null array element \n");
 							arrayFields[counter] = CJVMTI_NULL_OBJECT;
 						} else {
-							printfd("Follow array\n");
 							arrayFields[counter] = addFieldValue(
 									CJVMTI_ARRAY_VAR, arrayElement, 0,
-									(arrayType->name) + 1, 0, 0, 0);
+									(arrayType->name) + 1, 0, 0, 0, referenceDepth+1);
+							if (arrayFields[counter] == 0){
+								printf("Found left over ref\n");
+								(*jniptr)->DeleteLocalRef(jniptr, arrayElement);
+							}
 						}
 					}
 				}
 				FSEEK(variableFile, 0, SEEK_END);
 				position = FTELL(variableFile);
+
+				// Write out array references / array 
 				writeIDNoSize(CJVMTI_OBJECT_ARRAY, variableFile);
 				writeReference(arrayType->positionInFile, variableFile);
 				writeJint(szArray, variableFile);
@@ -286,8 +297,6 @@
 				break;
 			case CJVMTI_LOCAL_VAR:
 				err = (*env)->GetLocalObject(env, thread, depth, slot, &l);
-				if (err != JVMTI_ERROR_NONE)
-					printfd("Error %d \n", err);
 				break;
 			case CJVMTI_STATIC_VAR:
 				l = (*jniptr)->GetStaticObjectField(jniptr, obj, field);
@@ -297,9 +306,7 @@
 				break;
 			}
 			// TODO correct this, do we have a null object before we declare the class type, or use the signature..
-			printfd("get byte array \n");
 			if (l == 0) {
-				printfd("NULL primitive array\n");
 				writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				break;
 			}
@@ -316,160 +323,135 @@
 			//	Z 	boolean 	true or false
 			case 'B':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_BYTE_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					bArray
+					primArr.bArray
 							= (*jniptr)->GetByteArrayElements(jniptr, l,
 									&isCopy);
-					printfd("");
 
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%d", bArray[counter]);
-						fwrite(&bArray[counter], sizeof(jbyte), 1, variableFile);
+						fwrite(&primArr.bArray[counter], sizeof(jbyte), 1, variableFile);
 					}
-					(*jniptr)->ReleaseByteArrayElements(jniptr, l, bArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseByteArrayElements(jniptr, l, primArr.bArray,JNI_ABORT);
 				}
 				break;
 			case 'C':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_CHAR_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					cArray
+					primArr.cArray
 							= (*jniptr)->GetCharArrayElements(jniptr, l,
 									&isCopy);
-					printfd("");
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%c", cArray[counter]);
-						fwrite(&cArray[counter], sizeof(jchar), 1, variableFile);
+						fwrite(&primArr.cArray[counter], sizeof(jchar), 1, variableFile);
 					}
-					(*jniptr)->ReleaseCharArrayElements(jniptr, l, cArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseCharArrayElements(jniptr, l, primArr.cArray,JNI_ABORT);
 				}
 				break;
 			case 'D':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_DOUBLE_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
 
-					dArray = (*jniptr)->GetDoubleArrayElements(jniptr, l,
+					primArr.dArray = (*jniptr)->GetDoubleArrayElements(jniptr, l,
 							&isCopy);
-
-					printfd("");
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%f", dArray[counter]);
-						fwrite(&dArray[counter], sizeof(jdouble), 1,
+						fwrite(&primArr.dArray[counter], sizeof(jdouble), 1,
 								variableFile);
 					}
-					(*jniptr)->ReleaseDoubleArrayElements(jniptr, l, dArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseDoubleArrayElements(jniptr, l, primArr.dArray,JNI_ABORT);
 				}
 				break;
 			case 'F':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_FLOAT_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					fArray = (*jniptr)->GetFloatArrayElements(jniptr, l,
+					primArr.fArray = (*jniptr)->GetFloatArrayElements(jniptr, l,
 							&isCopy);
-					printfd("");
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%f", fArray[counter]);
-						fwrite(&fArray[counter], sizeof(jfloat), 1,
+						fwrite(&primArr.fArray[counter], sizeof(jfloat), 1,
 								variableFile);
 					}
-					(*jniptr)->ReleaseFloatArrayElements(jniptr, l, fArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseFloatArrayElements(jniptr, l, primArr.fArray,JNI_ABORT);
 				}
 				break;
 			case 'I':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_INT_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					iArray = (*jniptr)->GetIntArrayElements(jniptr, l, &isCopy);
-					printfd("");
+					primArr.iArray = (*jniptr)->GetIntArrayElements(jniptr, l, &isCopy);
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%d", iArray[counter]);
-						fwrite(&iArray[counter], sizeof(jint), 1, variableFile);
+						fwrite(&primArr.iArray[counter], sizeof(jint), 1, variableFile);
 					}
-					(*jniptr)->ReleaseIntArrayElements(jniptr, l, iArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseIntArrayElements(jniptr, l, primArr.iArray,JNI_ABORT);
 				}
 				break;
 
 			case 'J':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_LONG_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					jArray
+					primArr.jArray
 							= (*jniptr)->GetLongArrayElements(jniptr, l,
 									&isCopy);
-					printfd("");
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%ld ", jArray[counter]);
-						fwrite(&jArray[counter], sizeof(jlong), 1, variableFile);
+						fwrite(&primArr.jArray[counter], sizeof(jlong), 1, variableFile);
 					}
-					(*jniptr)->ReleaseLongArrayElements(jniptr, l, jArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseLongArrayElements(jniptr, l, primArr.jArray,JNI_ABORT);
 				}
 				break;
 			case 'S':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_SHORT_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					sArray = (*jniptr)->GetShortArrayElements(jniptr, l,
+					primArr.sArray = (*jniptr)->GetShortArrayElements(jniptr, l,
 							&isCopy);
-					printfd("");
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%d ", sArray[counter]);
-						fwrite(&sArray[counter], sizeof(jshort), 1,
+						fwrite(&primArr.sArray[counter], sizeof(jshort), 1,
 								variableFile);
 					}
-					(*jniptr)->ReleaseShortArrayElements(jniptr, l, sArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseShortArrayElements(jniptr, l, primArr.sArray,JNI_ABORT);
 				}
 				break;
 			case 'Z':
 				if (l == 0) {
-					printfd("NULL primitive array\n");
 					writeIDNoSize(CJVMTI_NULL_OBJECT, variableFile);
 				} else {
 					writeIDNoSize(CJVMTI_BOOLEAN_ARRAY, variableFile);
 					writeJint(szArray, variableFile);
-					zArray = (*jniptr)->GetBooleanArrayElements(jniptr, l,
+					primArr.zArray = (*jniptr)->GetBooleanArrayElements(jniptr, l,
 							&isCopy);
-					printfd("");
 					for (counter = 0; counter < szArray; counter++) {
-						printfR("%ld ", zArray[counter]);
-						fwrite(&zArray[counter], sizeof(jboolean), 1,
+						fwrite(&primArr.zArray[counter], sizeof(jboolean), 1,
 								variableFile);
 					}
-					(*jniptr)->ReleaseBooleanArrayElements(jniptr, l, zArray,JNI_ABORT);
-					printfR("\n");
+					(*jniptr)->ReleaseBooleanArrayElements(jniptr, l, primArr.zArray,JNI_ABORT);
 				}
 				break;
 			}
 		}
 	}
+	/*free(bArray);
+	free(cArray);
+	free(dArray);
+	free(fArray);
+	free(iArray);
+	free(jArray);
+	free(sArray); 
+	free(zArray); */
 	return position;
 }

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addObject.c
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addObject.c?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addObject.c (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addObject.c Mon Sep 28 15:22:07 2009
@@ -18,35 +18,50 @@
 #include "addObject.h"
 #include "addClass.h"
 #include "addField.h"
-struct JObject * addObject(jobject obj) {
-	jclass clazz;
-	if (obj == 0){
-		printf("NULL object! \n");
-		abort();
-		return &nullObject;
-	}
-	clazz = (*jniptr)->GetObjectClass(jniptr, obj);
-	return getObjectInfo(clazz, obj);
-}
-
 
-struct JObject * getObjectInfo(jclass class, jobject obj) {
+struct JObject * addObject(jobject obj, int depth) {
 	int i;
 	jlong tag;
 	jvmtiError err;
+	jclass class;
 	struct JClass * clazz;
 	struct JClass * tempClazz;
 	struct JObject * objp = NULL;
 	FPOS_T fieldValLoc;
 	jint totalFieldCount;
 	int classObject = 0;
+	
+	if (maxReferenceDepth != 0 && maxReferenceDepth <= depth){
+		return &nullObject; // We have followed to max reference depth so return null
+	}
+	
+	// Cover all cases of null classes / jni references / invalid classes
+
+	if (obj == NULL) return &nullObject; // Unexpected.
+
+	// Check if we have already referenced this object
+	err = (*env)->GetTag(env, obj, &tag);
+	if (tag == 0){
+		class = (*jniptr)->GetObjectClass(jniptr, obj);
+		if (class == NULL){
+			(*jniptr)->DeleteLocalRef(jniptr, obj);
+			(*jniptr)->DeleteLocalRef(jniptr, class);
+			return &nullObject;
+		}
+		clazz = addClassDetails(class);
+	}else{
+		class = (*jniptr)->GetObjectClass(jniptr, obj);
+		clazz = addClassDetails(class);
+		//(*jniptr)->DeleteLocalRef(jniptr, class);
+	}
+
+
+	if (obj == NULL || class == NULL) return &nullObject; // Unexpected
 
-	if (obj == NULL || class == NULL) return &nullObject;
-	clazz = addClassDetails(class); // grab the declaring class and ensure hierarchy is built for fields
-	//addClassDetails(obj); // check if this is a class object
 	if (clazz == NULL){
 		return &nullObject;
 	}
+
 	if (clazz->positionInFile == 0) {
 		objp = (void *) clazz;
 		printf("Invalid class location %p %lld %lld \n", clazz,
@@ -55,67 +70,62 @@
 		abort();
 	}
 
-	printDepth++;
-
-	if (clazz == NULL) {
-		printfd("Null class, abort\n");
-		abort();
-	}
-
-	err = (*env)->GetTag(env, obj, &tag);
-	if (err != JVMTI_ERROR_NONE) {
-		printfR("Could not retrieve tag/object %d \n", err);
-		printDepth--;
-		return objp;
-	}
-
+	// Check if what is tagged is actually a class object and needs filling in
 	if (tag != 0) {
 		objp = (void *) tag;
-		if (!objp->state) {
+		if (!objp->state) { // Check it has not previously been filled in 
 			objp->isClass = 1;
 			classObject = 1;
 		}else{
+			if (objp->depth > depth && maxReferenceDepth != 0){ // Check depth is not lower from this reference
+				objp->depth = depth;
+				//printf("Lower depth from here %d %s ! \n", objp->state, clazz->name);
+				objp->state = 1;}
 			return objp;
 		}
 	}
 
 	if (tag == 0 || classObject) {
-		printfd("--- Not seen this object before, save it ---\n");
 		if (!classObject)
 			tag = (jlong) calloc(1, sizeof(struct JObject));
+
 		if ((void *) tag == NULL) {
-			printfd("--- Failed to malloc ---\n");
-			printDepth--;
-			return objp;
+			printf("Failed to malloc object \n");
+			abort();
 		}
 
 		if (!classObject){
 			err = (*env)->SetTag(env, obj, tag);
-			Q_enqueue(&obj, toDetag);
+			Q_enqueue(&obj, toDetag); // Add object to deallocation queue
 		}
-		if (err != JVMTI_ERROR_NONE) {
+
+		if (err != JVMTI_ERROR_NONE) { // Check tag was set
 			printf("JVMTI Error %d \n", err);
-			printDepth--;
 			return objp;
 		}
+
 		FSEEK(variableFile, 0, SEEK_END);
 
 		// Work out how many fields we need to save across the hierarchy
 		tempClazz = clazz;
 		totalFieldCount = 0;
-
 		while (tempClazz) {
 			totalFieldCount += tempClazz->numInstanceFields;
 			tempClazz = tempClazz->superClass;
 		}
 
-		objp = (void *) tag;
+		objp = (void *) tag; // Set pointer
 		if (!classObject) objp->isClass = 0;
-		objp->state = 1;
+
+		objp->state = 1; // Indicates object has been written (but references not followed)
+
+		if (maxReferenceDepth!=0)objp->depth = depth; // Set reference depth
+
 		FSEEK(variableFile, 0, SEEK_END);
 		objp->positionInFile = FTELL(variableFile);
-		writeIDNoSize(CJVMTI_OBJECT, variableFile);
 
+		// Prepare space in dump file
+		writeIDNoSize(CJVMTI_OBJECT, variableFile);
 		writeReference(clazz->positionInFile, variableFile);
 		writeJint(totalFieldCount, variableFile);
 		fieldValLoc = FTELL(variableFile);
@@ -123,11 +133,11 @@
 			fwrite(&waitingToBeWritten, sizeof(FPOS_T), 1, variableFile);
 		}
 
-		objp->referenceLocation = fieldValLoc;
-		objp->totalFieldCount = totalFieldCount;
+		objp->referenceLocation = fieldValLoc; // used to write references into file
+		objp->totalFieldCount = totalFieldCount; // used to write references into file
 		FSEEK(variableFile, 0, SEEK_END);
 		objectCount++;
-		Q_enqueue(&obj, qObjects);
+		Q_enqueue(&obj, qObjects); // Queue this object to have its references followed
 	}
 	return objp;
 }
@@ -137,28 +147,33 @@
 	FPOS_T fieldValLoc;
 	FPOS_T fieldValue;
 	jlong tag;
+	jclass tempClass;
 	struct JObject * objp;
 	struct JClass * clazz;
 	struct JClass * tempClazz;
 	int totalFieldCount;
+
 	(*env)->GetTag(env, obj, &tag);
 	objp = (struct JObject *) tag;
-	if (objp->state == 2) {
+	if (objp->state == 2) { // Already had its reference resolved
 		objectCount--;
 		return objp;
 	}
-	clazz = addClassDetails((*jniptr)->GetObjectClass(jniptr, obj));
+
+	tempClass = (*jniptr)->GetObjectClass(jniptr, obj);
+	clazz = addClassDetails(tempClass);
+	(*jniptr)->DeleteLocalRef(jniptr, tempClass);
 	totalFieldCount = objp->totalFieldCount;
 	fieldValLoc = objp->referenceLocation;
 	FSEEK(variableFile, 0, SEEK_END);
+
 	// Loop through saving the references to file
 	tempClazz = clazz;
 	while (tempClazz) {
-		// TODO We only need an array of max size of a superclass fields
 		for (i = 0; i < tempClazz->numInstanceFields; i++) {
 			fieldValue = addFieldValue(CJVMTI_INSTANCE_VAR, obj,
 					tempClazz->instanceFields[i],
-					tempClazz->instanceFieldSignatures[i], 0, 0, 0);
+					tempClazz->instanceFieldSignatures[i], 0, 0, 0, objp->depth+1);
 			if (fieldValue == waitingToBeWritten){
 				printf("Error unwritten reference\n");
 				abort();
@@ -166,7 +181,7 @@
 			FSETPOS(variableFile, &fieldValLoc);
 			writeReference(fieldValue, variableFile);
 			if (fieldValue == waitingToBeWritten) {
-				printfd("Circular reference \n");
+				printf("Circular reference \n");
 				abort();
 			}
 			fieldValLoc = FTELL(variableFile);
@@ -175,7 +190,7 @@
 		tempClazz = tempClazz->superClass;
 	}
 	objectCount--;
-	objp->state = 2;
+	objp->state = 2; // Object full resolved
 	printDepth--;
 	return objp;
 }

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addThreads.c
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addThreads.c?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addThreads.c (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/addThreads.c Mon Sep 28 15:22:07 2009
@@ -23,22 +23,22 @@
 	int aliveVarCount;
 	jvmtiError err;
 	jint varCount;
-	jvmtiLocalVariableEntry * table;
+	jvmtiLocalVariableEntry * table = NULL;
 	FPOS_T refLoc;
 	FPOS_T tempLoc;
 	aliveVarCount = 0;
 	printDepth++;
-	err = (*env)->GetLocalVariableTable(env, methodID, &varCount, &table);
-	if (err != JVMTI_ERROR_NONE) {
-		printfd("JVMTI Error \n");
-		writeIDNoSize(CJVMTI_JVMTI_ERROR, variableFile);
+	
+	if (loc == -1) {
 		printDepth--;
+		writeIDNoSize(CJVMTI_LOCAL_NATIVECALL, variableFile);
 		return 0;
 	}
-	if (loc == -1) {
-		printfd("Executing native method\n");
+	err = (*env)->GetLocalVariableTable(env, methodID, &varCount, &table);
+	if (err != JVMTI_ERROR_NONE) {
+		writeIDNoSize(CJVMTI_JVMTI_ERROR, variableFile);
 		printDepth--;
-		writeIDNoSize(CJVMTI_LOCAL_NATIVECALL, variableFile);
+		(*env)->Deallocate(env, (unsigned char*)table);
 		return 0;
 	}
 	writeIDNoSize(CJVMTI_LOCAL_VARIABLE, variableFile);
@@ -51,7 +51,6 @@
 			aliveVarCount++;
 		}
 	}
-
 	writeJint(aliveVarCount, variableFile);
 	refLoc = FTELL(variableFile);
 	for (i = 0; i < aliveVarCount; i++) {
@@ -68,14 +67,16 @@
 			refLoc = FTELL(variableFile);
 			FSEEK(variableFile, 0, SEEK_END);
 			tempLoc = addFieldValue(CJVMTI_LOCAL_VAR, NULL, NULL,
-					table[i].signature, *thread, depth, table[i].slot);
+					table[i].signature, *thread, depth, table[i].slot, 0);
 			FSEEK(variableFile, refLoc, SEEK_SET);
 			writeReference(tempLoc, variableFile);
 			(*env)->Deallocate(env, (unsigned char*)table[i].generic_signature);
 			(*env)->Deallocate(env, (unsigned char*)table[i].name);
 			(*env)->Deallocate(env, (unsigned char*)table[i].signature);
 		} else {
-			printfd("Not currently in slot, ignore\n");
+			(*env)->Deallocate(env, (unsigned char*)table[i].generic_signature);
+			(*env)->Deallocate(env, (unsigned char*)table[i].name);
+			(*env)->Deallocate(env, (unsigned char*)table[i].signature);
 		}
 	}
 	(*env)->Deallocate(env, (unsigned char*)table);
@@ -89,7 +90,7 @@
 	FPOS_T dClassPos;
 	FPOS_T position;
 
-	char* methodName;
+	char* methodName = NULL;
 	struct JClass * declClazz;
 	printDepth++;
 	err = (*env)->GetMethodName(env, info->method, &methodName, NULL, NULL);
@@ -97,9 +98,13 @@
 	if (err != JVMTI_ERROR_NONE) {
 		position = FTELL(variableFile);
 		writeIDNoSize(CJVMTI_JVMTI_ERROR, variableFile);
-		return position;
+		(*env)->Deallocate(env, (unsigned char*)methodName);
+		printf("Unexpected JVMTI error %d \n", err);
+		abort();
 	}
 	FSEEK(variableFile, 0, SEEK_END);
+
+	// Add declaring class reference
 	if (declClass != 0) {
 		declClazz = addClassDetails(declClass);
 		if (declClazz != NULL){
@@ -118,6 +123,7 @@
 	writeReference(dClassPos, variableFile);
 
 	getLocVars(info->method, info->location, thread, depth);
+
 	printDepth--;
 	(*env)->Deallocate(env, (unsigned char*)methodName);
 	return position;
@@ -126,13 +132,13 @@
 
 FPOS_T getThreadInfo(jthread * thread) {
 	int i;
-	int maxDepth = 5;
+	int maxDepth = 0;
 	jvmtiThreadInfo info;
-	jvmtiFrameInfo frames[5];
+	jvmtiFrameInfo  * frames;
 	jvmtiError err;
 
 	jint ownedMonitorCount;
-	jobject * ownedObjects;
+	jobject * ownedObjects = NULL;
 
 	jobject contendedObject;
 	struct JObject * monObj;
@@ -142,11 +148,18 @@
 	FPOS_T position;
 	FPOS_T refLoc;
 	FPOS_T tempRef;
-
+	if (maxFrameDepth != 0){
+		maxDepth = maxFrameDepth;
+		frames = malloc(sizeof (jvmtiFrameInfo) * maxDepth);
+	}else{
+		maxDepth = 20;
+		frames = malloc(sizeof (jvmtiFrameInfo) * maxDepth);
+	}
 	printDepth++;
-
+	info.name = NULL;
 	err = (*env)->GetThreadInfo(env, *thread, &info);
 	if (err != JVMTI_ERROR_NONE) {
+		(*env)->Deallocate(env, (unsigned char*)info.name);
 		printf("No thread info %d \n ", err);
 		abort();
 	}
@@ -160,14 +173,29 @@
 		ownedMonitorCount = 0;
 	}
 	err = (*env)->GetStackTrace(env, *thread, 0, maxDepth, frames, &frameCount);
-	if (err != JVMTI_ERROR_NONE) {
-		frameCount = 0;
+		if (err != JVMTI_ERROR_NONE) {
+			frameCount = 0;
+		}
+	while (maxFrameDepth == 0 && frameCount == maxDepth ){
+		printf("Had to double frame buffer, recommend limiting stack depth current buffer size: %d\n", maxDepth *2);
+		free(frames);
+		maxDepth = maxDepth * 2;
+		frames = malloc(sizeof (jvmtiFrameInfo) * maxDepth);
+		err = (*env)->GetStackTrace(env, *thread, 0, maxDepth, frames, &frameCount);
+		if (err != JVMTI_ERROR_NONE) {
+			frameCount = 0;
+		}
 	}
+	printf("Thread %s Number of frames %d\n", info.name, frameCount);
+
 
+	// Prepare space in dump file for all information queried 
 	position = FTELL(variableFile);
 	writeIDNoSize(CJVMTI_THREAD, variableFile);
 	writeString(info.name, variableFile);
-	writeReference(addObject(*thread)->positionInFile, variableFile);
+	(*env)->Deallocate(env, (unsigned char*)info.name);
+	info.name = NULL;
+	writeReference(addObject(*thread, 0)->positionInFile, variableFile);
 	writeJint(info.priority, variableFile);
 	writeBool(info.is_daemon, variableFile);
 	writeJint(ownedMonitorCount, variableFile);
@@ -181,11 +209,13 @@
 	for (i = 0; i < frameCount; i++) {
 		writeReference(waitingToBeWritten, variableFile); // Stack frames
 	}
-
-	// Allocated space, fill references
+	
+	// Allocated space, now follow references
 	FSEEK(variableFile, 0, SEEK_END);
 	for (i = 0; i < ownedMonitorCount; i++) {
-		monObj = addObject(ownedObjects[i]);
+
+		monObj = addObject(ownedObjects[i], 0);
+
 		FSEEK(variableFile, refLoc, SEEK_SET);
 		writeReference(monObj->positionInFile, variableFile);
 		refLoc = FTELL(variableFile);
@@ -194,7 +224,9 @@
 	(*env)->Deallocate(env, (unsigned char*)ownedObjects);
 	ownedObjects = NULL;
 	if (contendedObject != 0) {
-		monObj = addObject(contendedObject);
+
+		monObj = addObject(contendedObject, 0);
+
 		FSEEK(variableFile, refLoc, SEEK_SET);
 		writeReference(monObj->positionInFile, variableFile);
 	} else {
@@ -206,13 +238,15 @@
 	refLoc = FTELL(variableFile);
 	FSEEK(variableFile, 0, SEEK_END);
 	for (i = 0; i < frameCount; i++) {
+
 		tempRef = getFrameInfo(i, &frames[i], thread);
+
 		FSEEK(variableFile, refLoc, SEEK_SET);
 		writeReference(tempRef, variableFile);
 		refLoc = FTELL(variableFile);
 		FSEEK(variableFile, 0, SEEK_END);
 	}
-
+	free(frames);
 	return position;
 }
 
@@ -226,31 +260,35 @@
 	int i;
 
 	err = (*env)->GetAllThreads(env, &threadCount, &threads);
+
+	// Prepare space in file
 	writeIDNoSize(CJVMTI_THREAD, variableFile);
 	writeJint(threadCount, variableFile);
 	refLoc = FTELL(variableFile);
 	for (i = 0; i < threadCount; i++) {
-		writeReference(waitingToBeWritten, variableFile); // Prepare reference space in file
+		writeReference(waitingToBeWritten, variableFile); 
 	}
+	printf("%d threads \n", threadCount);
 	check = FTELL(variableFile);
 	for (i = 0; i < threadCount; i++) {
-		clearObjectQueue();
-		addObject(threads[i]); // Add all thread objects
+		//clearObjectQueue();
+		addObject(threads[i], 0); // Add all thread objects
 	}
-	printf(" Q size %d \n", Q_size(qObjects));
 
+
+	// Now fill in all references
 	FSEEK(variableFile, 0, SEEK_END);
 	for (i = 0; i < threadCount; i++) {
+
 		ref = getThreadInfo(&threads[i]);
+
 		FSEEK(variableFile, refLoc, SEEK_SET);
 		writeReference(ref, variableFile);
 		refLoc = FTELL(variableFile);
 		FSEEK(variableFile, 0, SEEK_END);
 	}
 
-
 	clearObjectQueue();
 	(*env)->Deallocate(env, (unsigned char*)threads);
-	printfd("--- Finished following threads ---\n");
 	return 1;
 }

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/cjvmti.c
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/cjvmti.c?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/cjvmti.c (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/cjvmti.c Mon Sep 28 15:22:07 2009
@@ -12,6 +12,27 @@
  * limitations under the License.
  ******************************************************************************/
 
+/****
+
+CJVMTI v0.1
+-> indicates what this can possibly call 
+addThreads -> addObject & addClass
+addObject -> addClass & addObject & queues objects
+addClass -> addClass & queues classes
+objectQueues -> getObjectReferences
+getObjectReferences -> addField
+addField -> addObject
+classQueue -> getStaticReferences
+getStaticReferences -> addObject
+
+addObject and addClass both can function without following any references and allocate the required space in the dump file
+This means calling them can happen at any point with no adverse effects (running out of stack.)
+They are tagged so that any references to them are resolved to their position in the dump file.
+Its only once the dump is completed that the references are followed by clearing the class and object queue. These both generate
+many more references that need to be added to the queues. This two step process means all reference loops are easily avoided as references
+can always be written as the reference is only a pointer inside the file.
+
+****/
 
 #include "cjvmti.h"
 #include "addThreads.h"
@@ -19,15 +40,15 @@
 #include "addClass.h"
 #include "addObject.h"
 
-
-static int logFile = 0;
+int jvmtiVersion = 11;
+int dumping = 0; // Used to ensure two dumps aren't attempted at the same time
+static int logFile = 0; 
 int initAgent();
 
 // Provides printing to log/stdout
 void printfR(const char * _Format, ...) {
 	va_list args;
 	va_start(args, _Format);
-	assert(printDepth > -1);
 	//vprintf(_Format, args);
 
 	va_end(args);
@@ -66,28 +87,7 @@
 	return 1;
 }
 
-// Write a CJVMTI constant and make space to write the size of the following structure, returns the location in the file where the size needs to be written
-FPOS_T writeID(char id, FILE * fp) {
-	FPOS_T pos;
-	FPOS_T ident = 0x7fffffffffffffffL;
-	fwrite(&id, sizeof(char), 1, fp);
-	pos = FTELL(fp);
-	fwrite(&ident, sizeof(FPOS_T), 1, fp);
-	return pos;
-}
-
-// Works out and writes the size of the enclosed structure, sizeWrite is the position to write the size into
-int writeSize(FPOS_T sizeWrite, FILE * fp) {
-	FPOS_T pos;
-	FGETPOS(fp, &pos);
-	FSETPOS(fp, &sizeWrite);
-	sizeWrite = pos - sizeWrite;
-	fwrite(&sizeWrite, sizeof(FPOS_T), 1, fp);
-	FSEEK(fp, 0, SEEK_END);
-	return 1;
-}
-
-// Writes a null terminated string, needs replacing
+// Writes a null terminated string, needs replacing to specifying the number of characters
 int writeString(char * tString, FILE * fp) {
 	fputs(tString, fp);
 	fputc(0, fp);
@@ -101,9 +101,6 @@
 
 // Used for writing longs and file position, needs splitting up
 int writeReference(FPOS_T pt, FILE * fp) {
-	//if (pt == waitingToBeWritten) {
-	//	abort();
-	//}
 	fwrite(&pt, sizeof(FPOS_T), 1, fp);
 	return 1;
 }
@@ -118,7 +115,43 @@
 	return 1;
 }
 
+void JNICALL
+Exception(jvmtiEnv *jvmti_env,
+		  JNIEnv* jni_env,
+		  jthread thread,
+		  jmethodID method,
+		  jlocation location,
+		  jobject exception,
+		  jmethodID catch_method,
+		  jlocation catch_location){
+			  jvmtiPhase phas;
+			  char * sig;
+			  char * gSig;
+			  jclass clazz;
+
+			  if (catch_method == NULL){
+				  if (!dumping){
+					  dumping = 1;
+					  printf("Exception %d \n \n \n", catch_method);
+					  dataDumpRequest(jvmti_env);
+				  }
+			  }/*else{ // For apache tomcat demo.
+				  if (exception != NULL ){
+					  clazz = (*jni_env)->GetObjectClass(jni_env, exception);
+					  (*env)->GetClassSignature(env, clazz, &sig, &gSig);
+					  if (!strcmp(sig, "Ljava/lang/ArrayIndexOutOfBoundsException;")){
+						  if (!dumping){
+							  dumping = 1;
+							  printf("Exception %d \n \n \n", catch_method);
+							  dataDumpRequest(jvmti_env);
+						  }
+					  }
+				  }
+			  }*/
+			  return;
+}
 
+// Clears through reference queue
 int clearObjectQueue() {
 	jclass clazz;
 	jobject obj;
@@ -129,13 +162,13 @@
 			getObjectReferences(obj);
 		}
 		if(clazz != 0){
-			addStaticFields(clazz);
+			getClassReferences(clazz);
 		}
 	}
 	return 1;
 }
 
-// Ensures references are within range, useful for testing
+// Ensures references are within the files range, useful for testing
 int checkReference(FPOS_T loc, FILE * fp) {
 	FPOS_T fileSize;
 	FPOS_T currentLoc = FTELL(fp);
@@ -158,7 +191,7 @@
 static void JNICALL dataDumpRequest(jvmtiEnv *jvmti) {
 	int i;
 	jint rc;
-	jthread currentThread;
+	jthread currentThread = 0;
 	jlong tag;
 	jobject deTagObj;
 	struct JObject * deAlObj;
@@ -166,18 +199,33 @@
 	jthread * suspendedThreads;
 	jint numSuspendedThreads;
 	env = jvmti;
-	rc = (*vmptr)->GetEnv(vmptr, (void **) &jniptr, JNI_VERSION_1_6);
-	if (rc != JVMTI_ERROR_NONE) {
-		printf("Unable to load JNI environment");
-		return;
+	dumping = 1;
+	if (jniptr == NULL){
+		rc = (*vmptr)->GetEnv(vmptr, (void **) &jniptr, JNI_VERSION_1_4);
+		if (rc != JVMTI_ERROR_NONE) {
+			printf("Unable to load JNI environment");
+			return;
+		}
 	}
+
+	(*jniptr)->PushLocalFrame(jniptr, 5000); // Automatically deallocates local references when popped
+
 	nullObject.positionInFile = CJVMTI_NULL_OBJECT;
-	initAgent();
 
+	initAgent(); // Prepare dump file
+
+
+	printf("Get current thread \n");
 	(*jvmti)->GetCurrentThread(jvmti, &currentThread);
 
 
 	(*env)->SetTag(env, currentThread, 1);
+	
+	if (currentThread == 0){
+		printf("Null thread returned \n");
+	}else{
+	}
+	(*env)->SetTag(env, currentThread, 1); // So we can skip pausing the agent thread
 	rc = (*env)->GetAllThreads(env, &numSuspendedThreads, &suspendedThreads);
 	printf("Suspend the VM threads \n");
 	printf("Current thread is %llx \n", currentThread);
@@ -190,13 +238,15 @@
 		}
 	}
 	(*env)->SetTag(env,currentThread, 0);
-	printf("Creating dump file \n");
 
+	printf("Creating dump \n");
 	qObjects = Q_initQueue(100, sizeof(jobject));
 	qStaticFields = Q_initQueue(100, sizeof(jclass));
 	toDetag = Q_initQueue(200, sizeof(jobject));
-
 	followAllThreads();
+
+	// Dump finished
+
 	if (fp!=NULL)fclose(fp);
 	fp = NULL;
 	fclose(variableFile);
@@ -207,7 +257,6 @@
 		if (tag == 0)continue; // We sometimes free an object from earlier in the queue if it went from an object to a class object
 		deAlObj = (struct JObject *)tag;
 		if (deAlObj->isClass){
-			// TODO isClass is set before add object
 			deAlClass = (struct JClass *) tag;
 
 			for (i = 0; i < deAlClass->numInstanceFields; i++){
@@ -219,7 +268,6 @@
 			free(deAlClass->instanceFields);
 			free(deAlClass->instanceFieldSignatures);
 			free(deAlClass->instanceModifiers);
-			free(deAlClass->staticFieldLoc);
 
 
 		}
@@ -237,14 +285,73 @@
 	Q_free(qStaticFields);
 
 	(*env)->Deallocate(env, (unsigned char *)suspendedThreads);
-	printf("Left over object %d \n", objectCount);
-	printf("Left over static fields %d \n", staticsCount);
 	printf("Finished creating dump file \n");
+	(*jniptr)->PopLocalFrame(jniptr, NULL); // Clears local references
+	dumping = 0;
 }
 
+int setEnvironment(JavaVM * vm){
+	jint rc;
+	jvmtiError err;
+	char * errorName;
+	jvmtiCapabilities caps;
+	jvmtiEventCallbacks callbacks;
+	errorName = NULL;
+	rc = (*vm)->GetEnv(vm, (void **) &env, JVMTI_VERSION_1_1);
+	if (rc != JNI_OK) {
+		printf("--- Cannot connect to JNI ---\n");
+		if(rc == JNI_EVERSION){
+			printf(" Incompatible version \n");
+		}
+		return rc;
+	}
+	memset(&callbacks, 0, sizeof(callbacks));
+	callbacks.DataDumpRequest = &dataDumpRequest;
+	callbacks.Exception = &Exception;
+
+	err = (*env)->SetEventCallbacks(env, &callbacks, sizeof(callbacks));
+	if (err != JVMTI_ERROR_NONE)
+		printf("Could not set callbacks");
+
+
+	err = (*env)->SetEventNotificationMode(env, JVMTI_ENABLE,
+			JVMTI_EVENT_DATA_DUMP_REQUEST, (jthread) NULL);
+
+	memset(&caps, 0, sizeof(jvmtiCapabilities));
+
+	caps.can_get_owned_monitor_info = 1;
+	caps.can_get_current_contended_monitor = 1;
+	caps.can_get_monitor_info = 1;
+	caps.can_access_local_variables = 1;
+	caps.can_tag_objects = 1;
+	caps.can_generate_exception_events = 1;
+	caps.can_get_source_file_name = 1;
+	caps.can_get_line_numbers = 1;
+	caps.can_signal_thread = 1;
+	caps.can_suspend = 1;
+
+	err = (*env)->AddCapabilities(env, &caps);
+	if (err != JVMTI_ERROR_NONE)
+		printf("can't turn on required capabilites\n");
+
+	err = (*env)->SetEventNotificationMode(env, JVMTI_ENABLE,
+		JVMTI_EVENT_EXCEPTION, (jthread) NULL);
+
+	if (err != JVMTI_ERROR_NONE)
+		printf("Could not set event notification %d \n", err);
+
+
+	err = (*env)->CreateRawMonitor(env, "cbmonitor", &lock);
+	if (err != JVMTI_ERROR_NONE)
+		printf("cannot create monitor");
+	fp = NULL;
+	variableFile = NULL;
+	return 1;
+}
+
+
 int initAgent(){
 	static int dumpCount;
-
 	time_t creationTime;
 	struct tm  * dumpTime;
 	char fileName[50];
@@ -254,9 +361,12 @@
 	staticsCount = 0;
 	printDepth = 0;
 	logFile = 0;
-#ifdef __DEBUG_CJVMTI__
-	_CrtDumpMemoryLeaks();
-#endif
+
+	#ifdef __DEBUG_CJVMTI__
+		_RPT0(_CRT_WARN,"Trace\n");
+		_CrtDumpMemoryLeaks();
+	#endif
+
 	if (logFile) {
 		printf("Open log file\n");
 		fp = fopen("CJVMTI_debug.txt", "wb+");
@@ -344,8 +454,6 @@
       FILE_ATTRIBUTE_NORMAL, NULL);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, hLogFile);
-
-	printf("Memory leak \n");
 	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 	_CrtDumpMemoryLeaks();
 #endif
@@ -356,8 +464,11 @@
 Agent_OnUnload(JavaVM *vm) {
 #ifdef __DEBUG_CJVMTI__
 	_RPT0(_CRT_WARN,"file message\n");
-   CloseHandle(hLogFile);
+	CloseHandle(hLogFile);
 #endif
 	if (fp != NULL) fclose(fp);
-	if (fp != NULL) fclose(variableFile);
+	if (variableFile != NULL) fclose(variableFile);
+	//(*env)->DisposeEnvironment(env);
+
+	printf("Agent released \n");
 }

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addClass.h
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addClass.h?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addClass.h (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addClass.h Mon Sep 28 15:22:07 2009
@@ -17,6 +17,5 @@
 #define addClass_H_
 #include "cjvmti.h"
 struct JClass * addClassDetails(jclass class);
-struct JClass * addStaticFields(jclass class);
-int addMethodDetails(jclass class);
+struct JClass * getClassReferences(jclass class);
 #endif

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addField.h
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addField.h?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addField.h (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addField.h Mon Sep 28 15:22:07 2009
@@ -17,5 +17,5 @@
 #define addField_H_
 #include "cjvmti.h"
 FPOS_T addFieldValue(int type, jobject obj, jfieldID field, char * signature,
-		jthread thread, jint depth, jint slot);
+		jthread thread, jint depth, jint slot, int referenceDepth);
 #endif

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addObject.h
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addObject.h?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addObject.h (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addObject.h Mon Sep 28 15:22:07 2009
@@ -16,7 +16,6 @@
 #ifndef addObject_H_
 #define addObject_H_
 #include "cjvmti.h"
-struct JObject * addObject(jobject obj);
-struct JObject * getObjectInfo(jclass class, jobject obj);
+struct JObject * addObject(jobject obj, int depth);
 struct JObject * getObjectReferences(jobject obj);
 #endif

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addThreads.h
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addThreads.h?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addThreads.h (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/addThreads.h Mon Sep 28 15:22:07 2009
@@ -16,8 +16,5 @@
 #ifndef addThreads_H_
 #define addThreads_H_
 #include "cjvmti.h"
-int getLocVars(jmethodID methodID, jlocation loc, jthread * thread, int depth);
-FPOS_T getFrameInfo(int depth, jvmtiFrameInfo * info, jthread * thread);
-FPOS_T getThreadInfo(jthread * thread);
 int followAllThreads();
 #endif

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/cjvmti.h
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/cjvmti.h?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/cjvmti.h (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/include/cjvmti.h Mon Sep 28 15:22:07 2009
@@ -15,10 +15,11 @@
 #ifndef CJVMTI_H_
 #define CJVMTI_H_
 
+// Cross platform file operations all based on __int64
 #ifdef __linux__
 #define _FILE_OFFSET_BITS 64
 #elif WIN32
-// Uncomment to detect memory leaks
+// Uncomment to detect memory leaks with visual c++
 //#define __DEBUG_CJVMTI__
 #endif
 
@@ -41,20 +42,20 @@
 #define FSEEK(x,y,z) fseeko((x),(y),(z))
 #define FTELL(x) ftello((x))
 #define FGETPOS(x,y) (*(y))=ftello((x))
-#define FSETPOS(x,y) fseeko((x), (*(y)), SEEK_SET)
-#elif   __aix__
+#define FSETPOS(x,y) fseeko((x), (*(y)), SEEK_SET)
+#elif   __aix__
 #define FPOS_T off_t
 #define FSEEK(x,y,z) fseeko((x),(y),(z))
 #define FTELL(x) ftello((x))
 #define FGETPOS(x,y) (*(y))=ftello((x))
-#define FSETPOS(x,y) fseeko((x), (*(y)), SEEK_SET)
+#define FSETPOS(x,y) fseeko((x), (*(y)), SEEK_SET)
 #elif   WIN32
 #define FPOS_T __int64
 #define FSEEK(x,y,z) _fseeki64((x),(y),(z))
 #define FTELL(x) _ftelli64((x))
 #define FGETPOS(x,y) (*(y))=_ftelli64((x))
-#define FSETPOS(x,y) _fseeki64((x), (*(y)), SEEK_SET)
-#else
+#define FSETPOS(x,y) _fseeki64((x), (*(y)), SEEK_SET)
+#else
 #error "unable to compile on this platform"
 #endif
 
@@ -63,24 +64,24 @@
 
 struct JObject {
 	int state; // 0 not prepared 1 prepared 2 is references filled
-	FPOS_T positionInFile;
-	FPOS_T referenceLocation;
-	int totalFieldCount;
-	char isClass;
+	FPOS_T positionInFile; // Actual object position in dump file
+	FPOS_T referenceLocation; // Used to store where references should be saved
+	int totalFieldCount; // Number of fields after following the superclass hierarchy
+	char isClass; // Identifies if this is a class object
+	char depth; // Used to limit depth references are followed to
 };
 
 struct JClass {
-	struct JObject obj;
-	int filledIn;
-	char * name; // dealloc from jvmti
-	FPOS_T positionInFile;
-	FPOS_T classLoader;
-	FPOS_T staticFieldStart;
-	struct JClass * superClass;
+	struct JObject obj; // Class object
+	int filledIn; // Check class has been correctly initialised
+	char * name; // Class name
+	FPOS_T positionInFile; // Actual position in dump file
+	FPOS_T classLoader; // Class loader position
+	FPOS_T staticFieldStart; // Where static fields should be saved
+	struct JClass * superClass; 
 	int numStaticFields;
-	FPOS_T * staticFieldLoc;
 	int numInstanceFields;
-	jfieldID * instanceFields; //
+	jfieldID * instanceFields; 
 	char * * instanceFieldSignatures; // each ref is jvmti, malloced normally
 	char * * instanceFieldGenSig; // each ref is jvmti, malloced normally
 	jint * instanceModifiers; // malloced normally
@@ -139,12 +140,14 @@
 JavaVM *vmptr;
 JNIEnv *jniptr;
 jrawMonitorID lock;
-FILE *fp;
-FILE *variableFile;
+FILE *fp; // log file
+FILE *variableFile; // dump file
+int maxReferenceDepth;
+int maxFrameDepth;
 int printDepth;
-struct queueADT * qObjects;
-struct queueADT * qStaticFields;
-struct queueADT * toDetag; // JObjects that need to be detagged and freed
+struct queueADT * qObjects; // References waiting to be followed in objects
+struct queueADT * qStaticFields; // References waiting to be followed in classes
+struct queueADT * toDetag; // Memory that needs to be freed/objects that need to be detagged
 long objectCount;
 long staticsCount;
 struct JObject nullObject;
@@ -160,11 +163,10 @@
 void printfR(const char * _Format, ...);
 void printfd(const char * _Format, ...);
 int writeIDNoSize(char id, FILE * fp);
-FPOS_T writeID(char id, FILE * fp) ;
-int writeSize(FPOS_T sizeWrite, FILE * fp);
 int writeString(char * tString, FILE * fp);
 int writeJint(jint i, FILE * fp);
 int writeReference(FPOS_T pt, FILE * fp);
 int writeLong(jlong j, FILE *fp);
 int writeBool(jboolean b, FILE * fp);
+static void JNICALL dataDumpRequest(jvmtiEnv *jvmti);
 #endif

Modified: incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/queue.c
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/queue.c?rev=819582&r1=819581&r2=819582&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/queue.c (original)
+++ incubator/kato/trunk/org.apache.kato/kato.native/kato.native.cjvmti/src/main/native/queue.c Mon Sep 28 15:22:07 2009
@@ -30,6 +30,7 @@
 static int id;
 int doubleSize(queueADT);
 
+// Call this to initialise the array list
 struct queueADT * Q_initQueue(int qsize, int sizeofElement){
 	void * pt;
 	struct queueADT * q = calloc(1, sizeof(struct queueADT));
@@ -83,6 +84,8 @@
 	return q->size;
 }
 
+
+// Expands the size of the queue (array list), copies values and deallocs the old array 
 int doubleSize(struct queueADT * q){
 	void * pt;
 	int i;
@@ -121,6 +124,7 @@
 	return 1;
 }
 
+
 int Q_free(struct queueADT * q){
 	id--;
 	free(q->queue);