Domanda

Mi piacerebbe conoscere la dimensione di un array allocato, cercando in bytecode, se tale informazione è nota al momento della compilazione, naturalmente.

Sfondo: voglio scrivere un rivelatore FindBugs (che guarda il bytecode compilato) e riportare alcune occorrenze di allocazioni di array. Al fine di filtrare i falsi positivi non sono interessato a "piccoli" array, ma solo quelli la cui dimensione non è disponibile al momento della compilazione o che sono più grandi di una soglia configurabile.

Mentre il codice sorgente FindBugs non sia troppo pesante documentato, sto cercando alcune indicazioni su come iniziare - forse già c'è un rilevatore di fare qualcosa di simile che ho potuto guardare

.
È stato utile?

Soluzione

Questo potrebbe diventare un po 'difficile. La mia conoscenza è incompleta, ma dovrete avere almeno tre tipi di istruzioni di guardare fuori per (newArray, ANEWARRAY e MULTIANEWARRAY). Guardando la precedente istruzione (o, nel caso di MULTIANEWARRAY, n le istruzioni precedenti) ottiene la dimensione, che anche se era una costante potrebbe essere caricato con BIPUSH, SIPUSH o LDC (altro?) A seconda dalle dimensioni. Come hai notato, se la classe è il risultato di un calcolo, si può essere tracciando le istruzioni di nuovo a tempo indeterminato.

Se non ricordo male, FindBugs utilizza il BCEL internamente, ma non ho mai scavato in giro in là per vedere esattamente quanto intelligente che sei stato. Se uno di questi team hanno appropriate mailing list, possono rivelarsi un posto migliore per chiedere -. Che probabilmente almeno sapere se qualcuno è stato su questa strada prima

Altri suggerimenti

Bene, se sono assegnati sulla base di una costante, si potrebbe verificare la presenza di una costante che è stato spinto poco prima della allocazione. Ad esempio:

class ArraySize {
    private static final int smallsize = 10;
    private static final int largesize = 1000;
    public static void main(String[] args) {
        int[] small = new int[smallsize];
        int[] big = new int[largesize];
    }
}

dà il bytecode:

Compiled from "ArraySize.java"
class ArraySize extends java.lang.Object{
ArraySize();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   bipush  10
   2:   newarray int
   4:   astore_1
   5:   sipush  1000
   8:   newarray int
   10:  astore_2
   11:  return

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top