changeset 3903:fd74228fd5ca

8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing. Summary: Move _max_locals and _size_of_parameters to ConstMethod for better sharing. Reviewed-by: coleenp, minqi, jrose
author jiangli
date Tue, 11 Dec 2012 12:41:31 -0500
parents 4a2ed49abd51
children 807f1d348f7b
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/methodHandles_sparc.cpp src/cpu/sparc/vm/templateInterpreter_sparc.cpp src/cpu/sparc/vm/templateTable_sparc.cpp src/cpu/x86/vm/cppInterpreter_x86.cpp src/cpu/x86/vm/methodHandles_x86.cpp src/cpu/x86/vm/templateInterpreter_x86_32.cpp src/cpu/x86/vm/templateInterpreter_x86_64.cpp src/share/vm/oops/constMethod.hpp src/share/vm/oops/method.hpp src/share/vm/runtime/vmStructs.cpp
diffstat 13 files changed, 132 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java	Fri Dec 07 10:55:16 2012 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java	Tue Dec 11 12:41:31 2012 -0500
@@ -69,6 +69,8 @@
     signatureIndex             = new CIntField(type.getCIntegerField("_signature_index"), 0);
     idnum                      = new CIntField(type.getCIntegerField("_method_idnum"), 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);
 
     // start of byte code
     bytecodeOffset = type.getSize();
@@ -96,6 +98,8 @@
   private static CIntField signatureIndex;
   private static CIntField idnum;
   private static CIntField maxStack;
+  private static CIntField maxLocals;
+  private static CIntField sizeOfParameters;
 
   // start of bytecode
   private static long bytecodeOffset;
@@ -151,6 +155,14 @@
     return maxStack.getValue(this);
   }
 
+  public long getMaxLocals() {
+    return maxLocals.getValue(this);
+  }
+
+  public long getSizeOfParameters() {
+    return sizeOfParameters.getValue(this);
+  }
+
   public Symbol getName() {
     return getMethod().getName();
   }
@@ -247,6 +259,8 @@
       visitor.doCInt(signatureIndex, true);
       visitor.doCInt(codeSize, true);
       visitor.doCInt(maxStack, true);
+      visitor.doCInt(maxLocals, true);
+      visitor.doCInt(sizeOfParameters, true);
     }
 
   // Accessors
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Fri Dec 07 10:55:16 2012 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Tue Dec 11 12:41:31 2012 -0500
@@ -50,8 +50,6 @@
     constMethod                = type.getAddressField("_constMethod");
     methodData                 = type.getAddressField("_method_data");
     methodSize                 = new CIntField(type.getCIntegerField("_method_size"), 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);
     code                       = type.getAddressField("_code");
     vtableIndex                = new CIntField(type.getCIntegerField("_vtable_index"), 0);
@@ -83,8 +81,6 @@
   private static AddressField  constMethod;
   private static AddressField  methodData;
   private static CIntField methodSize;
-  private static CIntField maxLocals;
-  private static CIntField sizeOfParameters;
   private static CIntField accessFlags;
   private static CIntField vtableIndex;
   private static CIntField invocationCounter;
@@ -134,8 +130,8 @@
   /** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
   public long         getMethodSize()                 { return                methodSize.getValue(this);        }
   public long         getMaxStack()                   { return                getConstMethod().getMaxStack();   }
-  public long         getMaxLocals()                  { return                maxLocals.getValue(this);         }
-  public long         getSizeOfParameters()           { return                sizeOfParameters.getValue(this);  }
+  public long         getMaxLocals()                  { return                getConstMethod().getMaxLocals();         }
+  public long         getSizeOfParameters()           { return                getConstMethod().getSizeOfParameters();  }
   public long         getNameIndex()                  { return                getConstMethod().getNameIndex();  }
   public long         getSignatureIndex()             { return            getConstMethod().getSignatureIndex(); }
   public long         getGenericSignatureIndex()      { return     getConstMethod().getGenericSignatureIndex(); }
@@ -282,8 +278,6 @@
 
   public void iterateFields(MetadataVisitor visitor) {
       visitor.doCInt(methodSize, true);
-      visitor.doCInt(maxLocals, true);
-      visitor.doCInt(sizeOfParameters, true);
       visitor.doCInt(accessFlags, true);
     }
 
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -582,7 +582,9 @@
   // the following temporary registers are used during frame creation
   const Register Gtmp1 = G3_scratch ;
   const Register Gtmp2 = G1_scratch;
-  const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
+  const Register RconstMethod = Gtmp1;
+  const Address constMethod(G5_method, 0, in_bytes(Method::const_offset()));
+  const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
 
   bool inc_counter  = UseCompiler || CountCompiledCalls;
 
@@ -618,6 +620,7 @@
   }
 #endif // ASSERT
 
+  __ ld_ptr(constMethod, RconstMethod);
   __ lduh(size_of_parameters, Gtmp1);
   __ sll(Gtmp1, LogBytesPerWord, Gtmp2);       // parameter size in bytes
   __ add(Gargs, Gtmp2, Gargs);                 // points to first local + BytesPerWord
@@ -1047,8 +1050,6 @@
   const Register Gtmp = G3_scratch;
   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 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
   // we always have room to store a result when returning from a call without parameters
@@ -1066,6 +1067,9 @@
   // Now compute new frame size
 
   if (native) {
+    const Register RconstMethod = Gtmp;
+    const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
+    __ ld_ptr(constMethod, RconstMethod);
     __ lduh( size_of_parameters, Gtmp );
     __ calc_mem_param_words(Gtmp, Gtmp);     // space for native call parameters passed on the stack in words
   } else {
@@ -1236,9 +1240,13 @@
     }
     if (init_value != noreg) {
       Label clear_loop;
+      const Register RconstMethod = O1;
+      const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
+      const Address size_of_locals    (RconstMethod, 0, in_bytes(ConstMethod::size_of_locals_offset()));
 
       // NOTE: If you change the frame layout, this code will need to
       // be updated!
+      __ ld_ptr( constMethod, RconstMethod );
       __ lduh( size_of_locals, O2 );
       __ lduh( size_of_parameters, O1 );
       __ sll( O2, LogBytesPerWord, O2);
@@ -1483,13 +1491,16 @@
 //
 //  assert_different_registers(state, prev_state);
   const Register Gtmp = G3_scratch;
+  const RconstMethod = G3_scratch;
   const Register tmp = O2;
-  const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
-  const Address size_of_locals    (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
+  const Address constMethod(G5_method, 0, in_bytes(Method::const_offset()));
+  const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
+  const Address size_of_locals    (RconstMethod, 0, in_bytes(ConstMethod::size_of_locals_offset()));
 
+  __ ld_ptr(constMethod, RconstMethod);
   __ lduh(size_of_parameters, tmp);
-  __ sll(tmp, LogBytesPerWord, Gtmp);       // parameter size in bytes
-  __ add(args, Gtmp, Gargs);                // points to first local + BytesPerWord
+  __ sll(tmp, LogBytesPerWord, Gargs);       // parameter size in bytes
+  __ add(args, Gargs, Gargs);                // points to first local + BytesPerWord
   // NEW
   __ add(Gargs, -wordSize, Gargs);             // points to first local[0]
   // determine extra space for non-argument locals & adjust caller's SP
@@ -1541,8 +1552,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 size_of_locals    (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
 
   address entry_point = __ pc();
   __ mov(G0, prevState);                                                 // no current activation
@@ -1750,7 +1759,9 @@
 
   __ ld_ptr(STATE(_result._to_call._callee), L4_scratch);                        // called method
   __ ld_ptr(STATE(_stack), L1_scratch);                                          // get top of java expr stack
-  __ lduh(L4_scratch, in_bytes(Method::size_of_parameters_offset()), L2_scratch); // get parameter size
+  // get parameter size
+  __ ld_ptr(L4_scratch, in_bytes(Method::const_offset()), L2_scratch);
+  __ lduh(L2_scratch, in_bytes(ConstMethod::size_of_parameters_offset()), L2_scratch);
   __ sll(L2_scratch, LogBytesPerWord, L2_scratch     );                           // parameter size in bytes
   __ add(L1_scratch, L2_scratch, L1_scratch);                                      // stack destination for result
   __ ld(L4_scratch, in_bytes(Method::result_index_offset()), L3_scratch); // called method result type index
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -171,7 +171,8 @@
 
   if (VerifyMethodHandles && !for_compiler_entry) {
     // make sure recv is already on stack
-    __ load_sized_value(Address(method_temp, Method::size_of_parameters_offset()),
+    __ ld_ptr(method_temp, in_bytes(Method::const_offset()), temp2);
+    __ load_sized_value(Address(temp2, ConstMethod::size_of_parameters_offset()),
                         temp2,
                         sizeof(u2), /*is_signed*/ false);
     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
@@ -233,7 +234,8 @@
   int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
   assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
   if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
-    __ load_sized_value(Address(G5_method, Method::size_of_parameters_offset()),
+    __ ld_ptr(G5_method, in_bytes(Method::const_offset()), O4_param_size);
+    __ load_sized_value(Address(O4_param_size, ConstMethod::size_of_parameters_offset()),
                         O4_param_size,
                         sizeof(u2), /*is_signed*/ false);
     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -494,9 +494,6 @@
   // (gri - 2/25/2000)
 
 
-  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 constMethod       (G5_method, Method::const_offset());
   int rounded_vm_local_words = round_to( frame::interpreter_frame_vm_local_words, WordsPerLong );
 
   const int extra_space =
@@ -506,11 +503,15 @@
     (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0);
 
   const Register Glocals_size = G3;
+  const Register RconstMethod = Glocals_size;
   const Register Otmp1 = O3;
   const Register Otmp2 = O4;
   // Lscratch can't be used as a temporary because the call_stub uses
   // it to assert that the stack frame was setup correctly.
+  const Address constMethod       (G5_method, Method::const_offset());
+  const Address size_of_parameters(RconstMethod, ConstMethod::size_of_parameters_offset());
 
+  __ ld_ptr( constMethod, RconstMethod );
   __ lduh( size_of_parameters, Glocals_size);
 
   // Gargs points to first local + BytesPerWord
@@ -530,6 +531,8 @@
     //
     // Compute number of locals in method apart from incoming parameters
     //
+    const Address size_of_locals    (Otmp1, ConstMethod::size_of_locals_offset());
+    __ ld_ptr( constMethod, Otmp1 );
     __ lduh( size_of_locals, Otmp1 );
     __ sub( Otmp1, Glocals_size, Glocals_size );
     __ round_to( Glocals_size, WordsPerLong );
@@ -1256,8 +1259,7 @@
   // make sure registers are different!
   assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
 
-  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 constMethod       (G5_method, Method::const_offset());
   // Seems like G5_method is live at the point this is used. So we could make this look consistent
   // and use in the asserts.
   const Address access_flags      (Lmethod,   Method::access_flags_offset());
@@ -1307,8 +1309,13 @@
   init_value = G0;
   Label clear_loop;
 
+  const Register RconstMethod = O1;
+  const Address size_of_parameters(RconstMethod, ConstMethod::size_of_parameters_offset());
+  const Address size_of_locals    (RconstMethod, ConstMethod::size_of_locals_offset());
+
   // NOTE: If you change the frame layout, this code will need to
   // be updated!
+  __ ld_ptr( constMethod, RconstMethod );
   __ lduh( size_of_locals, O2 );
   __ lduh( size_of_parameters, O1 );
   __ sll( O2, Interpreter::logStackElementSize, O2);
@@ -1823,9 +1830,13 @@
 
     const Register Gtmp1 = G3_scratch;
     const Register Gtmp2 = G1_scratch;
+    const Register RconstMethod = Gtmp1;
+    const Address constMethod(Lmethod, Method::const_offset());
+    const Address size_of_parameters(RconstMethod, ConstMethod::size_of_parameters_offset());
 
     // Compute size of arguments for saving when returning to deoptimized caller
-    __ lduh(Lmethod, in_bytes(Method::size_of_parameters_offset()), Gtmp1);
+    __ ld_ptr(constMethod, RconstMethod);
+    __ lduh(size_of_parameters, Gtmp1);
     __ sll(Gtmp1, Interpreter::logStackElementSize, Gtmp1);
     __ sub(Llocals, Gtmp1, Gtmp2);
     __ add(Gtmp2, wordSize, Gtmp2);
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -3040,7 +3040,8 @@
   Register Rtemp = G4_scratch;
 
   // Load receiver from stack slot
-  __ lduh(G5_method, in_bytes(Method::size_of_parameters_offset()), G4_scratch);
+  __ ld_ptr(G5_method, in_bytes(Method::const_offset()), G4_scratch);
+  __ lduh(G4_scratch, in_bytes(ConstMethod::size_of_parameters_offset()), G4_scratch);
   __ load_receiver(G4_scratch, O0);
 
   // receiver NULL check
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -611,8 +611,6 @@
   // C++ interpreter only
   // rsi/r13 - previous interpreter state pointer
 
-  const Address size_of_parameters(rbx, Method::size_of_parameters_offset());
-
   // InterpreterRuntime::frequency_counter_overflow takes one argument
   // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp).
   // The call returns the address of the verified entry point for the method or NULL
@@ -977,15 +975,16 @@
   //      to save/restore.
   address entry_point = __ pc();
 
-  const Address size_of_parameters(rbx, Method::size_of_parameters_offset());
-  const Address size_of_locals    (rbx, Method::size_of_locals_offset());
+  const Address constMethod       (rbx, Method::const_offset());
   const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
   const Address access_flags      (rbx, Method::access_flags_offset());
+  const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
 
   // rsi/r13 == state/locals rdi == prevstate
   const Register locals = rdi;
 
   // get parameter size (always needed)
+  __ movptr(rcx, constMethod);
   __ load_unsigned_short(rcx, size_of_parameters);
 
   // rbx: Method*
@@ -994,6 +993,7 @@
   // for natives the size of locals is zero
 
   // compute beginning of parameters /locals
+
   __ lea(locals, Address(rsp, rcx, Address::times_ptr, -wordSize));
 
   // initialize fixed part of activation frame
@@ -1107,11 +1107,14 @@
   const Register method = rbx;
   const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi);
   const Register t      = InterpreterRuntime::SignatureHandlerGenerator::temp();    // rcx|rscratch1
+  const Address constMethod       (method, Method::const_offset());
+  const Address size_of_parameters(t, ConstMethod::size_of_parameters_offset());
 
   // allocate space for parameters
   __ movptr(method, STATE(_method));
   __ verify_method_ptr(method);
-  __ load_unsigned_short(t, Address(method, Method::size_of_parameters_offset()));
+  __ movptr(t, constMethod);
+  __ load_unsigned_short(t, size_of_parameters);
   __ shll(t, 2);
 #ifdef _LP64
   __ subptr(rsp, t);
@@ -1700,15 +1703,17 @@
   // save sender sp
   __ push(rcx);
 
-  const Address size_of_parameters(rbx, Method::size_of_parameters_offset());
-  const Address size_of_locals    (rbx, Method::size_of_locals_offset());
+  const Address constMethod       (rbx, Method::const_offset());
   const Address access_flags      (rbx, Method::access_flags_offset());
+  const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset());
+  const Address size_of_locals    (rdx, ConstMethod::size_of_locals_offset());
 
   // const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
   // const Address monitor_block_bot (rbp, frame::interpreter_frame_initial_sp_offset        * wordSize);
   // const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock));
 
   // get parameter size (always needed)
+  __ movptr(rdx, constMethod);
   __ load_unsigned_short(rcx, size_of_parameters);
 
   // rbx: Method*
@@ -1989,7 +1994,9 @@
   __ movptr(rbx, STATE(_result._to_call._callee));
 
   // callee left args on top of expression stack, remove them
-  __ load_unsigned_short(rcx, Address(rbx, Method::size_of_parameters_offset()));
+  __ movptr(rcx, constMethod);
+  __ load_unsigned_short(rcx, Address(rcx, ConstMethod::size_of_parameters_offset()));
+
   __ lea(rsp, Address(rsp, rcx, Address::times_ptr));
 
   __ movl(rcx, Address(rbx, Method::result_index_offset()));
@@ -2159,7 +2166,9 @@
   // Make it look like call_stub calling conventions
 
   // Get (potential) receiver
-  __ load_unsigned_short(rcx, size_of_parameters);                   // get size of parameters in words
+  // get size of parameters in words
+  __ movptr(rcx, constMethod);
+  __ load_unsigned_short(rcx, Address(rcx, ConstMethod::size_of_parameters_offset()));
 
   ExternalAddress recursive(CAST_FROM_FN_PTR(address, RecursiveInterpreterActivation));
   __ pushptr(recursive.addr());                                      // make it look good in the debugger
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -169,8 +169,9 @@
 
   if (VerifyMethodHandles && !for_compiler_entry) {
     // make sure recv is already on stack
+    __ movptr(temp2, Address(method_temp, Method::const_offset()));
     __ load_sized_value(temp2,
-                        Address(method_temp, Method::size_of_parameters_offset()),
+                        Address(temp2, ConstMethod::size_of_parameters_offset()),
                         sizeof(u2), /*is_signed*/ false);
     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
     Label L;
@@ -234,8 +235,9 @@
   int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
   assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
   if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
+    __ movptr(rdx_argp, Address(rbx_method, Method::const_offset()));
     __ load_sized_value(rdx_argp,
-                        Address(rbx_method, Method::size_of_parameters_offset()),
+                        Address(rdx_argp, ConstMethod::size_of_parameters_offset()),
                         sizeof(u2), /*is_signed*/ false);
     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
     rdx_first_arg_addr = __ argument_address(rdx_argp, -1);
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -424,8 +424,6 @@
   // C++ interpreter only
   // rsi - previous interpreter state pointer
 
-  const Address size_of_parameters(rbx, Method::size_of_parameters_offset());
-
   // InterpreterRuntime::frequency_counter_overflow takes one argument
   // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp).
   // The call returns the address of the verified entry point for the method or NULL
@@ -868,12 +866,13 @@
   // rsi: previous interpreter state (C++ interpreter) must preserve
   address entry_point = __ pc();
 
-
-  const Address size_of_parameters(rbx, Method::size_of_parameters_offset());
+  const Address constMethod       (rbx, Method::const_offset());
   const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
   const Address access_flags      (rbx, Method::access_flags_offset());
+  const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
 
   // get parameter size (always needed)
+  __ movptr(rcx, constMethod);
   __ load_unsigned_short(rcx, size_of_parameters);
 
   // native calls don't need the stack size check since they have no expression stack
@@ -988,7 +987,9 @@
 
   // allocate space for parameters
   __ get_method(method);
-  __ load_unsigned_short(t, Address(method, Method::size_of_parameters_offset()));
+  __ movptr(t, Address(method, Method::const_offset()));
+  __ load_unsigned_short(t, Address(t, ConstMethod::size_of_parameters_offset()));
+
   __ shlptr(t, Interpreter::logStackElementSize);
   __ addptr(t, 2*wordSize);     // allocate two more slots for JNIEnv and possible mirror
   __ subptr(rsp, t);
@@ -1297,13 +1298,14 @@
   // rsi: sender sp
   address entry_point = __ pc();
 
-
-  const Address size_of_parameters(rbx, Method::size_of_parameters_offset());
-  const Address size_of_locals    (rbx, Method::size_of_locals_offset());
+  const Address constMethod       (rbx, Method::const_offset());
   const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
   const Address access_flags      (rbx, Method::access_flags_offset());
+  const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset());
+  const Address size_of_locals    (rdx, ConstMethod::size_of_locals_offset());
 
   // get parameter size (always needed)
+  __ movptr(rdx, constMethod);
   __ load_unsigned_short(rcx, size_of_parameters);
 
   // rbx,: Method*
@@ -1734,7 +1736,8 @@
 
     // Compute size of arguments for saving when returning to deoptimized caller
     __ get_method(rax);
-    __ load_unsigned_short(rax, Address(rax, in_bytes(Method::size_of_parameters_offset())));
+    __ movptr(rax, Address(rax, Method::const_offset()));
+    __ load_unsigned_short(rax, Address(rax, ConstMethod::size_of_parameters_offset()));
     __ shlptr(rax, Interpreter::logStackElementSize);
     __ restore_locals();
     __ subptr(rdi, rax);
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -369,9 +369,6 @@
   // Everything as it was on entry
   // rdx is not restored. Doesn't appear to really be set.
 
-  const Address size_of_parameters(rbx,
-                                   Method::size_of_parameters_offset());
-
   // InterpreterRuntime::frequency_counter_overflow takes two
   // arguments, the first (thread) is passed by call_VM, the second
   // indicates if the counter overflow occurs at a backwards branch
@@ -844,14 +841,17 @@
 
   address entry_point = __ pc();
 
-  const Address size_of_parameters(rbx, Method::
-                                        size_of_parameters_offset());
+  const Address constMethod       (rbx, Method::const_offset());
   const Address invocation_counter(rbx, Method::
                                         invocation_counter_offset() +
                                         InvocationCounter::counter_offset());
   const Address access_flags      (rbx, Method::access_flags_offset());
+  const Address size_of_parameters(rcx, ConstMethod::
+                                        size_of_parameters_offset());
+
 
   // get parameter size (always needed)
+  __ movptr(rcx, constMethod);
   __ load_unsigned_short(rcx, size_of_parameters);
 
   // native calls don't need the stack size check since they have no
@@ -967,9 +967,8 @@
 
   // allocate space for parameters
   __ get_method(method);
-  __ load_unsigned_short(t,
-                         Address(method,
-                                 Method::size_of_parameters_offset()));
+  __ movptr(t, Address(method, Method::const_offset()));
+  __ load_unsigned_short(t, Address(t, ConstMethod::size_of_parameters_offset()));
   __ shll(t, Interpreter::logStackElementSize);
 
   __ subptr(rsp, t);
@@ -1302,15 +1301,18 @@
   // r13: sender sp
   address entry_point = __ pc();
 
-  const Address size_of_parameters(rbx,
-                                   Method::size_of_parameters_offset());
-  const Address size_of_locals(rbx, Method::size_of_locals_offset());
+  const Address constMethod(rbx, Method::const_offset());
   const Address invocation_counter(rbx,
                                    Method::invocation_counter_offset() +
                                    InvocationCounter::counter_offset());
   const Address access_flags(rbx, Method::access_flags_offset());
+  const Address size_of_parameters(rdx,
+                                   ConstMethod::size_of_parameters_offset());
+  const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
+
 
   // get parameter size (always needed)
+  __ movptr(rdx, constMethod);
   __ load_unsigned_short(rcx, size_of_parameters);
 
   // rbx: Method*
@@ -1752,7 +1754,8 @@
     // Compute size of arguments for saving when returning to
     // deoptimized caller
     __ get_method(rax);
-    __ load_unsigned_short(rax, Address(rax, in_bytes(Method::
+    __ movptr(rax, Address(rax, Method::const_offset()));
+    __ load_unsigned_short(rax, Address(rax, in_bytes(ConstMethod::
                                                 size_of_parameters_offset())));
     __ shll(rax, Interpreter::logStackElementSize);
     __ restore_locals(); // XXX do we need this?
--- a/src/share/vm/oops/constMethod.hpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/share/vm/oops/constMethod.hpp	Tue Dec 11 12:41:31 2012 -0500
@@ -46,6 +46,7 @@
 // | interp_kind  | flags    | code_size                  |
 // | name index              | signature index            |
 // | method_idnum            | max_stack                  |
+// | max_locals              | size_of_parameters         |
 // |------------------------------------------------------|
 // |                                                      |
 // | byte codes                                           |
@@ -150,7 +151,8 @@
                                                  // initially corresponds to the index into the methods array.
                                                  // but this may change with redefinition
   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
 
   // Constructor
   ConstMethod(int byte_code_size,
@@ -338,6 +340,11 @@
 
   static ByteSize max_stack_offset()
                             { return byte_offset_of(ConstMethod, _max_stack); }
+  static ByteSize size_of_locals_offset()
+                            { return byte_offset_of(ConstMethod, _max_locals); }
+  static ByteSize size_of_parameters_offset()
+                            { return byte_offset_of(ConstMethod, _size_of_parameters); }
+
 
   // Unique id for the method
   static const u2 MAX_IDNUM;
@@ -349,6 +356,14 @@
   int  max_stack() const                         { return _max_stack; }
   void set_max_stack(int size)                   { _max_stack = size; }
 
+  // max locals
+  int  max_locals() const                        { return _max_locals; }
+  void set_max_locals(int size)                  { _max_locals = size; }
+
+  // size of parameters
+  int  size_of_parameters() const                { return _size_of_parameters; }
+  void set_size_of_parameters(int size)          { _size_of_parameters = size; }
+
   // Deallocation for RedefineClasses
   void deallocate_contents(ClassLoaderData* loader_data);
   bool is_klass() const { return false; }
--- a/src/share/vm/oops/method.hpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/share/vm/oops/method.hpp	Tue Dec 11 12:41:31 2012 -0500
@@ -73,8 +73,7 @@
 // |------------------------------------------------------|
 // | result_index (C++ interpreter only)                  |
 // |------------------------------------------------------|
-// | method_size             |   max_locals               |
-// | size_of_parameters      |   intrinsic_id|   flags    |
+// | method_size             |   intrinsic_id|   flags    |
 // |------------------------------------------------------|
 // | throwout_count          |   num_breakpoints          |
 // |------------------------------------------------------|
@@ -116,8 +115,6 @@
   int               _result_index;               // C++ interpreter needs for converting results to/from stack
 #endif
   u2                _method_size;                // size of this object
-  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)
   u1                _jfr_towrite  : 1,           // Flags
                     _force_inline : 1,
@@ -292,8 +289,8 @@
   void      set_max_stack(int size)              {        constMethod()->set_max_stack(size); }
 
   // max locals
-  int  max_locals() const                        { return _max_locals; }
-  void set_max_locals(int size)                  { _max_locals = size; }
+  int  max_locals() const                        { return constMethod()->max_locals(); }
+  void set_max_locals(int size)                  { constMethod()->set_max_locals(size); }
 
   int highest_comp_level() const;
   void set_highest_comp_level(int level);
@@ -311,7 +308,8 @@
   void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; }
 
   // size of parameters
-  int  size_of_parameters() const                { return _size_of_parameters; }
+  int  size_of_parameters() const                { return constMethod()->size_of_parameters(); }
+  void set_size_of_parameters(int size)          { constMethod()->set_size_of_parameters(size); }
 
   bool has_stackmap_table() const {
     return constMethod()->has_stackmap_table();
@@ -588,8 +586,6 @@
 #ifdef CC_INTERP
   static ByteSize result_index_offset()          { return byte_offset_of(Method, _result_index ); }
 #endif /* CC_INTERP */
-  static ByteSize size_of_locals_offset()        { return byte_offset_of(Method, _max_locals        ); }
-  static ByteSize size_of_parameters_offset()    { return byte_offset_of(Method, _size_of_parameters); }
   static ByteSize from_compiled_offset()         { return byte_offset_of(Method, _from_compiled_entry); }
   static ByteSize code_offset()                  { return byte_offset_of(Method, _code); }
   static ByteSize invocation_counter_offset()    { return byte_offset_of(Method, _invocation_counter); }
@@ -796,9 +792,6 @@
                            Array<AnnotationArray*>* methods_default_annotations,
                            bool idempotent = false);
 
-  // size of parameters
-  void set_size_of_parameters(int size)          { _size_of_parameters = size; }
-
   // Deallocation function for redefine classes or if an error occurs
   void deallocate_contents(ClassLoaderData* loader_data);
 
--- a/src/share/vm/runtime/vmStructs.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Tue Dec 11 12:41:31 2012 -0500
@@ -355,8 +355,6 @@
   nonstatic_field(Method,               _access_flags,                                 AccessFlags)                           \
   nonstatic_field(Method,               _vtable_index,                                 int)                                   \
   nonstatic_field(Method,               _method_size,                                  u2)                                    \
-  nonstatic_field(Method,               _max_locals,                                   u2)                                    \
-  nonstatic_field(Method,               _size_of_parameters,                           u2)                                    \
   nonstatic_field(Method,               _interpreter_throwout_count,                   u2)                                    \
   nonstatic_field(Method,               _number_of_breakpoints,                        u2)                                    \
   nonstatic_field(Method,               _invocation_counter,                           InvocationCounter)                     \
@@ -378,6 +376,8 @@
   nonstatic_field(ConstMethod,          _signature_index,                              u2)                                    \
   nonstatic_field(ConstMethod,          _method_idnum,                                 u2)                                    \
   nonstatic_field(ConstMethod,          _max_stack,                                    u2)                                    \
+  nonstatic_field(ConstMethod,          _max_locals,                                   u2)                                    \
+  nonstatic_field(ConstMethod,          _size_of_parameters,                           u2)                                    \
   nonstatic_field(ObjArrayKlass,               _element_klass,                                Klass*)                                \
   nonstatic_field(ObjArrayKlass,               _bottom_klass,                                 Klass*)                                \
   volatile_nonstatic_field(Symbol,             _refcount,                                     int)                                   \