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, ¤tThread);
(*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);