# HG changeset patch # User jrose # Date 1239174779 25200 # Node ID 1d037ecd79600736ddebc96c3c7de1a295bf1784 # Parent f2049ae95c3d92a88b1deedbbc4e3845dfb19a73 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 diff -r f2049ae95c3d -r 1d037ecd7960 src/cpu/sparc/vm/vtableStubs_sparc.cpp --- a/src/cpu/sparc/vm/vtableStubs_sparc.cpp Tue Apr 07 19:04:24 2009 -0700 +++ b/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 } diff -r f2049ae95c3d -r 1d037ecd7960 src/cpu/x86/vm/vtableStubs_x86_32.cpp --- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp Tue Apr 07 19:04:24 2009 -0700 +++ b/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() { diff -r f2049ae95c3d -r 1d037ecd7960 src/cpu/x86/vm/vtableStubs_x86_64.cpp --- a/src/cpu/x86/vm/vtableStubs_x86_64.cpp Tue Apr 07 19:04:24 2009 -0700 +++ b/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() { diff -r f2049ae95c3d -r 1d037ecd7960 src/share/vm/code/vtableStubs.cpp --- a/src/share/vm/code/vtableStubs.cpp Tue Apr 07 19:04:24 2009 -0700 +++ b/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(); }