changeset 747:1d037ecd7960

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
author jrose
date Wed, 08 Apr 2009 00:12:59 -0700
parents f2049ae95c3d
children e5b0439ef4ae
files src/cpu/sparc/vm/vtableStubs_sparc.cpp src/cpu/x86/vm/vtableStubs_x86_32.cpp src/cpu/x86/vm/vtableStubs_x86_64.cpp src/share/vm/code/vtableStubs.cpp
diffstat 4 files changed, 130 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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
 }
 
 
--- 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() {
--- 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() {
--- 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();
 }