changeset 7187:5fafdef522c6

Merge
author johnc
date Fri, 30 Nov 2012 12:01:34 -0800
parents 5505fbbae3d3 (diff) dad48145e775 (current diff)
children b61d9c88b759
files src/share/vm/classfile/classFileParser.cpp src/share/vm/memory/metaspace.cpp src/share/vm/memory/metaspace.hpp src/share/vm/memory/universe.cpp
diffstat 34 files changed, 309 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java	Thu Nov 29 23:02:52 2012 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java	Fri Nov 30 12:01:34 2012 -0800
@@ -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	Thu Nov 29 23:02:52 2012 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java	Fri Nov 30 12:01:34 2012 -0800
@@ -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	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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/frame_sparc.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/cpu/sparc/vm/frame_sparc.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -648,7 +648,7 @@
   Method* m = *interpreter_frame_method_addr();
 
   // validate the method we'd find in this potential sender
-  if (!Universe::heap()->is_valid_method(m)) return false;
+  if (!m->is_valid_method()) return false;
 
   // stack frames shouldn't be much larger than max_stack elements
 
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -518,7 +518,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	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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/cpu/x86/vm/frame_x86.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/cpu/x86/vm/frame_x86.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -534,7 +534,7 @@
   Method* m = *interpreter_frame_method_addr();
 
   // validate the method we'd find in this potential sender
-  if (!Universe::heap()->is_valid_method(m)) return false;
+  if (!m->is_valid_method()) return false;
 
   // stack frames shouldn't be much larger than max_stack elements
 
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/classfile/defaultMethods.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -65,8 +65,7 @@
   declare_toplevel_type(AFLBinaryTreeDictionary*)                         \
   declare_toplevel_type(LinearAllocBlock)                                 \
   declare_toplevel_type(FreeBlockDictionary<FreeChunk>)                   \
-  declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>)   \
-            declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>) \
+           declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>)
 
 #define VM_INT_CONSTANTS_CMS(declare_constant)                            \
   declare_constant(Generation::ConcurrentMarkSweep)                       \
--- a/src/share/vm/gc_interface/collectedHeap.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/gc_interface/collectedHeap.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -289,11 +289,6 @@
   // (A scavenge is a GC which is not a full GC.)
   virtual bool is_scavengable(const void *p) = 0;
 
-  // Returns "TRUE" if "p" is a method oop in the
-  // current heap, with high probability. This predicate
-  // is not stable, in general.
-  bool is_valid_method(Method* p) const;
-
   void set_gc_cause(GCCause::Cause v) {
      if (UsePerfData) {
        _gc_lastcause = _gc_cause;
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -230,36 +230,6 @@
   return (oop)obj;
 }
 
-// Returns "TRUE" if "p" is a method oop in the
-// current heap with high probability. NOTE: The main
-// current consumers of this interface are Forte::
-// and ThreadProfiler::. In these cases, the
-// interpreter frame from which "p" came, may be
-// under construction when sampled asynchronously, so
-// the clients want to check that it represents a
-// valid method before using it. Nonetheless since
-// the clients do not typically lock out GC, the
-// predicate is_valid_method() is not stable, so
-// it is possible that by the time "p" is used, it
-// is no longer valid.
-inline bool CollectedHeap::is_valid_method(Method* p) const {
-  return
-    p != NULL &&
-
-    // Check whether "method" is metadata
-    p->is_metadata() &&
-
-    // See if GC is active; however, there is still an
-    // apparently unavoidable window after this call
-    // and before the client of this interface uses "p".
-    // If the client chooses not to lock out GC, then
-    // it's a risk the client must accept.
-    !is_gc_active() &&
-
-    // Check that p is a Method*.
-    p->is_method();
-}
-
 inline void CollectedHeap::oop_iterate_no_header(OopClosure* cl) {
   NoHeaderExtendedOopClosure no_header_cl(cl);
   oop_iterate(&no_header_cl);
--- a/src/share/vm/memory/allocation.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/memory/allocation.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -66,10 +66,17 @@
 }
 
 bool MetaspaceObj::is_metadata() const {
-  // ClassLoaderDataGraph::contains((address)this); has lock inversion problems
+  // GC Verify checks use this in guarantees.
+  // TODO: either replace them with is_metaspace_object() or remove them.
+  // is_metaspace_object() is slower than this test.  This test doesn't
+  // seem very useful for metaspace objects anymore though.
   return !Universe::heap()->is_in_reserved(this);
 }
 
+bool MetaspaceObj::is_metaspace_object() const {
+  return Metaspace::contains((void*)this);
+}
+
 void MetaspaceObj::print_address_on(outputStream* st) const {
   st->print(" {"INTPTR_FORMAT"}", this);
 }
--- a/src/share/vm/memory/allocation.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/memory/allocation.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -245,6 +245,7 @@
 class MetaspaceObj {
  public:
   bool is_metadata() const;
+  bool is_metaspace_object() const;  // more specific test but slower
   bool is_shared() const;
   void print_address_on(outputStream* st) const;  // nonvirtual address printing
 
--- a/src/share/vm/memory/filemap.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/memory/filemap.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/symbolTable.hpp"
+#include "classfile/altHashing.hpp"
 #include "memory/filemap.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/java.hpp"
@@ -82,8 +83,37 @@
   close();
 }
 
+// Fill in the fileMapInfo structure with data about this VM instance.
 
-// Fill in the fileMapInfo structure with data about this VM instance.
+// This method copies the vm version info into header_version.  If the version is too
+// long then a truncated version, which has a hash code appended to it, is copied.
+//
+// Using a template enables this method to verify that header_version is an array of
+// length JVM_IDENT_MAX.  This ensures that the code that writes to the CDS file and
+// the code that reads the CDS file will both use the same size buffer.  Hence, will
+// use identical truncation.  This is necessary for matching of truncated versions.
+template <int N> static void get_header_version(char (&header_version) [N]) {
+  assert(N == JVM_IDENT_MAX, "Bad header_version size");
+
+  const char *vm_version = VM_Version::internal_vm_info_string();
+  const int version_len = (int)strlen(vm_version);
+
+  if (version_len < (JVM_IDENT_MAX-1)) {
+    strcpy(header_version, vm_version);
+
+  } else {
+    // Get the hash value.  Use a static seed because the hash needs to return the same
+    // value over multiple jvm invocations.
+    unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len);
+
+    // Truncate the ident, saving room for the 8 hex character hash value.
+    strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
+
+    // Append the hash code as eight hex digits.
+    sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash);
+    header_version[JVM_IDENT_MAX-1] = 0;  // Null terminate.
+  }
+}
 
 void FileMapInfo::populate_header(size_t alignment) {
   _header._magic = 0xf00baba2;
@@ -95,13 +125,7 @@
   // invoked with.
 
   // JVM version string ... changes on each build.
-  const char *vm_version = VM_Version::internal_vm_info_string();
-  if (strlen(vm_version) < (JVM_IDENT_MAX-1)) {
-    strcpy(_header._jvm_ident, vm_version);
-  } else {
-    fail_stop("JVM Ident field for shared archive is too long"
-              " - truncated to <%s>", _header._jvm_ident);
-  }
+  get_header_version(_header._jvm_ident);
 
   // Build checks on classpath and jar files
   _header._num_jars = 0;
@@ -434,8 +458,9 @@
     fail_continue("The shared archive file has a bad magic number.");
     return false;
   }
-  if (strncmp(_header._jvm_ident, VM_Version::internal_vm_info_string(),
-              JVM_IDENT_MAX-1) != 0) {
+  char header_version[JVM_IDENT_MAX];
+  get_header_version(header_version);
+  if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
     fail_continue("The shared archive file was created by a different"
                   " version or build of HotSpot.");
     return false;
--- a/src/share/vm/memory/metaspace.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/memory/metaspace.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -36,6 +36,7 @@
 #include "memory/universe.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/mutex.hpp"
+#include "runtime/orderAccess.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/debug.hpp"
@@ -1010,6 +1011,8 @@
     delete new_entry;
     return false;
   } else {
+    // ensure lock-free iteration sees fully initialized node
+    OrderAccess::storestore();
     link_vs(new_entry, vs_word_size);
     return true;
   }
@@ -1099,7 +1102,6 @@
   }
 }
 
-#ifndef PRODUCT
 bool VirtualSpaceList::contains(const void *ptr) {
   VirtualSpaceNode* list = virtual_space_list();
   VirtualSpaceListIterator iter(list);
@@ -1111,7 +1113,6 @@
   }
   return false;
 }
-#endif // PRODUCT
 
 
 // MetaspaceGC methods
@@ -2755,15 +2756,17 @@
   }
 }
 
-#ifndef PRODUCT
-bool Metaspace::contains(const void * ptr) const {
+bool Metaspace::contains(const void * ptr) {
   if (MetaspaceShared::is_in_shared_space(ptr)) {
     return true;
   }
-  MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
+  // This is checked while unlocked.  As long as the virtualspaces are added
+  // at the end, the pointer will be in one of them.  The virtual spaces
+  // aren't deleted presently.  When they are, some sort of locking might
+  // be needed.  Note, locking this can cause inversion problems with the
+  // caller in MetaspaceObj::is_metadata() function.
   return space_list()->contains(ptr) || class_space_list()->contains(ptr);
 }
-#endif
 
 void Metaspace::verify() {
   vsm()->verify();
--- a/src/share/vm/memory/metaspace.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/memory/metaspace.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -135,11 +135,7 @@
 
   static bool is_initialized() { return _class_space_list != NULL; }
 
-#ifndef PRODUCT
-  bool contains(const void *ptr) const;
-  bool contains_class(const void *ptr) const;
-#endif
-
+  static bool contains(const void *ptr);
   void dump(outputStream* const out) const;
 
   void print_on(outputStream* st) const;
--- a/src/share/vm/memory/universe.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/memory/universe.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -418,14 +418,10 @@
 // from MetaspaceObj, because the latter does not have virtual functions.
 // If the metadata type has a vtable, it cannot be shared in the read-only
 // section of the CDS archive, because the vtable pointer is patched.
-static inline void* dereference(void* addr) {
-  return *(void**)addr;
-}
-
 static inline void add_vtable(void** list, int* n, void* o, int count) {
   guarantee((*n) < count, "vtable list too small");
-  void* vtable = dereference(o);
-  assert(dereference(vtable) != NULL, "invalid vtable");
+  void* vtable = dereference_vptr(o);
+  assert(*(void**)(vtable) != NULL, "invalid vtable");
   list[(*n)++] = vtable;
 }
 
--- a/src/share/vm/oops/compiledICHolder.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/oops/compiledICHolder.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -48,8 +48,8 @@
 // Verification
 
 void CompiledICHolder::verify_on(outputStream* st) {
-  guarantee(holder_method()->is_metadata(),   "should be in permspace");
+  guarantee(holder_method()->is_metadata(),   "should be in metaspace");
   guarantee(holder_method()->is_method(), "should be method");
-  guarantee(holder_klass()->is_metadata(),    "should be in permspace");
+  guarantee(holder_klass()->is_metadata(),    "should be in metaspace");
   guarantee(holder_klass()->is_klass(),   "should be klass");
 }
--- a/src/share/vm/oops/constMethod.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/oops/constMethod.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/oops/constMethod.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/oops/method.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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);
@@ -1814,6 +1818,23 @@
   loader_data->jmethod_ids()->clear_all_methods();
 }
 
+
+// Check that this pointer is valid by checking that the vtbl pointer matches
+bool Method::is_valid_method() const {
+  if (this == NULL) {
+    return false;
+  } else if (!is_metaspace_object()) {
+    return false;
+  } else {
+    Method m;
+    // This assumes that the vtbl pointer is the first word of a C++ object.
+    // This assumption is also in universe.cpp patch_klass_vtble
+    void* vtbl2 = dereference_vptr((void*)&m);
+    void* this_vtbl = dereference_vptr((void*)this);
+    return vtbl2 == this_vtbl;
+  }
+}
+
 #ifndef PRODUCT
 void Method::print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) {
   out->print_cr("jni_method_id count = %d", loader_data->jmethod_ids()->count_methods());
@@ -1935,7 +1956,7 @@
   guarantee(constMethod()->is_metadata(), "should be metadata");
   MethodData* md = method_data();
   guarantee(md == NULL ||
-      md->is_metadata(), "should be in permspace");
+      md->is_metadata(), "should be metadata");
   guarantee(md == NULL ||
       md->is_methodData(), "should be method data");
 }
--- a/src/share/vm/oops/method.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/oops/method.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -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,10 +163,12 @@
                           int localvariable_table_length,
                           int exception_table_length,
                           int checked_exceptions_length,
+                          u2 generic_signature_index,
                           ConstMethod::MethodType method_type,
                           TRAPS);
 
-  Method() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
+  // CDS and vtbl checking can create an empty Method to get vtbl pointer.
+  Method(){}
 
   // The Method vtable is restored by this call when the Method is in the
   // shared archive.  See patch_klass_vtables() in metaspaceShared.cpp for
@@ -288,9 +287,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 +605,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); }
@@ -812,6 +810,9 @@
 
   const char* internal_name() const { return "{method}"; }
 
+  // Check for valid method pointer
+  bool is_valid_method() const;
+
   // Verify
   void verify() { verify_on(tty); }
   void verify_on(outputStream* st);
--- a/src/share/vm/prims/forte.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/prims/forte.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -216,10 +216,7 @@
     // not yet valid.
 
     *method_p = method;
-
-    // See if gc may have invalidated method since we validated frame
-
-    if (!Universe::heap()->is_valid_method(method)) return false;
+    if (!method->is_valid_method()) return false;
 
     intptr_t bcx = fr->interpreter_frame_bcx();
 
@@ -394,19 +391,11 @@
   bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);
 
   // The frame might not be walkable but still recovered a method
-  // (e.g. an nmethod with no scope info for the pc
+  // (e.g. an nmethod with no scope info for the pc)
 
   if (method == NULL) return;
 
-  CollectedHeap* ch = Universe::heap();
-
-  // The method is not stored GC safe so see if GC became active
-  // after we entered AsyncGetCallTrace() and before we try to
-  // use the Method*.
-  // Yes, there is still a window after this check and before
-  // we use Method* below, but we can't lock out GC so that
-  // has to be an acceptable risk.
-  if (!ch->is_valid_method(method)) {
+  if (!method->is_valid_method()) {
     trace->num_frames = ticks_GC_active; // -2
     return;
   }
@@ -440,13 +429,7 @@
     bci = st.bci();
     method = st.method();
 
-    // The method is not stored GC safe so see if GC became active
-    // after we entered AsyncGetCallTrace() and before we try to
-    // use the Method*.
-    // Yes, there is still a window after this check and before
-    // we use Method* below, but we can't lock out GC so that
-    // has to be an acceptable risk.
-    if (!ch->is_valid_method(method)) {
+    if (!method->is_valid_method()) {
       // we throw away everything we've gathered in this sample since
       // none of it is safe
       trace->num_frames = ticks_GC_active; // -2
--- a/src/share/vm/prims/jni.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/prims/jni.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -5041,6 +5041,9 @@
 
 #include "gc_interface/collectedHeap.hpp"
 #include "utilities/quickSort.hpp"
+#if INCLUDE_VM_STRUCTS
+#include "runtime/vmStructs.hpp"
+#endif
 
 #define run_unit_test(unit_test_function_call)              \
   tty->print_cr("Running test: " #unit_test_function_call); \
@@ -5053,6 +5056,9 @@
     run_unit_test(CollectedHeap::test_is_in());
     run_unit_test(QuickSort::test_quick_sort());
     run_unit_test(AltHashing::test_alt_hash());
+#if INCLUDE_VM_STRUCTS
+    run_unit_test(VMStructs::test());
+#endif
     tty->print_cr("All internal VM tests passed");
   }
 }
--- a/src/share/vm/prims/jvmti.xml	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/prims/jvmti.xml	Fri Nov 30 12:01:34 2012 -0800
@@ -2370,11 +2370,11 @@
 jvmtiError err;
 
 err = (*jvmti)-&gt;GetStackTrace(jvmti, aThread, 0, 5, 
-                               &amp;frames, &amp;count);
+                               frames, &amp;count);
 if (err == JVMTI_ERROR_NONE &amp;&amp; count &gt;= 1) {
    char *methodName;
    err = (*jvmti)-&gt;GetMethodName(jvmti, frames[0].method, 
-                       &amp;methodName, NULL);
+                       &amp;methodName, NULL, NULL);
    if (err == JVMTI_ERROR_NONE) {
       printf("Executing method: %s", methodName);
    }
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -355,7 +355,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)                                    \
@@ -378,7 +377,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)                                   \
@@ -2096,8 +2095,7 @@
   declare_toplevel_type(FreeList<Metablock>*)                             \
   declare_toplevel_type(FreeList<Metablock>)                              \
   declare_toplevel_type(MetablockTreeDictionary*)                         \
-  declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)   \
-              declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
+           declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
 
 
   /* NOTE that we do not use the last_entry() macro here; it is used  */
@@ -2281,6 +2279,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                */                                 \
@@ -3204,3 +3203,17 @@
 void vmStructs_init() {
   debug_only(VMStructs::init());
 }
+
+#ifndef PRODUCT
+void VMStructs::test() {
+  // Check for duplicate entries in type array
+  for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
+    for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) {
+      if (strcmp(localHotSpotVMTypes[i].typeName, localHotSpotVMTypes[j].typeName) == 0) {
+        tty->print_cr("Duplicate entries for '%s'", localHotSpotVMTypes[i].typeName);
+        assert(false, "Duplicate types in localHotSpotVMTypes array");
+      }
+    }
+  }
+}
+#endif
--- a/src/share/vm/runtime/vmStructs.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/runtime/vmStructs.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -123,6 +123,11 @@
   // the data structure (debug build only)
   static void init();
 
+#ifndef PRODUCT
+  // Execute unit tests
+  static void test();
+#endif
+
 private:
   // Look up a type in localHotSpotVMTypes using strcmp() (debug build only).
   // Returns 1 if found, 0 if not.
--- a/src/share/vm/runtime/vm_version.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/runtime/vm_version.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -243,19 +243,21 @@
 
   #ifndef FLOAT_ARCH
     #if defined(__SOFTFP__)
-      #define FLOAT_ARCH "-sflt"
+      #define FLOAT_ARCH_STR "-sflt"
     #elif defined(E500V2)
-      #define FLOAT_ARCH "-e500v2"
+      #define FLOAT_ARCH_STR "-e500v2"
     #elif defined(ARM)
-      #define FLOAT_ARCH "-vfp"
+      #define FLOAT_ARCH_STR "-vfp"
     #elif defined(PPC)
-      #define FLOAT_ARCH "-hflt"
+      #define FLOAT_ARCH_STR "-hflt"
     #else
-      #define FLOAT_ARCH ""
+      #define FLOAT_ARCH_STR ""
     #endif
+  #else
+    #define FLOAT_ARCH_STR XSTR(FLOAT_ARCH)
   #endif
 
-  return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH
+  return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH_STR
          " JRE (" JRE_RELEASE_VERSION "), built on " __DATE__ " " __TIME__
          " by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER;
 }
--- a/src/share/vm/services/memSnapshot.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/services/memSnapshot.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -261,17 +261,19 @@
   VMMemRegion* cur = (VMMemRegion*)current();
   assert(cur->is_reserved_region() && cur->contains_region(rec),
     "Sanity check");
+  if (rec->is_same_region(cur)) {
+    // release whole reserved region
 #ifdef ASSERT
-  VMMemRegion* next_reg = (VMMemRegion*)peek_next();
-  // should not have any committed memory in this reserved region
-  assert(next_reg == NULL || !next_reg->is_committed_region(), "Sanity check");
+    VMMemRegion* next_region = (VMMemRegion*)peek_next();
+    // should not have any committed memory in this reserved region
+    assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check");
 #endif
-  if (rec->is_same_region(cur)) {
     remove();
   } else if (rec->addr() == cur->addr() ||
     rec->addr() + rec->size() == cur->addr() + cur->size()) {
     // released region is at either end of this region
     cur->exclude_region(rec->addr(), rec->size());
+    assert(check_reserved_region(), "Integrity check");
   } else { // split the reserved region and release the middle
     address high_addr = cur->addr() + cur->size();
     size_t sz = high_addr - rec->addr();
@@ -280,10 +282,14 @@
     if (MemTracker::track_callsite()) {
       MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
         ((VMMemRegionEx*)cur)->pc());
-      return insert_reserved_region(&tmp);
+      bool ret = insert_reserved_region(&tmp);
+      assert(!ret || check_reserved_region(), "Integrity check");
+      return ret;
     } else {
       MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
-      return insert_reserved_region(&tmp);
+      bool ret = insert_reserved_region(&tmp);
+      assert(!ret || check_reserved_region(), "Integrity check");
+      return ret;
     }
   }
   return true;
--- a/src/share/vm/services/memSnapshot.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/services/memSnapshot.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -146,6 +146,23 @@
   // reset current position
   inline void reset() { _pos = 0; }
 #ifdef ASSERT
+  // check integrity of records on current reserved memory region.
+  bool check_reserved_region() {
+    VMMemRegion* reserved_region = (VMMemRegion*)current();
+    assert(reserved_region != NULL && reserved_region->is_reserved_region(),
+          "Sanity check");
+    // all committed regions that follow current reserved region, should all
+    // belong to the reserved region.
+    VMMemRegion* next_region = (VMMemRegion*)next();
+    for (; next_region != NULL && next_region->is_committed_region();
+         next_region = (VMMemRegion*)next() ) {
+      if(!reserved_region->contains_region(next_region)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   virtual bool is_dup_pointer(const MemPointer* ptr1,
     const MemPointer* ptr2) const {
     VMMemRegion* p1 = (VMMemRegion*)ptr1;
--- a/src/share/vm/services/memTracker.cpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/services/memTracker.cpp	Fri Nov 30 12:01:34 2012 -0800
@@ -69,15 +69,12 @@
 
 void MemTracker::init_tracking_options(const char* option_line) {
   _tracking_level = NMT_off;
-  if (strncmp(option_line, "=summary", 8) == 0) {
+  if (strcmp(option_line, "=summary") == 0) {
     _tracking_level = NMT_summary;
-  } else if (strncmp(option_line, "=detail", 7) == 0) {
+  } else if (strcmp(option_line, "=detail") == 0) {
     _tracking_level = NMT_detail;
-  } else {
-    char msg[255];
-    //+1 to remove the '=' character
-    jio_snprintf(msg, 255, "Unknown option given to XX:NativeMemoryTracking: %s", option_line+1);
-    vm_exit_during_initialization(msg, NULL);
+  } else if (strcmp(option_line, "=off") != 0) {
+    vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
   }
 }
 
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu Nov 29 23:02:52 2012 +0100
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Nov 30 12:01:34 2012 -0800
@@ -1280,4 +1280,12 @@
 
 #define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
 
+// Dereference vptr
+// All C++ compilers that we know of have the vtbl pointer in the first
+// word.  If there are exceptions, this function needs to be made compiler
+// specific.
+static inline void* dereference_vptr(void* addr) {
+  return *(void**)addr;
+}
+
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP