6827505: sizing logic for vtable and itable stubs needs self-check
Summary: Asserts and comments to help maintain the correct sizing of certain stubs
Reviewed-by: kvn
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Tue Apr 07 19:04:24 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Wed Apr 08 00:12:59 2009 -0700
@@ -114,6 +114,9 @@
(int)(s->code_end() - __ pc()));
}
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+ // shut the door on sizing bugs
+ int slop = 2*BytesPerInstWord; // 32-bit offset is this much larger than a 13-bit one
+ assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for sethi;add");
s->set_exception_points(npe_addr, ame_addr);
return s;
@@ -208,6 +211,9 @@
(int)(s->code_end() - __ pc()));
}
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+ // shut the door on sizing bugs
+ int slop = 2*BytesPerInstWord; // 32-bit offset is this much larger than a 13-bit one
+ assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for sethi;add");
s->set_exception_points(npe_addr, ame_addr);
return s;
@@ -233,6 +239,50 @@
return (basic + slop);
}
}
+
+ // In order to tune these parameters, run the JVM with VM options
+ // +PrintMiscellaneous and +WizardMode to see information about
+ // actual itable stubs. Look for lines like this:
+ // itable #1 at 0x5551212[116] left over: 8
+ // Reduce the constants so that the "left over" number is 8
+ // Do not aim at a left-over number of zero, because a very
+ // large vtable or itable offset (> 4K) will require an extra
+ // sethi/or pair of instructions.
+ //
+ // The JVM98 app. _202_jess has a megamorphic interface call.
+ // The itable code looks like this:
+ // Decoding VtableStub itbl[1]@16
+ // ld [ %o0 + 4 ], %g3
+ // save %sp, -64, %sp
+ // ld [ %g3 + 0xe8 ], %l2
+ // sll %l2, 2, %l2
+ // add %l2, 0x134, %l2
+ // and %l2, -8, %l2 ! NOT_LP64 only
+ // add %g3, %l2, %l2
+ // add %g3, 4, %g3
+ // ld [ %l2 ], %l5
+ // brz,pn %l5, throw_icce
+ // cmp %l5, %g5
+ // be %icc, success
+ // add %l2, 8, %l2
+ // loop:
+ // ld [ %l2 ], %l5
+ // brz,pn %l5, throw_icce
+ // cmp %l5, %g5
+ // bne,pn %icc, loop
+ // add %l2, 8, %l2
+ // success:
+ // ld [ %l2 + -4 ], %l2
+ // ld [ %g3 + %l2 ], %l5
+ // restore %l5, 0, %g5
+ // ld [ %g5 + 0x44 ], %g3
+ // jmp %g3
+ // nop
+ // throw_icce:
+ // sethi %hi(throw_ICCE_entry), %g3
+ // ! 5 more instructions here, LP64_ONLY
+ // jmp %g3 + %lo(throw_ICCE_entry)
+ // restore
}
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp Tue Apr 07 19:04:24 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp Wed Apr 08 00:12:59 2009 -0700
@@ -108,6 +108,9 @@
(int)(s->code_end() - __ pc()));
}
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+ // shut the door on sizing bugs
+ int slop = 3; // 32-bit offset is this much larger than an 8-bit one
+ assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
s->set_exception_points(npe_addr, ame_addr);
return s;
@@ -181,6 +184,9 @@
(int)(s->code_end() - __ pc()));
}
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+ // shut the door on sizing bugs
+ int slop = 3; // 32-bit offset is this much larger than an 8-bit one
+ assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
s->set_exception_points(npe_addr, ame_addr);
return s;
@@ -196,6 +202,41 @@
// Itable stub size
return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
}
+ // In order to tune these parameters, run the JVM with VM options
+ // +PrintMiscellaneous and +WizardMode to see information about
+ // actual itable stubs. Look for lines like this:
+ // itable #1 at 0x5551212[65] left over: 3
+ // Reduce the constants so that the "left over" number is >=3
+ // for the common cases.
+ // Do not aim at a left-over number of zero, because a
+ // large vtable or itable index (> 16) will require a 32-bit
+ // immediate displacement instead of an 8-bit one.
+ //
+ // The JVM98 app. _202_jess has a megamorphic interface call.
+ // The itable code looks like this:
+ // Decoding VtableStub itbl[1]@1
+ // mov 0x4(%ecx),%esi
+ // mov 0xe8(%esi),%edi
+ // lea 0x130(%esi,%edi,4),%edi
+ // add $0x7,%edi
+ // and $0xfffffff8,%edi
+ // lea 0x4(%esi),%esi
+ // mov (%edi),%ebx
+ // cmp %ebx,%eax
+ // je success
+ // loop:
+ // test %ebx,%ebx
+ // je throw_icce
+ // add $0x8,%edi
+ // mov (%edi),%ebx
+ // cmp %ebx,%eax
+ // jne loop
+ // success:
+ // mov 0x4(%edi),%edi
+ // mov (%esi,%edi,1),%ebx
+ // jmp *0x44(%ebx)
+ // throw_icce:
+ // jmp throw_ICCE_entry
}
int VtableStub::pd_code_alignment() {
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp Tue Apr 07 19:04:24 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp Wed Apr 08 00:12:59 2009 -0700
@@ -106,6 +106,9 @@
(int)(s->code_end() - __ pc()));
}
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+ // shut the door on sizing bugs
+ int slop = 3; // 32-bit offset is this much larger than an 8-bit one
+ assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
s->set_exception_points(npe_addr, ame_addr);
return s;
@@ -191,6 +194,9 @@
(int)(s->code_end() - __ pc()));
}
guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+ // shut the door on sizing bugs
+ int slop = 3; // 32-bit offset is this much larger than an 8-bit one
+ assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
s->set_exception_points(npe_addr, ame_addr);
return s;
@@ -206,6 +212,39 @@
return (DebugVtables ? 512 : 72) + (CountCompiledCalls ? 13 : 0) +
(UseCompressedOops ? 32 : 0); // 2 leaqs
}
+ // In order to tune these parameters, run the JVM with VM options
+ // +PrintMiscellaneous and +WizardMode to see information about
+ // actual itable stubs. Look for lines like this:
+ // itable #1 at 0x5551212[71] left over: 3
+ // Reduce the constants so that the "left over" number is >=3
+ // for the common cases.
+ // Do not aim at a left-over number of zero, because a
+ // large vtable or itable index (>= 32) will require a 32-bit
+ // immediate displacement instead of an 8-bit one.
+ //
+ // The JVM98 app. _202_jess has a megamorphic interface call.
+ // The itable code looks like this:
+ // Decoding VtableStub itbl[1]@12
+ // mov 0x8(%rsi),%r10
+ // mov 0x198(%r10),%r11d
+ // lea 0x218(%r10,%r11,8),%r11
+ // lea 0x8(%r10),%r10
+ // mov (%r11),%rbx
+ // cmp %rbx,%rax
+ // je success
+ // loop:
+ // test %rbx,%rbx
+ // je throw_icce
+ // add $0x10,%r11
+ // mov (%r11),%rbx
+ // cmp %rbx,%rax
+ // jne loop
+ // success:
+ // mov 0x8(%r11),%r11d
+ // mov (%r10,%r11,1),%rbx
+ // jmpq *0x60(%rbx)
+ // throw_icce:
+ // jmpq throw_ICCE_entry
}
int VtableStub::pd_code_alignment() {
--- a/hotspot/src/share/vm/code/vtableStubs.cpp Tue Apr 07 19:04:24 2009 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp Wed Apr 08 00:12:59 2009 -0700
@@ -107,13 +107,11 @@
s = create_itable_stub(vtable_index);
}
enter(is_vtable_stub, vtable_index, s);
-#ifndef PRODUCT
if (PrintAdapterHandlers) {
tty->print_cr("Decoding VtableStub %s[%d]@%d",
is_vtable_stub? "vtbl": "itbl", vtable_index, VtableStub::receiver_location());
Disassembler::decode(s->code_begin(), s->code_end());
}
-#endif
}
return s->entry_point();
}