src/cpu/sparc/vm/templateTable_sparc.cpp
Print this page
*** 429,454 ****
__ push(ltos);
__ bind(exit);
}
-
void TemplateTable::locals_index(Register reg, int offset) {
__ ldub( at_bcp(offset), reg );
}
-
void TemplateTable::locals_index_wide(Register reg) {
// offset is 2, not 1, because Lbcp points to wide prefix code
__ get_2_byte_integer_at_bcp(2, G4_scratch, reg, InterpreterMacroAssembler::Unsigned);
}
void TemplateTable::iload() {
transition(vtos, itos);
// Rewrite iload,iload pair into fast_iload2
// iload,caload pair into fast_icaload
! if (RewriteFrequentPairs) {
Label rewrite, done;
// get next byte
__ ldub(at_bcp(Bytecodes::length_for(Bytecodes::_iload)), G3_scratch);
--- 429,460 ----
__ push(ltos);
__ bind(exit);
}
void TemplateTable::locals_index(Register reg, int offset) {
__ ldub( at_bcp(offset), reg );
}
void TemplateTable::locals_index_wide(Register reg) {
// offset is 2, not 1, because Lbcp points to wide prefix code
__ get_2_byte_integer_at_bcp(2, G4_scratch, reg, InterpreterMacroAssembler::Unsigned);
}
void TemplateTable::iload() {
+ iload_internal();
+ }
+
+ void TemplateTable::nofast_iload() {
+ iload_internal(MAY_NOT_REWRITE);
+ }
+
+ void TemplateTable::iload_internal(RewriteControl rc) {
transition(vtos, itos);
// Rewrite iload,iload pair into fast_iload2
// iload,caload pair into fast_icaload
! if (RewriteFrequentPairs && rc == MAY_REWRITE) {
Label rewrite, done;
// get next byte
__ ldub(at_bcp(Bytecodes::length_for(Bytecodes::_iload)), G3_scratch);
*** 671,682 ****
void TemplateTable::aload(int n) {
transition(vtos, atos);
__ ld_ptr( Llocals, Interpreter::local_offset_in_bytes(n), Otos_i );
}
-
void TemplateTable::aload_0() {
transition(vtos, atos);
// According to bytecode histograms, the pairs:
//
// _aload_0, _fast_igetfield (itos)
--- 677,695 ----
void TemplateTable::aload(int n) {
transition(vtos, atos);
__ ld_ptr( Llocals, Interpreter::local_offset_in_bytes(n), Otos_i );
}
void TemplateTable::aload_0() {
+ aload_0_internal();
+ }
+
+ void TemplateTable::nofast_aload_0() {
+ aload_0_internal(MAY_NOT_REWRITE);
+ }
+
+ void TemplateTable::aload_0_internal(RewriteControl rc) {
transition(vtos, atos);
// According to bytecode histograms, the pairs:
//
// _aload_0, _fast_igetfield (itos)
*** 686,696 ****
// occur frequently. If RewriteFrequentPairs is set, the (slow) _aload_0
// bytecode checks the next bytecode and then rewrites the current
// bytecode into a pair bytecode; otherwise it rewrites the current
// bytecode into _fast_aload_0 that doesn't do the pair check anymore.
//
! if (RewriteFrequentPairs) {
Label rewrite, done;
// get next byte
__ ldub(at_bcp(Bytecodes::length_for(Bytecodes::_aload_0)), G3_scratch);
--- 699,709 ----
// occur frequently. If RewriteFrequentPairs is set, the (slow) _aload_0
// bytecode checks the next bytecode and then rewrites the current
// bytecode into a pair bytecode; otherwise it rewrites the current
// bytecode into _fast_aload_0 that doesn't do the pair check anymore.
//
! if (RewriteFrequentPairs && rc == MAY_REWRITE) {
Label rewrite, done;
// get next byte
__ ldub(at_bcp(Bytecodes::length_for(Bytecodes::_aload_0)), G3_scratch);
*** 730,740 ****
} else {
aload(0);
}
}
-
void TemplateTable::istore() {
transition(itos, vtos);
locals_index(G3_scratch);
__ store_local_int( G3_scratch, Otos_i );
}
--- 743,752 ----
*** 2044,2063 ****
void TemplateTable::resolve_cache_and_index(int byte_no,
Register Rcache,
Register index,
size_t index_size) {
// Depends on cpCacheOop layout!
Label resolved;
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
__ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size);
! __ cmp(Lbyte_code, (int) bytecode()); // have we resolved this bytecode?
__ br(Assembler::equal, false, Assembler::pt, resolved);
! __ delayed()->set((int)bytecode(), O1);
address entry;
! switch (bytecode()) {
case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through
case Bytecodes::_putfield : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
case Bytecodes::_invokevirtual : // fall through
--- 2056,2083 ----
void TemplateTable::resolve_cache_and_index(int byte_no,
Register Rcache,
Register index,
size_t index_size) {
// Depends on cpCacheOop layout!
+
Label resolved;
+ Bytecodes::Code code = bytecode();
+ switch (code) {
+ case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
+ case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
+ case Bytecodes::_nofast_invokevirtual: code = Bytecodes::_invokevirtual;
+ }
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
__ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size);
! __ cmp(Lbyte_code, code); // have we resolved this bytecode?
__ br(Assembler::equal, false, Assembler::pt, resolved);
! __ delayed()->set(code, O1);
address entry;
!
! switch (code) {
case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through
case Bytecodes::_putfield : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
case Bytecodes::_invokevirtual : // fall through
*** 2065,2075 ****
case Bytecodes::_invokestatic : // fall through
case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
default:
! fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
break;
}
// first time invocation - must resolve first
__ call_VM(noreg, entry, O1);
// Update registers with resolved info
--- 2085,2095 ----
case Bytecodes::_invokestatic : // fall through
case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
default:
! fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(code)));
break;
}
// first time invocation - must resolve first
__ call_VM(noreg, entry, O1);
// Update registers with resolved info
*** 2182,2192 ****
__ get_cache_and_index_at_bcp(Rcache, index, 1);
__ bind(Label1);
}
}
! void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
transition(vtos, vtos);
Register Rcache = G3_scratch;
Register index = G4_scratch;
Register Rclass = Rcache;
--- 2202,2212 ----
__ get_cache_and_index_at_bcp(Rcache, index, 1);
__ bind(Label1);
}
}
! void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos);
Register Rcache = G3_scratch;
Register index = G4_scratch;
Register Rclass = Rcache;
*** 2230,2240 ****
// atos
__ load_heap_oop(Rclass, Roffset, Otos_i);
__ verify_oop(Otos_i);
__ push(atos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2250,2260 ----
// atos
__ load_heap_oop(Rclass, Roffset, Otos_i);
__ verify_oop(Otos_i);
__ push(atos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2245,2255 ****
__ delayed() ->cmp(Rflags, ltos);
// itos
__ ld(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2265,2275 ----
__ delayed() ->cmp(Rflags, ltos);
// itos
__ ld(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2261,2271 ****
// ltos
// load must be atomic
__ ld_long(Rclass, Roffset, Otos_l);
__ push(ltos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2281,2291 ----
// ltos
// load must be atomic
__ ld_long(Rclass, Roffset, Otos_l);
__ push(ltos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2276,2286 ****
__ delayed() ->cmp(Rflags, ctos);
// btos
__ ldsb(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2296,2306 ----
__ delayed() ->cmp(Rflags, ctos);
// btos
__ ldsb(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2291,2301 ****
__ delayed() ->cmp(Rflags, stos);
// ctos
__ lduh(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2311,2321 ----
__ delayed() ->cmp(Rflags, stos);
// ctos
__ lduh(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2306,2316 ****
__ delayed() ->cmp(Rflags, ftos);
// stos
__ ldsh(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2326,2336 ----
__ delayed() ->cmp(Rflags, ftos);
// stos
__ ldsh(Rclass, Roffset, Otos_i);
__ push(itos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2322,2332 ****
__ delayed() ->tst(Lscratch);
// ftos
__ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f);
__ push(ftos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
--- 2342,2352 ----
__ delayed() ->tst(Lscratch);
// ftos
__ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f);
__ push(ftos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
*** 2334,2344 ****
// dtos
__ ldf(FloatRegisterImpl::D, Rclass, Roffset, Ftos_d);
__ push(dtos);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_dgetfield, G3_scratch, G4_scratch);
}
__ bind(checkVolatile);
if (__ membar_has_effect(membar_bits)) {
--- 2354,2364 ----
// dtos
__ ldf(FloatRegisterImpl::D, Rclass, Roffset, Ftos_d);
__ push(dtos);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_dgetfield, G3_scratch, G4_scratch);
}
__ bind(checkVolatile);
if (__ membar_has_effect(membar_bits)) {
*** 2349,2368 ****
}
__ bind(exit);
}
-
void TemplateTable::getfield(int byte_no) {
getfield_or_static(byte_no, false);
}
void TemplateTable::getstatic(int byte_no) {
getfield_or_static(byte_no, true);
}
-
void TemplateTable::fast_accessfield(TosState state) {
transition(atos, state);
Register Rcache = G3_scratch;
Register index = G4_scratch;
Register Roffset = G4_scratch;
--- 2369,2390 ----
}
__ bind(exit);
}
void TemplateTable::getfield(int byte_no) {
getfield_or_static(byte_no, false);
}
+ void TemplateTable::nofast_getfield(int byte_no) {
+ getfield_or_static(byte_no, false, MAY_NOT_REWRITE);
+ }
+
void TemplateTable::getstatic(int byte_no) {
getfield_or_static(byte_no, true);
}
void TemplateTable::fast_accessfield(TosState state) {
transition(atos, state);
Register Rcache = G3_scratch;
Register index = G4_scratch;
Register Roffset = G4_scratch;
*** 2543,2553 ****
__ pop_ptr(r);
__ null_check(r); // for field access must check obj.
__ verify_oop(r);
}
! void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
transition(vtos, vtos);
Register Rcache = G3_scratch;
Register index = G4_scratch;
Register Rclass = Rcache;
Register Roffset= G4_scratch;
--- 2565,2575 ----
__ pop_ptr(r);
__ null_check(r); // for field access must check obj.
__ verify_oop(r);
}
! void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos);
Register Rcache = G3_scratch;
Register index = G4_scratch;
Register Rclass = Rcache;
Register Roffset= G4_scratch;
*** 2619,2629 ****
// itos
{
__ pop_i();
pop_and_check_object(Rclass);
__ st(Otos_i, Rclass, Roffset);
! patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
__ bind(notInt);
--- 2641,2651 ----
// itos
{
__ pop_i();
pop_and_check_object(Rclass);
__ st(Otos_i, Rclass, Roffset);
! if (rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
__ bind(notInt);
*** 2635,2645 ****
{
__ pop_ptr();
pop_and_check_object(Rclass);
__ verify_oop(Otos_i);
do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
! patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
__ bind(notObj);
--- 2657,2667 ----
{
__ pop_ptr();
pop_and_check_object(Rclass);
__ verify_oop(Otos_i);
do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
! if (rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
__ bind(notObj);
*** 2652,2662 ****
// btos
{
__ pop_i();
if (!is_static) pop_and_check_object(Rclass);
__ stb(Otos_i, Rclass, Roffset);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
--- 2674,2684 ----
// btos
{
__ pop_i();
if (!is_static) pop_and_check_object(Rclass);
__ stb(Otos_i, Rclass, Roffset);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
*** 2669,2679 ****
// ltos
{
__ pop_l();
if (!is_static) pop_and_check_object(Rclass);
__ st_long(Otos_l, Rclass, Roffset);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
--- 2691,2701 ----
// ltos
{
__ pop_l();
if (!is_static) pop_and_check_object(Rclass);
__ st_long(Otos_l, Rclass, Roffset);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
*** 2686,2696 ****
// ctos (char)
{
__ pop_i();
if (!is_static) pop_and_check_object(Rclass);
__ sth(Otos_i, Rclass, Roffset);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
--- 2708,2718 ----
// ctos (char)
{
__ pop_i();
if (!is_static) pop_and_check_object(Rclass);
__ sth(Otos_i, Rclass, Roffset);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
*** 2703,2713 ****
// stos (short)
{
__ pop_i();
if (!is_static) pop_and_check_object(Rclass);
__ sth(Otos_i, Rclass, Roffset);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
--- 2725,2735 ----
// stos (short)
{
__ pop_i();
if (!is_static) pop_and_check_object(Rclass);
__ sth(Otos_i, Rclass, Roffset);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
*** 2720,2730 ****
// ftos
{
__ pop_f();
if (!is_static) pop_and_check_object(Rclass);
__ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
--- 2742,2752 ----
// ftos
{
__ pop_f();
if (!is_static) pop_and_check_object(Rclass);
__ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
*** 2734,2744 ****
// dtos
{
__ pop_d();
if (!is_static) pop_and_check_object(Rclass);
__ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
! if (!is_static) {
patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no);
}
}
__ bind(checkVolatile);
--- 2756,2766 ----
// dtos
{
__ pop_d();
if (!is_static) pop_and_check_object(Rclass);
__ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
! if (!is_static && rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no);
}
}
__ bind(checkVolatile);
*** 2808,2827 ****
volatile_barrier(Assembler::StoreLoad);
__ bind(exit);
}
}
-
void TemplateTable::putfield(int byte_no) {
putfield_or_static(byte_no, false);
}
void TemplateTable::putstatic(int byte_no) {
putfield_or_static(byte_no, true);
}
-
void TemplateTable::fast_xaccess(TosState state) {
transition(vtos, state);
Register Rcache = G3_scratch;
Register Roffset = G4_scratch;
Register Rflags = G4_scratch;
--- 2830,2851 ----
volatile_barrier(Assembler::StoreLoad);
__ bind(exit);
}
}
void TemplateTable::putfield(int byte_no) {
putfield_or_static(byte_no, false);
}
+ void TemplateTable::nofast_putfield(int byte_no) {
+ putfield_or_static(byte_no, false, MAY_NOT_REWRITE);
+ }
+
void TemplateTable::putstatic(int byte_no) {
putfield_or_static(byte_no, true);
}
void TemplateTable::fast_xaccess(TosState state) {
transition(vtos, state);
Register Rcache = G3_scratch;
Register Roffset = G4_scratch;
Register Rflags = G4_scratch;
*** 2881,2891 ****
Register index, // itable index, MethodType, etc.
Register recv, // if caller wants to see it
Register flags // if caller wants to test it
) {
// determine flags
! const Bytecodes::Code code = bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
const bool is_invokehandle = code == Bytecodes::_invokehandle;
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
const bool is_invokespecial = code == Bytecodes::_invokespecial;
--- 2905,2915 ----
Register index, // itable index, MethodType, etc.
Register recv, // if caller wants to see it
Register flags // if caller wants to test it
) {
// determine flags
! const Bytecodes::Code code = bytecode() == Bytecodes::_nofast_invokevirtual ? Bytecodes::_invokevirtual : bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
const bool is_invokehandle = code == Bytecodes::_invokehandle;
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
const bool is_invokespecial = code == Bytecodes::_invokespecial;
*** 2952,2961 ****
--- 2976,2993 ----
__ profile_arguments_type(G5_method, Rcall, Gargs, true);
__ call_from_interpreter(Rcall, Gargs, Rret);
}
void TemplateTable::invokevirtual(int byte_no) {
+ invokevirtual_internal(byte_no);
+ }
+
+ void TemplateTable::nofast_invokevirtual(int byte_no) {
+ invokevirtual_internal(byte_no, MAY_NOT_REWRITE);
+ }
+
+ void TemplateTable::invokevirtual_internal(int byte_no, RewriteControl rc) {
transition(vtos, vtos);
assert(byte_no == f2_byte, "use this argument");
Register Rscratch = G3_scratch;
Register Rtemp = G4_scratch;
*** 2970,2980 ****
--- 3002,3014 ----
__ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), G4_scratch);
__ btst(Rret, G4_scratch);
__ br(Assembler::zero, false, Assembler::pt, notFinal);
__ delayed()->and3(Rret, 0xFF, G4_scratch); // gets number of parameters
+ if (rc == MAY_REWRITE) {
patch_bytecode(Bytecodes::_fast_invokevfinal, Rscratch, Rtemp);
+ }
invokevfinal_helper(Rscratch, Rret);
__ bind(notFinal);