changeset 7183:b2dbd323c668

8003848: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod. Summary: Make ConstMethod::generic_signature_index optional and move Method::_max_stack to ConstMethod. Reviewed-by: bdelsart, sspitsyn, coleenp
author jiangli
date Tue, 27 Nov 2012 17:03:56 -0500
parents e1d42ba865de
children 5505fbbae3d3
files agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java agent/src/share/classes/sun/jvm/hotspot/oops/Method.java src/cpu/sparc/vm/cppInterpreter_sparc.cpp src/cpu/sparc/vm/interp_masm_sparc.cpp src/cpu/sparc/vm/templateInterpreter_sparc.cpp src/cpu/x86/vm/cppInterpreter_x86.cpp src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/defaultMethods.cpp src/share/vm/oops/constMethod.cpp src/share/vm/oops/constMethod.hpp src/share/vm/oops/method.cpp src/share/vm/oops/method.hpp src/share/vm/runtime/vmStructs.cpp
diffstat 13 files changed, 144 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java	Fri Nov 16 09:43:43 2012 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java	Tue Nov 27 17:03:56 2012 -0500
@@ -48,6 +48,7 @@
   private static int HAS_CHECKED_EXCEPTIONS;
   private static int HAS_LOCALVARIABLE_TABLE;
   private static int HAS_EXCEPTION_TABLE;
+  private static int HAS_GENERIC_SIGNATURE;
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type                  = db.lookupType("ConstMethod");
@@ -60,13 +61,14 @@
     HAS_CHECKED_EXCEPTIONS     = db.lookupIntConstant("ConstMethod::_has_checked_exceptions").intValue();
     HAS_LOCALVARIABLE_TABLE   = db.lookupIntConstant("ConstMethod::_has_localvariable_table").intValue();
     HAS_EXCEPTION_TABLE       = db.lookupIntConstant("ConstMethod::_has_exception_table").intValue();
+    HAS_GENERIC_SIGNATURE     = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue();
 
     // Size of Java bytecodes allocated immediately after ConstMethod*.
     codeSize                   = new CIntField(type.getCIntegerField("_code_size"), 0);
     nameIndex                  = new CIntField(type.getCIntegerField("_name_index"), 0);
     signatureIndex             = new CIntField(type.getCIntegerField("_signature_index"), 0);
-    genericSignatureIndex      = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
     idnum                      = new CIntField(type.getCIntegerField("_method_idnum"), 0);
+    maxStack                   = new CIntField(type.getCIntegerField("_max_stack"), 0);
 
     // start of byte code
     bytecodeOffset = type.getSize();
@@ -92,8 +94,8 @@
   private static CIntField codeSize;
   private static CIntField nameIndex;
   private static CIntField signatureIndex;
-  private static CIntField genericSignatureIndex;
   private static CIntField idnum;
+  private static CIntField maxStack;
 
   // start of bytecode
   private static long bytecodeOffset;
@@ -134,13 +136,21 @@
   }
 
   public long getGenericSignatureIndex() {
-    return genericSignatureIndex.getValue(this);
+    if (hasGenericSignature()) {
+      return getAddress().getCIntegerAt(offsetOfGenericSignatureIndex(), 2, true);
+    } else {
+      return 0;
+    }
   }
 
   public long getIdNum() {
     return idnum.getValue(this);
   }
 
+  public long getMaxStack() {
+    return maxStack.getValue(this);
+  }
+
   public Symbol getName() {
     return getMethod().getName();
   }
@@ -235,8 +245,8 @@
       visitor.doCInt(codeSize, true);
       visitor.doCInt(nameIndex, true);
       visitor.doCInt(signatureIndex, true);
-      visitor.doCInt(genericSignatureIndex, true);
       visitor.doCInt(codeSize, true);
+      visitor.doCInt(maxStack, true);
     }
 
   // Accessors
@@ -353,6 +363,10 @@
     return ret;
   }
 
+  private boolean hasGenericSignature() {
+    return (getFlags() & HAS_GENERIC_SIGNATURE) != 0;
+  }
+
 
   //---------------------------------------------------------------------------
   // Internals only below this point
@@ -377,8 +391,14 @@
     return getSize() * VM.getVM().getObjectHeap().getOopSize() - 2;
   }
 
+  // Offset of the generic signature index
+  private long offsetOfGenericSignatureIndex() {
+    return offsetOfLastU2Element();
+  }
+
   private long offsetOfCheckedExceptionsLength() {
-    return offsetOfLastU2Element();
+    return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+                                   offsetOfLastU2Element();
   }
 
   private int getCheckedExceptionsLength() {
@@ -431,7 +451,8 @@
     } else if (hasCheckedExceptions()) {
       return offsetOfCheckedExceptions() - 2;
     } else {
-      return offsetOfLastU2Element();
+      return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+                                     offsetOfLastU2Element();
     }
   }
 
@@ -460,7 +481,8 @@
     if (hasCheckedExceptions()) {
       return offsetOfCheckedExceptions() - 2;
     } else {
-      return offsetOfLastU2Element();
+      return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+                                     offsetOfLastU2Element();
     }
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Fri Nov 16 09:43:43 2012 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Tue Nov 27 17:03:56 2012 -0500
@@ -50,7 +50,6 @@
     constMethod                = type.getAddressField("_constMethod");
     methodData                 = type.getAddressField("_method_data");
     methodSize                 = new CIntField(type.getCIntegerField("_method_size"), 0);
-    maxStack                   = new CIntField(type.getCIntegerField("_max_stack"), 0);
     maxLocals                  = new CIntField(type.getCIntegerField("_max_locals"), 0);
     sizeOfParameters           = new CIntField(type.getCIntegerField("_size_of_parameters"), 0);
     accessFlags                = new CIntField(type.getCIntegerField("_access_flags"), 0);
@@ -84,7 +83,6 @@
   private static AddressField  constMethod;
   private static AddressField  methodData;
   private static CIntField methodSize;
-  private static CIntField maxStack;
   private static CIntField maxLocals;
   private static CIntField sizeOfParameters;
   private static CIntField accessFlags;
@@ -135,7 +133,7 @@
   }
   /** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
   public long         getMethodSize()                 { return                methodSize.getValue(this);        }
-  public long         getMaxStack()                   { return                maxStack.getValue(this);          }
+  public long         getMaxStack()                   { return                getConstMethod().getMaxStack();   }
   public long         getMaxLocals()                  { return                maxLocals.getValue(this);         }
   public long         getSizeOfParameters()           { return                sizeOfParameters.getValue(this);  }
   public long         getNameIndex()                  { return                getConstMethod().getNameIndex();  }
@@ -284,7 +282,6 @@
 
   public void iterateFields(MetadataVisitor visitor) {
       visitor.doCInt(methodSize, true);
-      visitor.doCInt(maxStack, true);
       visitor.doCInt(maxLocals, true);
       visitor.doCInt(sizeOfParameters, true);
       visitor.doCInt(accessFlags, true);
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -1048,7 +1048,6 @@
   const Address constMethod       (G5_method, 0, in_bytes(Method::const_offset()));
   const Address access_flags      (G5_method, 0, in_bytes(Method::access_flags_offset()));
   const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
-  const Address max_stack         (G5_method, 0, in_bytes(Method::max_stack_offset()));
   const Address size_of_locals    (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
 
   // slop factor is two extra slots on the expression stack so that
@@ -1070,7 +1069,9 @@
     __ lduh( size_of_parameters, Gtmp );
     __ calc_mem_param_words(Gtmp, Gtmp);     // space for native call parameters passed on the stack in words
   } else {
-    __ lduh(max_stack, Gtmp);                // Full size expression stack
+    // Full size expression stack
+    __ ld_ptr(constMethod, Gtmp);
+    __ lduh(Gtmp, in_bytes(ConstMethod::max_stack_offset()), Gtmp);
   }
   __ add(Gtmp, fixed_size, Gtmp);           // plus the fixed portion
 
@@ -1206,7 +1207,9 @@
   __ sub(O2, wordSize, O2);                    // prepush
   __ st_ptr(O2, XXX_STATE(_stack));                // PREPUSH
 
-  __ lduh(max_stack, O3);                      // Full size expression stack
+  // Full size expression stack
+  __ ld_ptr(constMethod, O3);
+  __ lduh(O3, in_bytes(ConstMethod::max_stack_offset()), O3);
   guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
   //6815692//if (EnableInvokeDynamic)
   //6815692//  __ inc(O3, Method::extra_stack_entries());
@@ -1539,7 +1542,6 @@
   const Address constMethod       (G5_method, 0, in_bytes(Method::const_offset()));
   const Address access_flags      (G5_method, 0, in_bytes(Method::access_flags_offset()));
   const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
-  const Address max_stack         (G5_method, 0, in_bytes(Method::max_stack_offset()));
   const Address size_of_locals    (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
 
   address entry_point = __ pc();
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -523,7 +523,8 @@
   delayed()->nop();
 
   // Compute max expression stack+register save area
-  lduh(Lmethod, in_bytes(Method::max_stack_offset()), Gframe_size);  // Load max stack.
+  ld_ptr(Lmethod, in_bytes(Method::const_offset()), Gframe_size);
+  lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size);  // Load max stack.
   add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
 
   //
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -496,7 +496,7 @@
 
   const Address size_of_parameters(G5_method, Method::size_of_parameters_offset());
   const Address size_of_locals    (G5_method, Method::size_of_locals_offset());
-  const Address max_stack         (G5_method, Method::max_stack_offset());
+  const Address constMethod       (G5_method, Method::const_offset());
   int rounded_vm_local_words = round_to( frame::interpreter_frame_vm_local_words, WordsPerLong );
 
   const int extra_space =
@@ -538,7 +538,8 @@
     // see if the frame is greater than one page in size. If so,
     // then we need to verify there is enough stack space remaining
     // Frame_size = (max_stack + extra_space) * BytesPerWord;
-    __ lduh( max_stack, Gframe_size );
+    __ ld_ptr( constMethod, Gframe_size );
+    __ lduh( Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size );
     __ add( Gframe_size, extra_space, Gframe_size );
     __ round_to( Gframe_size, WordsPerLong );
     __ sll( Gframe_size, Interpreter::logStackElementSize, Gframe_size);
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -538,9 +538,9 @@
 
     // compute full expression stack limit
 
-    const Address size_of_stack    (rbx, Method::max_stack_offset());
     const int extra_stack = 0; //6815692//Method::extra_stack_words();
-    __ load_unsigned_short(rdx, size_of_stack);                           // get size of expression stack in words
+    __ movptr(rdx, Address(rbx, Method::const_offset()));
+    __ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
     __ negptr(rdx);                                                       // so we can subtract in next step
     // Allocate expression stack
     __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack));
@@ -682,12 +682,12 @@
   const Address stack_size(thread, Thread::stack_size_offset());
 
   // locals + overhead, in bytes
-    const Address size_of_stack    (rbx, Method::max_stack_offset());
-    // Always give one monitor to allow us to start interp if sync method.
-    // Any additional monitors need a check when moving the expression stack
-    const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
-    const int extra_stack = 0; //6815692//Method::extra_stack_entries();
-  __ load_unsigned_short(rax, size_of_stack);                           // get size of expression stack in words
+  // Always give one monitor to allow us to start interp if sync method.
+  // Any additional monitors need a check when moving the expression stack
+  const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
+  const int extra_stack = 0; //6815692//Method::extra_stack_entries();
+  __ movptr(rax, Address(rbx, Method::const_offset()));
+  __ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
   __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor));
   __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
 
--- a/src/share/vm/classfile/classFileParser.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -2184,7 +2184,7 @@
   Method* m = Method::allocate(
       loader_data, code_length, access_flags, linenumber_table_length,
       total_lvt_length, exception_table_length, checked_exceptions_length,
-      ConstMethod::NORMAL, CHECK_(nullHandle));
+      generic_signature_index, ConstMethod::NORMAL, CHECK_(nullHandle));
 
   ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
 
@@ -2192,7 +2192,6 @@
   m->set_constants(cp());
   m->set_name_index(name_index);
   m->set_signature_index(signature_index);
-  m->set_generic_signature_index(generic_signature_index);
 #ifdef CC_INTERP
   // hmm is there a gc issue here??
   ResultTypeFinder rtf(cp->symbol_at(signature_index));
--- a/src/share/vm/classfile/defaultMethods.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/classfile/defaultMethods.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -1148,12 +1148,11 @@
   int code_length = bytecodes->length();
 
   Method* m = Method::allocate(cp->pool_holder()->class_loader_data(),
-      code_length, flags, 0, 0, 0, 0, mt, CHECK_NULL);
+      code_length, flags, 0, 0, 0, 0, 0, mt, CHECK_NULL);
 
   m->set_constants(NULL); // This will get filled in later
   m->set_name_index(cp->utf8(name));
   m->set_signature_index(cp->utf8(sig));
-  m->set_generic_signature_index(0);
 #ifdef CC_INTERP
   ResultTypeFinder rtf(sig);
   m->set_result_index(rtf.type());
--- a/src/share/vm/oops/constMethod.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/oops/constMethod.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -39,16 +39,19 @@
                                    int localvariable_table_length,
                                    int exception_table_length,
                                    int checked_exceptions_length,
+                                   u2  generic_signature_index,
                                    MethodType method_type,
                                    TRAPS) {
   int size = ConstMethod::size(byte_code_size,
                                       compressed_line_number_size,
                                       localvariable_table_length,
                                       exception_table_length,
-                                      checked_exceptions_length);
+                                      checked_exceptions_length,
+                                      generic_signature_index);
   return new (loader_data, size, true, THREAD) ConstMethod(
       byte_code_size, compressed_line_number_size, localvariable_table_length,
-      exception_table_length, checked_exceptions_length, method_type, size);
+      exception_table_length, checked_exceptions_length, generic_signature_index,
+      method_type, size);
 }
 
 ConstMethod::ConstMethod(int byte_code_size,
@@ -56,6 +59,7 @@
                          int localvariable_table_length,
                          int exception_table_length,
                          int checked_exceptions_length,
+                         u2  generic_signature_index,
                          MethodType method_type,
                          int size) {
 
@@ -66,7 +70,8 @@
   set_stackmap_data(NULL);
   set_code_size(byte_code_size);
   set_constMethod_size(size);
-  set_inlined_tables_length(checked_exceptions_length,
+  set_inlined_tables_length(generic_signature_index,
+                            checked_exceptions_length,
                             compressed_line_number_size,
                             localvariable_table_length,
                             exception_table_length);
@@ -90,7 +95,8 @@
                                     int compressed_line_number_size,
                                     int local_variable_table_length,
                                     int exception_table_length,
-                                    int checked_exceptions_length) {
+                                    int checked_exceptions_length,
+                                    u2  generic_signature_index) {
   int extra_bytes = code_size;
   if (compressed_line_number_size > 0) {
     extra_bytes += compressed_line_number_size;
@@ -108,6 +114,9 @@
     extra_bytes += sizeof(u2);
     extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
   }
+  if (generic_signature_index != 0) {
+    extra_bytes += sizeof(u2);
+  }
   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
   return align_object_size(header_size() + extra_words);
 }
@@ -125,10 +134,17 @@
   return code_end();
 }
 
-u2* ConstMethod::checked_exceptions_length_addr() const {
+u2* ConstMethod::generic_signature_index_addr() const {
   // Located at the end of the constMethod.
+  assert(has_generic_signature(), "called only if generic signature exists");
+  return last_u2_element();
+}
+
+u2* ConstMethod::checked_exceptions_length_addr() const {
+  // Located immediately before the generic signature index.
   assert(has_checked_exceptions(), "called only if table is present");
-  return last_u2_element();
+  return has_generic_signature() ? (last_u2_element() - 1) :
+                                    last_u2_element();
 }
 
 u2* ConstMethod::exception_table_length_addr() const {
@@ -137,8 +153,10 @@
     // If checked_exception present, locate immediately before them.
     return (u2*) checked_exceptions_start() - 1;
   } else {
-    // Else, the exception table is at the end of the constMethod.
-    return last_u2_element();
+    // Else, the exception table is at the end of the constMethod or
+    // immediately before the generic signature index.
+    return has_generic_signature() ? (last_u2_element() - 1) :
+                                      last_u2_element();
   }
 }
 
@@ -152,25 +170,30 @@
       // If checked_exception present, locate immediately before them.
       return (u2*) checked_exceptions_start() - 1;
     } else {
-      // Else, the linenumber table is at the end of the constMethod.
-      return last_u2_element();
+      // Else, the linenumber table is at the end of the constMethod or
+      // immediately before the generic signature index.
+      return has_generic_signature() ? (last_u2_element() - 1) :
+                                        last_u2_element();
     }
   }
 }
 
-
 // Update the flags to indicate the presence of these optional fields.
-void ConstMethod::set_inlined_tables_length(
-                                              int checked_exceptions_len,
-                                              int compressed_line_number_size,
-                                              int localvariable_table_len,
-                                              int exception_table_len) {
+void ConstMethod::set_inlined_tables_length(u2  generic_signature_index,
+                                            int checked_exceptions_len,
+                                            int compressed_line_number_size,
+                                            int localvariable_table_len,
+                                            int exception_table_len) {
   // Must be done in the order below, otherwise length_addr accessors
   // will not work. Only set bit in header if length is positive.
   assert(_flags == 0, "Error");
   if (compressed_line_number_size > 0) {
     _flags |= _has_linenumber_table;
   }
+  if (generic_signature_index != 0) {
+    _flags |= _has_generic_signature;
+    *(generic_signature_index_addr()) = generic_signature_index;
+  }
   if (checked_exceptions_len > 0) {
     _flags |= _has_checked_exceptions;
     *(checked_exceptions_length_addr()) = checked_exceptions_len;
--- a/src/share/vm/oops/constMethod.hpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/oops/constMethod.hpp	Tue Nov 27 17:03:56 2012 -0500
@@ -45,7 +45,7 @@
 // | constMethod_size                                     |
 // | interp_kind  | flags    | code_size                  |
 // | name index              | signature index            |
-// | method_idnum            | generic_signature_index    |
+// | method_idnum            | max_stack                  |
 // |------------------------------------------------------|
 // |                                                      |
 // | byte codes                                           |
@@ -55,26 +55,29 @@
 // |  (see class CompressedLineNumberReadStream)          |
 // |  (note that length is unknown until decompressed)    |
 // |  (access flags bit tells whether table is present)   |
-// |  (indexed from start of ConstMethod*)              |
+// |  (indexed from start of ConstMethod*)                |
 // |  (elements not necessarily sorted!)                  |
 // |------------------------------------------------------|
 // | localvariable table elements + length (length last)  |
 // |  (length is u2, elements are 6-tuples of u2)         |
 // |  (see class LocalVariableTableElement)               |
 // |  (access flags bit tells whether table is present)   |
-// |  (indexed from end of ConstMethod*)                |
+// |  (indexed from end of ConstMethod*)                  |
 // |------------------------------------------------------|
 // | exception table + length (length last)               |
 // |  (length is u2, elements are 4-tuples of u2)         |
 // |  (see class ExceptionTableElement)                   |
 // |  (access flags bit tells whether table is present)   |
-// |  (indexed from end of ConstMethod*)                |
+// |  (indexed from end of ConstMethod*)                  |
 // |------------------------------------------------------|
 // | checked exceptions elements + length (length last)   |
 // |  (length is u2, elements are u2)                     |
 // |  (see class CheckedExceptionElement)                 |
 // |  (access flags bit tells whether table is present)   |
-// |  (indexed from end of ConstMethod*)                |
+// |  (indexed from end of ConstMethod*)                  |
+// |------------------------------------------------------|
+// | generic signature index (u2)                         |
+// |  (indexed from start of constMethodOop)              |
 // |------------------------------------------------------|
 
 
@@ -118,7 +121,8 @@
     _has_checked_exceptions = 2,
     _has_localvariable_table = 4,
     _has_exception_table = 8,
-    _is_overpass = 16
+    _has_generic_signature = 16,
+    _is_overpass = 32
   };
 
   // Bit vector of signature
@@ -145,7 +149,7 @@
   u2                _method_idnum;               // unique identification number for the method within the class
                                                  // initially corresponds to the index into the methods array.
                                                  // but this may change with redefinition
-  u2                _generic_signature_index;    // Generic signature (index in constant pool, 0 if absent)
+  u2                _max_stack;                  // Maximum number of entries on the expression stack
 
 
   // Constructor
@@ -154,6 +158,7 @@
               int localvariable_table_length,
               int exception_table_length,
               int checked_exceptions_length,
+              u2  generic_signature_index,
               MethodType is_overpass,
               int size);
 public:
@@ -164,17 +169,22 @@
                                int localvariable_table_length,
                                int exception_table_length,
                                int checked_exceptions_length,
+                               u2  generic_signature_index,
                                MethodType mt,
                                TRAPS);
 
   bool is_constMethod() const { return true; }
 
   // Inlined tables
-  void set_inlined_tables_length(int checked_exceptions_len,
+  void set_inlined_tables_length(u2  generic_signature_index,
+                                 int checked_exceptions_len,
                                  int compressed_line_number_size,
                                  int localvariable_table_len,
                                  int exception_table_len);
 
+  bool has_generic_signature() const
+    { return (_flags & _has_generic_signature) != 0; }
+
   bool has_linenumber_table() const
     { return (_flags & _has_linenumber_table) != 0; }
 
@@ -252,8 +262,18 @@
   void set_signature_index(int index)            { _signature_index = index; }
 
   // generics support
-  int generic_signature_index() const            { return _generic_signature_index; }
-  void set_generic_signature_index(int index)    { _generic_signature_index = index; }
+  int generic_signature_index() const            {
+    if (has_generic_signature()) {
+      return *generic_signature_index_addr();
+    } else {
+      return 0;
+    }
+  }
+  void set_generic_signature_index(u2 index)    {
+    assert(has_generic_signature(), "");
+    u2* addr = generic_signature_index_addr();
+    *addr = index;
+  }
 
   // Sizing
   static int header_size() {
@@ -264,7 +284,8 @@
   static int size(int code_size, int compressed_line_number_size,
                          int local_variable_table_length,
                          int exception_table_length,
-                         int checked_exceptions_length);
+                         int checked_exceptions_length,
+                         u2  generic_signature_index);
 
   int size() const                    { return _constMethod_size;}
   void set_constMethod_size(int size)     { _constMethod_size = size; }
@@ -281,6 +302,7 @@
   // linenumber table - note that length is unknown until decompression,
   // see class CompressedLineNumberReadStream.
   u_char* compressed_linenumber_table() const;         // not preserved by gc
+  u2* generic_signature_index_addr() const;
   u2* checked_exceptions_length_addr() const;
   u2* localvariable_table_length_addr() const;
   u2* exception_table_length_addr() const;
@@ -314,12 +336,19 @@
   static ByteSize constants_offset()
                             { return byte_offset_of(ConstMethod, _constants); }
 
+  static ByteSize max_stack_offset()
+                            { return byte_offset_of(ConstMethod, _max_stack); }
+
   // Unique id for the method
   static const u2 MAX_IDNUM;
   static const u2 UNSET_IDNUM;
   u2 method_idnum() const                        { return _method_idnum; }
   void set_method_idnum(u2 idnum)                { _method_idnum = idnum; }
 
+  // max stack
+  int  max_stack() const                         { return _max_stack; }
+  void set_max_stack(int size)                   { _max_stack = size; }
+
   // Deallocation for RedefineClasses
   void deallocate_contents(ClassLoaderData* loader_data);
   bool is_klass() const { return false; }
--- a/src/share/vm/oops/method.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/oops/method.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -64,6 +64,7 @@
                          int localvariable_table_length,
                          int exception_table_length,
                          int checked_exceptions_length,
+                         u2  generic_signature_index,
                          ConstMethod::MethodType method_type,
                          TRAPS) {
   assert(!access_flags.is_native() || byte_code_size == 0,
@@ -74,6 +75,7 @@
                                           localvariable_table_length,
                                           exception_table_length,
                                           checked_exceptions_length,
+                                          generic_signature_index,
                                           method_type,
                                           CHECK_NULL);
 
@@ -1034,7 +1036,7 @@
   methodHandle m;
   {
     Method* m_oop = Method::allocate(loader_data, 0, accessFlags_from(flags_bits),
-            0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty));
+             0, 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty));
     m = methodHandle(THREAD, m_oop);
   }
   m->set_constants(cp());
@@ -1082,6 +1084,7 @@
   assert(!m->is_native(), "cannot rewrite native methods");
   // Allocate new Method*
   AccessFlags flags = m->access_flags();
+  u2  generic_signature_index = m->generic_signature_index();
   int checked_exceptions_len = m->checked_exceptions_length();
   int localvariable_len = m->localvariable_table_length();
   int exception_table_len = m->exception_table_length();
@@ -1094,6 +1097,7 @@
                                       localvariable_len,
                                       exception_table_len,
                                       checked_exceptions_len,
+                                      generic_signature_index,
                                       m->method_type(),
                                       CHECK_(methodHandle()));
   methodHandle newm (THREAD, newm_oop);
--- a/src/share/vm/oops/method.hpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/oops/method.hpp	Tue Nov 27 17:03:56 2012 -0500
@@ -73,12 +73,10 @@
 // |------------------------------------------------------|
 // | result_index (C++ interpreter only)                  |
 // |------------------------------------------------------|
-// | method_size             | max_stack                  |
-// | max_locals              | size_of_parameters         |
+// | method_size             |   max_locals               |
+// | size_of_parameters      |   intrinsic_id|   flags    |
 // |------------------------------------------------------|
-// |intrinsic_id|   flags    |  throwout_count            |
-// |------------------------------------------------------|
-// | num_breakpoints         |  (unused)                  |
+// | throwout_count          |   num_breakpoints          |
 // |------------------------------------------------------|
 // | invocation_counter                                   |
 // | backedge_counter                                     |
@@ -118,7 +116,6 @@
   int               _result_index;               // C++ interpreter needs for converting results to/from stack
 #endif
   u2                _method_size;                // size of this object
-  u2                _max_stack;                  // Maximum number of entries on the expression stack
   u2                _max_locals;                 // Number of local variables used by this method
   u2                _size_of_parameters;         // size of the parameter block (receiver + arguments) in words
   u1                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
@@ -166,6 +163,7 @@
                           int localvariable_table_length,
                           int exception_table_length,
                           int checked_exceptions_length,
+                          u2 generic_signature_index,
                           ConstMethod::MethodType method_type,
                           TRAPS);
 
@@ -288,9 +286,9 @@
 
   // max stack
   // return original max stack size for method verification
-  int  verifier_max_stack() const                { return _max_stack; }
-  int           max_stack() const                { return _max_stack + extra_stack_entries(); }
-  void      set_max_stack(int size)              {        _max_stack = size; }
+  int  verifier_max_stack() const                { return constMethod()->max_stack(); }
+  int           max_stack() const                { return constMethod()->max_stack() + extra_stack_entries(); }
+  void      set_max_stack(int size)              {        constMethod()->set_max_stack(size); }
 
   // max locals
   int  max_locals() const                        { return _max_locals; }
@@ -606,7 +604,6 @@
   static ByteSize from_interpreted_offset()      { return byte_offset_of(Method, _from_interpreted_entry ); }
   static ByteSize interpreter_entry_offset()     { return byte_offset_of(Method, _i2i_entry ); }
   static ByteSize signature_handler_offset()     { return in_ByteSize(sizeof(Method) + wordSize);      }
-  static ByteSize max_stack_offset()             { return byte_offset_of(Method, _max_stack         ); }
 
   // for code generation
   static int method_data_offset_in_bytes()       { return offset_of(Method, _method_data); }
--- a/src/share/vm/runtime/vmStructs.cpp	Fri Nov 16 09:43:43 2012 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Tue Nov 27 17:03:56 2012 -0500
@@ -366,7 +366,6 @@
   nonstatic_field(Method,               _access_flags,                                 AccessFlags)                           \
   nonstatic_field(Method,               _vtable_index,                                 int)                                   \
   nonstatic_field(Method,               _method_size,                                  u2)                                    \
-  nonstatic_field(Method,               _max_stack,                                    u2)                                    \
   nonstatic_field(Method,               _max_locals,                                   u2)                                    \
   nonstatic_field(Method,               _size_of_parameters,                           u2)                                    \
   nonstatic_field(Method,               _interpreter_throwout_count,                   u2)                                    \
@@ -389,7 +388,7 @@
   nonstatic_field(ConstMethod,          _name_index,                                   u2)                                    \
   nonstatic_field(ConstMethod,          _signature_index,                              u2)                                    \
   nonstatic_field(ConstMethod,          _method_idnum,                                 u2)                                    \
-  nonstatic_field(ConstMethod,          _generic_signature_index,                      u2)                                    \
+  nonstatic_field(ConstMethod,          _max_stack,                                    u2)                                    \
   nonstatic_field(ObjArrayKlass,               _element_klass,                                Klass*)                                \
   nonstatic_field(ObjArrayKlass,               _bottom_klass,                                 Klass*)                                \
   volatile_nonstatic_field(Symbol,             _refcount,                                     int)                                   \
@@ -2292,6 +2291,7 @@
   declare_constant(ConstMethod::_has_checked_exceptions)           \
   declare_constant(ConstMethod::_has_localvariable_table)          \
   declare_constant(ConstMethod::_has_exception_table)              \
+  declare_constant(ConstMethod::_has_generic_signature)            \
                                                                           \
   /*************************************/                                 \
   /* InstanceKlass enum                */                                 \