changeset 421:577f3a2e0662

Merge
author never
date Fri, 07 Nov 2008 13:55:14 -0800
parents 348be627a148 (diff) a1980da045cc (current diff)
children 909cfd030fab 3c07cda72b7d 334969144810
files
diffstat 6 files changed, 65 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Nov 07 09:29:38 2008 -0800
+++ b/.hgtags	Fri Nov 07 13:55:14 2008 -0800
@@ -12,3 +12,4 @@
 5fa96a5a7e76da7c8dad12486293a0456c2c116c jdk7-b35
 e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
 9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
+d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
--- a/src/share/vm/interpreter/bytecodeStream.cpp	Fri Nov 07 09:29:38 2008 -0800
+++ b/src/share/vm/interpreter/bytecodeStream.cpp	Fri Nov 07 13:55:14 2008 -0800
@@ -28,8 +28,9 @@
 Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
   assert(!is_last_bytecode(), "should have been checked");
   // set next bytecode position
-  address bcp  = RawBytecodeStream::bcp();
-  int l = Bytecodes::raw_special_length_at(bcp);
+  address bcp = RawBytecodeStream::bcp();
+  address end = method()->code_base() + end_bci();
+  int l = Bytecodes::raw_special_length_at(bcp, end);
   if (l <= 0 || (_bci + l) > _end_bci) {
     code = Bytecodes::_illegal;
   } else {
@@ -39,8 +40,12 @@
     _is_wide = false;
     // check for special (uncommon) cases
     if (code == Bytecodes::_wide) {
-      code = (Bytecodes::Code)bcp[1];
-      _is_wide = true;
+      if (bcp + 1 >= end) {
+        code = Bytecodes::_illegal;
+      } else {
+        code = (Bytecodes::Code)bcp[1];
+        _is_wide = true;
+      }
     }
   }
   _code = code;
--- a/src/share/vm/interpreter/bytecodes.cpp	Fri Nov 07 09:29:38 2008 -0800
+++ b/src/share/vm/interpreter/bytecodes.cpp	Fri Nov 07 13:55:14 2008 -0800
@@ -54,13 +54,19 @@
   return method->orig_bytecode_at(method->bci_from(bcp));
 }
 
-int Bytecodes::special_length_at(address bcp) {
+int Bytecodes::special_length_at(address bcp, address end) {
   Code code = code_at(bcp);
   switch (code) {
   case _wide:
+    if (end != NULL && bcp + 1 >= end) {
+      return -1; // don't read past end of code buffer
+    }
     return wide_length_for(cast(*(bcp + 1)));
   case _tableswitch:
     { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
+      if (end != NULL && aligned_bcp + 3*jintSize >= end) {
+        return -1; // don't read past end of code buffer
+      }
       jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
       jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
       jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
@@ -73,6 +79,9 @@
   case _fast_binaryswitch: // fall through
   case _fast_linearswitch:
     { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
+      if (end != NULL && aligned_bcp + 2*jintSize >= end) {
+        return -1; // don't read past end of code buffer
+      }
       jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
       jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
       // only return len if it can be represented as a positive int;
@@ -90,14 +99,17 @@
 // verifier when reading in bytecode to verify.  Other mechanisms that
 // run at runtime (such as generateOopMaps) need to iterate over the code
 // and don't expect to see breakpoints: they want to see the instruction
-// which was replaces so that they can get the correct length and find
+// which was replaced so that they can get the correct length and find
 // the next bytecode.
-int Bytecodes::raw_special_length_at(address bcp) {
+//
+// 'end' indicates the end of the code buffer, which we should not try to read
+// past.
+int Bytecodes::raw_special_length_at(address bcp, address end) {
   Code code = code_or_bp_at(bcp);
   if (code == _breakpoint) {
     return 1;
   } else {
-    return special_length_at(bcp);
+    return special_length_at(bcp, end);
   }
 }
 
--- a/src/share/vm/interpreter/bytecodes.hpp	Fri Nov 07 09:29:38 2008 -0800
+++ b/src/share/vm/interpreter/bytecodes.hpp	Fri Nov 07 13:55:14 2008 -0800
@@ -340,8 +340,10 @@
     const char* wf = wide_format(code);
     return (wf == NULL) ? 0 : (int)strlen(wf);
   }
-  static int         special_length_at(address bcp);
-  static int         raw_special_length_at(address bcp);
+  // if 'end' is provided, it indicates the end of the code buffer which
+  // should not be read past when parsing.
+  static int         special_length_at(address bcp, address end = NULL);
+  static int         raw_special_length_at(address bcp, address end = NULL);
   static int         length_at      (address bcp)  { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
   static int         java_length_at (address bcp)  { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
   static bool        is_java_code   (Code code)    { return 0 <= code && code < number_of_java_codes; }
--- a/src/share/vm/memory/compactingPermGenGen.hpp	Fri Nov 07 09:29:38 2008 -0800
+++ b/src/share/vm/memory/compactingPermGenGen.hpp	Fri Nov 07 13:55:14 2008 -0800
@@ -100,7 +100,7 @@
 
   enum {
     vtbl_list_size = 16, // number of entries in the shared space vtable list.
-    num_virtuals = 100   // number of virtual methods in Klass (or
+    num_virtuals = 200   // number of virtual methods in Klass (or
                          // subclass) objects, or greater.
   };
 
--- a/src/share/vm/memory/dump.cpp	Fri Nov 07 09:29:38 2008 -0800
+++ b/src/share/vm/memory/dump.cpp	Fri Nov 07 13:55:14 2008 -0800
@@ -818,6 +818,40 @@
 // across the space while doing this, as that causes the vtables to be
 // patched, undoing our useful work.  Instead, iterate to make a list,
 // then use the list to do the fixing.
+//
+// Our constructed vtables:
+// Dump time:
+//  1. init_self_patching_vtbl_list: table of pointers to current virtual method addrs
+//  2. generate_vtable_methods: create jump table, appended to above vtbl_list
+//  3. PatchKlassVtables: for Klass list, patch the vtable entry to point to jump table
+//     rather than to current vtbl
+// Table layout: NOTE FIXED SIZE
+//   1. vtbl pointers
+//   2. #Klass X #virtual methods per Klass
+//   1 entry for each, in the order:
+//   Klass1:method1 entry, Klass1:method2 entry, ... Klass1:method<num_virtuals> entry
+//   Klass2:method1 entry, Klass2:method2 entry, ... Klass2:method<num_virtuals> entry
+//   ...
+//   Klass<vtbl_list_size>:method1 entry, Klass<vtbl_list_size>:method2 entry,
+//       ... Klass<vtbl_list_size>:method<num_virtuals> entry
+//  Sample entry: (Sparc):
+//   save(sp, -256, sp)
+//   ba,pt common_code
+//   mov XXX, %L0       %L0 gets: Klass index <<8 + method index (note: max method index 255)
+//
+// Restore time:
+//   1. initialize_oops: reserve space for table
+//   2. init_self_patching_vtbl_list: update pointers to NEW virtual method addrs in text
+//
+// Execution time:
+//   First virtual method call for any object of these Klass types:
+//   1. object->klass->klass_part
+//   2. vtable entry for that klass_part points to the jump table entries
+//   3. branches to common_code with %O0/klass_part, %L0: Klass index <<8 + method index
+//   4. common_code:
+//      Get address of new vtbl pointer for this Klass from updated table
+//      Update new vtbl pointer in the Klass: future virtual calls go direct
+//      Jump to method, using new vtbl pointer and method index
 
 class PatchKlassVtables: public ObjectClosure {
 private: