# HG changeset patch # User enevill # Date 1432717328 0 # Node ID 325a4db0d161dea51f97d02ea48a4e816347d732 # Parent 2a5a2426cee029262042df2a99dc009acbfbd3a6 8081289: aarch64: add support for RewriteFrequentPairs in interpreter Summary: Add support for RewriteFrequentPairs Reviewed-by: roland Contributed-by: alexander.alexeev@caviumnetworks.com diff -r 2a5a2426cee0 -r 325a4db0d161 hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp --- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Tue Jun 02 09:15:32 2015 -0700 +++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Wed May 27 09:02:08 2015 +0000 @@ -64,7 +64,7 @@ define_pd_global(intx, PreInflateSpin, 10); define_pd_global(bool, RewriteBytecodes, true); -define_pd_global(bool, RewriteFrequentPairs, false); +define_pd_global(bool, RewriteFrequentPairs, true); define_pd_global(bool, UseMembar, true); diff -r 2a5a2426cee0 -r 325a4db0d161 hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp Tue Jun 02 09:15:32 2015 -0700 +++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp Wed May 27 09:02:08 2015 +0000 @@ -513,23 +513,61 @@ void TemplateTable::iload_internal(RewriteControl rc) { transition(vtos, itos); if (RewriteFrequentPairs && rc == may_rewrite) { - // TODO : check x86 code for what to do here - __ call_Unimplemented(); - } else { - locals_index(r1); - __ ldr(r0, iaddress(r1)); + Label rewrite, done; + Register bc = r4; + + // get next bytecode + __ load_unsigned_byte(r1, at_bcp(Bytecodes::length_for(Bytecodes::_iload))); + + // if _iload, wait to rewrite to iload2. We only want to rewrite the + // last two iloads in a pair. Comparing against fast_iload means that + // the next bytecode is neither an iload or a caload, and therefore + // an iload pair. + __ cmpw(r1, Bytecodes::_iload); + __ br(Assembler::EQ, done); + + // if _fast_iload rewrite to _fast_iload2 + __ cmpw(r1, Bytecodes::_fast_iload); + __ movw(bc, Bytecodes::_fast_iload2); + __ br(Assembler::EQ, rewrite); + + // if _caload rewrite to _fast_icaload + __ cmpw(r1, Bytecodes::_caload); + __ movw(bc, Bytecodes::_fast_icaload); + __ br(Assembler::EQ, rewrite); + + // else rewrite to _fast_iload + __ movw(bc, Bytecodes::_fast_iload); + + // rewrite + // bc: new bytecode + __ bind(rewrite); + patch_bytecode(Bytecodes::_iload, bc, r1, false); + __ bind(done); + } + // do iload, get the local value into tos + locals_index(r1); + __ ldr(r0, iaddress(r1)); + } void TemplateTable::fast_iload2() { - __ call_Unimplemented(); + transition(vtos, itos); + locals_index(r1); + __ ldr(r0, iaddress(r1)); + __ push(itos); + locals_index(r1, 3); + __ ldr(r0, iaddress(r1)); } void TemplateTable::fast_iload() { - __ call_Unimplemented(); + transition(vtos, itos); + locals_index(r1); + __ ldr(r0, iaddress(r1)); } void TemplateTable::lload() @@ -721,7 +759,18 @@ // iload followed by caload frequent pair void TemplateTable::fast_icaload() { - __ call_Unimplemented(); + transition(vtos, itos); + // load index out of locals + locals_index(r2); + __ ldr(r1, iaddress(r2)); + + __ pop_ptr(r0); + + // r0: array + // r1: index + index_check(r0, r1); // leaves index in r1, kills rscratch1 + __ lea(r1, Address(r0, r1, Address::uxtw(1))); + __ load_unsigned_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_CHAR))); } void TemplateTable::saload() @@ -797,7 +846,47 @@ // These bytecodes with a small amount of code are most profitable // to rewrite if (RewriteFrequentPairs && rc == may_rewrite) { - __ call_Unimplemented(); + Label rewrite, done; + const Register bc = r4; + + // get next bytecode + __ load_unsigned_byte(r1, at_bcp(Bytecodes::length_for(Bytecodes::_aload_0))); + + // do actual aload_0 + aload(0); + + // if _getfield then wait with rewrite + __ cmpw(r1, Bytecodes::Bytecodes::_getfield); + __ br(Assembler::EQ, done); + + // if _igetfield then reqrite to _fast_iaccess_0 + assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) == Bytecodes::_aload_0, "fix bytecode definition"); + __ cmpw(r1, Bytecodes::_fast_igetfield); + __ movw(bc, Bytecodes::_fast_iaccess_0); + __ br(Assembler::EQ, rewrite); + + // if _agetfield then reqrite to _fast_aaccess_0 + assert(Bytecodes::java_code(Bytecodes::_fast_aaccess_0) == Bytecodes::_aload_0, "fix bytecode definition"); + __ cmpw(r1, Bytecodes::_fast_agetfield); + __ movw(bc, Bytecodes::_fast_aaccess_0); + __ br(Assembler::EQ, rewrite); + + // if _fgetfield then reqrite to _fast_faccess_0 + assert(Bytecodes::java_code(Bytecodes::_fast_faccess_0) == Bytecodes::_aload_0, "fix bytecode definition"); + __ cmpw(r1, Bytecodes::_fast_fgetfield); + __ movw(bc, Bytecodes::_fast_faccess_0); + __ br(Assembler::EQ, rewrite); + + // else rewrite to _fast_aload0 + assert(Bytecodes::java_code(Bytecodes::_fast_aload_0) == Bytecodes::_aload_0, "fix bytecode definition"); + __ movw(bc, Bytecodes::Bytecodes::_fast_aload_0); + + // rewrite + // bc: new bytecode + __ bind(rewrite); + patch_bytecode(Bytecodes::_aload_0, bc, r1, false); + + __ bind(done); } else { aload(0); }