Come rilevare dimensione array in Java bytecode (FindBugs)
-
13-09-2019 - |
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
.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
}