Nemám přesné informace o reprezentaci objektů v paměti, ale pochybuju, že se dostane na 8 bytů. A i kdyby, tak takových objektů bude naprosté minimum.
S ohledem na dnešní standard zarovnání paměti na 16 bytů (aspoň na nejrozšířenější x86/x86_64 - např. kvůli movaps, ale obecné vhodnosti pro jakoukoli 16byte operaci) bych čekal, že v návrhu useknou 4 bity. Vidím samá pozitiva, nebo se pletu?
Kdysi jsem meril velikost objektu (pomoci mereni spotreby pameti) a vychazelo mi ze java.lang.Object ma 16 bajtu a kazdy object spotrebuje nasobek 8 bajtu (takhle to bylo uz na 32 bitech). Zarovnani na 8B je tam tedy vzdy, zarovani na 16B kupodivu ne.
Napada me dve negativa: Nejpis se uziva adresovani s indexem nasobenym 8, a nasobeni 16 architektura amd64 neumi. Taky by se utracelo az 8B na objekt a to muze byt uz hodne - netusim jaka je prumerna velikost objektu v prumernym programu.
Hm, díky za měření. Asi bychom u hodně malých objektů (Integer, Long, ...) přišli o pár bytů. Maximálně 1/4, to by asi nebyla taková tragédie.
To adresování mě později taky napadlo, chtělo by to vidět implementaci, třeba se Pavel Tišňovský rozepíše v dalším dílu :) V každém případě by to znamenalo, že si java musí držet nějaký zero register, bo, pokud vím, tak bázový registr je při adresování s indexem povinný.
S tim bazovym registrem mate pravdu, jeste ze mame dalsich osm pracovnich registru :-). Dekodovani adresy vypada nasledovne. Ddoufam ze je ten kod je aspon trochu citelny, je to description file pro JIT i interpretr:
// Indirect Narrow Oop Plus Offset Operand
// Note: x86 architecture doesn't support "scale * index + offset" without a base
// we can't free r12 even with Universe::narrow_oop_base() == NULL.
operand indCompressedOopOffset(rRegN reg, immL32 off) %{
predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP (DecodeN reg) off);
op_cost(10);
format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
interface(MEMORY_INTER) %{
base(0xc); // R12
index($reg);
scale(0x3);
disp($off);
%}
%}
Baze ma jeste vyznam pri rozpoznani typu ukazatelu, jeste se o tom nekdy zkusim rozepsat.
Asi ne, soudě podle příspěvku výše:
format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
Takže je to asi tak, jak psal Maaartin, tedy místo rbx *= compress_bits a mov rax, [rbx] se píše rovnou mov rax, [r12+rbx*8]
A těch 8 (3 bity) je omezení dané platformou, z r12 si java asi udělala zero register. Ostatní řešení s násobením by asi způsobily znatelné zpomalení kódu, takže je to celkem pochopitelné.