dalvik/vm/oo/Object.h
è tuo amico qui. Il commento per struct Object
dice:
/*
* There are three types of objects:
* Class objects - an instance of java.lang.Class
* Array objects - an object created with a "new array" instruction
* Data objects - an object that is neither of the above
*
* We also define String objects. At present they're equivalent to
* DataObject, but that may change. (Either way, they make some of the
* code more obvious.)
*
* All objects have an Object header followed by type-specific data.
*/
java.lang.Class
oggetti sono speciali; il loro layout è definito dalla struttura ClassObject
in Object.h
. oggetti array sono semplici:
struct ArrayObject : Object {
/* number of elements; immutable after init */
u4 length;
/*
* Array contents; actual size is (length * sizeof(type)). This is
* declared as u8 so that the compiler inserts any necessary padding
* (e.g. for EABI); the actual allocation may be smaller than 8 bytes.
*/
u8 contents[1];
};
Per gli array, le larghezze sono in vm/oo/Array.cpp
. I booleani sono larghezza 1, gli oggetti hanno lunghezza sizeof(Object*)
(in genere 4) e tutti gli altri tipi primitivi hanno la lunghezza prevista (imballata).
oggetti dati sono molto semplici:
/*
* Data objects have an Object header followed by their instance data.
*/
struct DataObject : Object {
/* variable #of u4 slots; u8 uses 2 slots */
u4 instanceData[1];
};
il layout di una (tutte le istanze di classe non-Class) DataObject
è disciplinato dalle computeFieldOffsets
in vm/oo/Class.cpp
. Secondo il commento c'è:
/*
* Assign instance fields to u4 slots.
*
* The top portion of the instance field area is occupied by the superclass
* fields, the bottom by the fields for this class.
*
* "long" and "double" fields occupy two adjacent slots. On some
* architectures, 64-bit quantities must be 64-bit aligned, so we need to
* arrange fields (or introduce padding) to ensure this. We assume the
* fields of the topmost superclass (i.e. Object) are 64-bit aligned, so
* we can just ensure that the offset is "even". To avoid wasting space,
* we want to move non-reference 32-bit fields into gaps rather than
* creating pad words.
*
* In the worst case we will waste 4 bytes, but because objects are
* allocated on >= 64-bit boundaries, those bytes may well be wasted anyway
* (assuming this is the most-derived class).
*
* Pad words are not represented in the field table, so the field table
* itself does not change size.
*
* The number of field slots determines the size of the object, so we
* set that here too.
*
* This function feels a little more complicated than I'd like, but it
* has the property of moving the smallest possible set of fields, which
* should reduce the time required to load a class.
*
* NOTE: reference fields *must* come first, or precacheReferenceOffsets()
* will break.
*/
Quindi, i campi della superclasse arrivato, primo (come al solito), seguita da campi di riferimento di tipo, seguito da un singolo campo a 32 bit (se disponibile, e se è necessario padding perché c'è un numero dispari di campi di riferimento a 32 bit) seguito da campi a 64 bit. Seguono i normali campi a 32 bit. Si noti che tutti i campi sono a 32 o 64 bit (le primitive più corte sono riempite). In particolare, in questo momento, la VM non memorizza i campi byte/char/short/boolean con meno di 4 byte, anche se in teoria potrebbe supportarli.
Si noti che tutto ciò si basa sulla lettura del codice sorgente Dalvik a partire dal commit 43241340
(6 febbraio 2013). Dal momento che questo aspetto della VM non sembra essere pubblicamente documentato, non si deve fare affidamento su ciò per essere una descrizione stabile del layout dell'oggetto della VM: potrebbe cambiare nel tempo.
Hai letto/visto questo: https://sites.google.com/site/io/dalvik-vm-internals/ –
Non l'avevo, ma non ho le informazioni che desidero. Parla del layout dell'APK e del bytecode, ma non degli oggetti sull'heap. –
Dalvik sembra quasi identico: 4 byte di classe ptr, 4 byte di blocco, quindi dati: https://android.googlesource.com/platform/dalvik/+/master/vm/oo/Object.h – Chris