< prev index next >

src/hotspot/share/code/vtableStubs.cpp

Print this page
rev 51258 : [mq]: 8207343.patch

@@ -88,12 +88,16 @@
 //
 // For each hash value there's a linked list of vtable stubs (with that
 // hash value). Each list is anchored in a little hash _table, indexed
 // by that hash value.
 
+static int const firstStub_size = 1024;
+
 VtableStub* VtableStubs::_table[VtableStubs::N];
 int VtableStubs::_number_of_vtable_stubs = 0;
+int VtableStubs::_vtab_stub_size = 0;
+int VtableStubs::_itab_stub_size = 0;
 
 
 void VtableStubs::initialize() {
   VtableStub::_receiver_location = SharedRuntime::name_for_receiver();
   {

@@ -105,10 +109,71 @@
     }
   }
 }
 
 
+int VtableStub::code_size_limit(bool is_vtable_stub) {
+  if (is_vtable_stub) {
+    return VtableStubs::_vtab_stub_size > 0 ? VtableStubs::_vtab_stub_size
+                                            : firstStub_size;
+  } else { // itable stub
+    return VtableStubs::_itab_stub_size > 0 ? VtableStubs::_itab_stub_size
+                                            : firstStub_size;
+  }
+}   // code_size_limit
+
+
+void VtableStub::check_and_set_size_limit(bool is_vtable_stub,
+                                          int  code_size,
+                                          int  padding        ) {
+  const char* name = is_vtable_stub ? "vtable" : "itable";
+
+  guarantee(code_size <= code_size_limit(is_vtable_stub),
+            "buffer overflow in %s stub, code_size is %d, limit is %d", name, code_size, code_size_limit(is_vtable_stub));
+
+  if (is_vtable_stub) {
+    if ( code_size > VtableStubs::_vtab_stub_size - padding ) {
+      VtableStubs::_vtab_stub_size = code_size + padding;
+    }
+  } else {  // itable stub
+    if ( code_size > VtableStubs::_itab_stub_size - padding ) {
+      VtableStubs::_itab_stub_size = code_size + padding;
+    }
+  }
+  return;
+}   // check_and_set_size_limit
+
+
+void VtableStubs::bookkeeping(MacroAssembler* masm, outputStream* out, VtableStub* s,
+                              address npe_addr, address ame_addr,   bool is_vtable_stub,
+                              int     index,    int     slop_bytes, int  slop32) {
+  const char* name        = is_vtable_stub ? "vtable" : "itable";
+  const int   stub_length = VtableStub::code_size_limit(is_vtable_stub);
+
+  if (PrintMiscellaneous && (WizardMode || Verbose)) {
+    out->print_cr("%s #%d at " PTR_FORMAT "[%d], estimate %d, left over: %d",
+                  name, index, p2i(s->entry_point()),
+                  (int)(s->code_end() - s->entry_point()),
+                  stub_length,
+                  (int)(s->code_end() - masm->pc()));
+  }
+  guarantee(masm->pc() <= s->code_end(), "%s #%d: overflowed buffer, estimated len: %d, actual len: %d, overrun: %d",
+                                         name, index, stub_length,
+                                         (int)(masm->pc() - s->code_begin()),
+                                         (int)(masm->pc() - s->code_end()));
+  assert((masm->pc() + slop32) <= s->code_end(), "%s #%d: spare space for 32-bit offset: required = %d, available = %d",
+                                         name, index, slop32,
+                                         (int)(s->code_end() - masm->pc()));
+
+  // After the first vtable/itable stub is generated, we have a much
+  // better estimate for the stub size. Remember/update this
+  // estimate after some sanity checks.
+  s->check_and_set_size_limit(is_vtable_stub, masm->offset(), slop_bytes);
+  s->set_exception_points(npe_addr, ame_addr);
+}
+
+
 address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) {
   assert(vtable_index >= 0, "must be positive");
 
   VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL;
   if (s == NULL) {

@@ -171,14 +236,11 @@
   MutexLocker ml(VtableStubs_lock);
   VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset());
   uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index());
   VtableStub* s;
   for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {}
-  if (s == stub) {
-    return s;
-  }
-  return NULL;
+  return (s == stub) ? s : NULL;
 }
 
 bool VtableStubs::contains(address pc) {
   // simple solution for now - we may want to use
   // a faster way if this function is called often
< prev index next >