Some help for a netbeans patch?

I have a RFE in the netbeans OQL console (operates on heap dumps) for some time with no movement. I want the ability to find overallocated Stream/Reader buffers in a heap dump. So i wrote a JS query to propose a patch, but i don’t know JS, and this query didn’t give me any results in my little test. It is also copied from the “Overallocated Strings” query there, but i deleted one of the function calls inside map because i really didn’t understand it, so its probably that. The query is also probably duplicating things but as a first attempt i want to put it showing the instance i know it should accuse in my test code.

Notice that i’m accessing the “in” and “out” fields as if they were public, (they are private or protected) but i thought that JS Rhino allowed that. Anyway, the catch body never triggers.

Original overallocated string query:


function overallocation(it) {
    return (2 * it.offset) + (2 * (it.value.length - (1*it.count + 1*it.offset)));
}

function showOAinfo(it) {
    return toHtml(it) + " wasting " + overallocation(it) + "b";
}

function overallocationdiff(lhs, rhs) {
    return overallocation(rhs) - overallocation(lhs);
}

map(top(heap.objects("java.lang.String", false, 'overallocation(it) > 0'), overallocationdiff), showOAinfo);

My query:


var duplicated;

function overAllocationFilterInputStream(it) {
    try { 
    while(it instanceof java.io.FilterInputStream){
        var stream = it["in"];
        if(stream instanceof java.io.BufferedInputStream ||
            stream instanceof java.io.ByteArrayInputStream ||
            stream instanceof java.io.StringBufferInputStream ||
            stream instanceof java.io.PipedInputStream){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}
function overAllocationFilterOutputStream(it) {
    try { 
    while(it instanceof java.io.FilterOutputStream){
        var stream = it["out"];
        if(stream instanceof java.io.BufferedOutputStream ||
            stream instanceof java.io.ByteArrayOutputStream ||
            stream instanceof java.io.PipedOutputStream){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}

function overAllocationReader(it) {
    try { 
    while(it instanceof java.io.BufferedReader ||
            it instanceof java.io.FilterReader){
        var stream = it["in"];
        if(stream instanceof java.io.BufferedReader ||
            stream instanceof java.io.PipedReader ||
            stream instanceof java.io.CharArrayReader ||
            stream instanceof java.io.StringReader){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}

function overAllocationWriter(it) {
    try { 
    while(it instanceof java.io.BufferedWriter ||
            it instanceof java.io.FilterWriter){
        var stream = it["out"];
        if(stream instanceof java.io.BufferedWriter ||
            stream instanceof java.io.PipedWriter ||
            stream instanceof java.io.CharArrayWriter ||
            stream instanceof java.io.StringWriter){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}

function showOAinfo(it) {
    return toHtml(it) + " buffers data that " + toHtml(duplicated) + " also does, one of them probably should be eliminated.";
}

//these must buffer data AND be in a chain
map(heap.objects("java.util.zip.InflaterInputStream", false, 'overAllocationFilterInputStream(it)'), showOAinfo);
map(heap.objects("java.io.BufferedInputStream", false, 'overAllocationFilterInputStream(it)'), showOAinfo);
map(heap.objects("java.util.zip.DeflaterOutputStream", false, 'overAllocationFilterOutputStream(it)'), showOAinfo);
map(heap.objects("java.io.BufferedOutputStream", false, 'overAllocationFilterOutputStream(it)'), showOAinfo);
map(heap.objects("java.io.BufferedReader", false, 'overAllocationReader(it)'), showOAinfo);
map(heap.objects("java.io.BufferedWriter", false, 'overAllocationReader(it)'), showOAinfo);

Any idea whats wrong?

Also tried with explicit reflection … didn’t find anything too…

code

Ok found the specs of the functions in netbeans help.

Apparently the problem appears to be that the parser is retarded, and can’t handle things before the select (in pure OQL). However the string query above works, is not using OQL syntax but pure javascript. Can’t reproduce it.

Edit: shit. i can’t believe this, the language has a instanceof keyword but it doesn’t work?

Ok finally did it:
Was wrong before is right now.

Finally understood this code is almost useless, since when it is triggered, there is a very low probability of catching the offending objects in the dump. Any way to hook a dump into the gc of a class or something like that?


var duplicated;

function instanceOf(it, other){
    c2 = heap.findClass(other);
    if(c2 == null)
        return false;
    c1 = classof(it);
    return c1 == c2 || c1.isSubclassOf(c2);
}

function overAllocationFilterInputStream(it) {
    while(instanceOf(it, "java.io.FilterInputStream")){
        stream = it["in"];
        if(instanceOf(stream, "java.io.BufferedInputStream") ||
           instanceOf(stream, "java.io.ByteArrayInputStream") ||
           instanceOf(stream, "java.io.StringBufferInputStream") ||
           instanceOf(stream, "java.io.PipedInputStream")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationFilterOutputStream(it) {
    while(instanceOf(it, "java.io.FilterOutputStream")){
        stream = it["out"];
        if(instanceOf(stream,  "java.io.BufferedOutputStream") ||
           instanceOf(stream,  "java.io.ByteArrayOutputStream") ||
           instanceOf(stream, "java.io.PipedOutputStream")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationReader(it) {
    while(instanceOf(it, "java.io.BufferedReader") || instanceOf(it, "java.io.FilterReader")){
        stream = it["in"];
        if(instanceOf(stream, "java.io.BufferedReader") ||
           instanceOf(stream, "java.io.PipedReader") ||
           instanceOf(stream, "java.io.CharArrayReader") ||
           instanceOf(stream, "java.io.StringReader")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationWriter(it) {
    while(instanceOf(it, "java.io.BufferedWriter") || instanceOf(it, "java.io.FilterWriter")){
        stream = it["out"];
        if(instanceOf(stream, "java.io.BufferedWriter") ||
           instanceOf(stream, "java.io.PipedWriter") ||
           instanceOf(stream, "java.io.CharArrayWriter") ||
           instanceOf(stream, "java.io.StringWriter")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function showOAinfo(it) {
    return toHtml(it) + " buffers data that " + toHtml(duplicated) + " also does, one of them probably should be eliminated.";
}

map(
concat(
concat(
concat(
concat(
concat(
heap.objects("java.util.zip.InflaterInputStream", false, 'overAllocationFilterInputStream(it)'),
heap.objects("java.io.BufferedInputStream", false, 'overAllocationFilterInputStream(it)')), 
heap.objects("java.util.zip.DeflaterOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedReader", false, 'overAllocationReader(it)')),
heap.objects("java.io.BufferedWriter", false, 'overAllocationWriter(it)')), showOAinfo);